diff options
Diffstat (limited to 'moon_manager')
52 files changed, 4933 insertions, 982 deletions
diff --git a/moon_manager/Changelog b/moon_manager/Changelog new file mode 100644 index 00000000..56521a0e --- /dev/null +++ b/moon_manager/Changelog @@ -0,0 +1,42 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +CHANGES +======= + +1.0.0 +----- +- First version of the manager + +2.0.0 +----- +- Version built inside the Keystone component + +3.0.0 +----- +- Version built outside the Keystone component + +4.0.0 +----- +- First micro-architecture version + +4.5.2 +----- +- use the threading capability of Flask app +- set the number of manager to 1 +- update to the latest version of the python-moondb library + +4.5.2-1 +----- +integrating validtion to send mandatory key names + +4.5.3 +----- +- Removing try catch from all requets to allow raised exception to be passed to http server, to send actual error to client side +- fixing test cases to assert on the expected exception after removing try-catch +- allow 404 to be catched from our side instead of flask itself +- revert the params in the get/post/patch/delete to be by default = None, so that we could catch the param if it was None +instead of having not found url if the param is mandatory
\ No newline at end of file diff --git a/moon_manager/Dockerfile b/moon_manager/Dockerfile index b5eb4e02..d264a113 100644 --- a/moon_manager/Dockerfile +++ b/moon_manager/Dockerfile @@ -1,8 +1,15 @@ FROM python:3 +LABEL Name=Manager +LABEL Description="Manager component for the Moon platform" +LABEL Maintainer="Thomas Duval" +LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal" + +USER root + ADD . /root WORKDIR /root/ -RUN pip3 install -r requirements.txt -RUN pip3 install . +RUN pip3 install --no-cache-dir -r requirements.txt +RUN pip3 install --no-cache-dir . CMD ["python3", "-m", "moon_manager"]
\ No newline at end of file diff --git a/moon_manager/MANIFEST.in b/moon_manager/MANIFEST.in index 1f674d50..cf4d2e4e 100644 --- a/moon_manager/MANIFEST.in +++ b/moon_manager/MANIFEST.in @@ -3,7 +3,7 @@ # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. -include README.rst +include README.md include LICENSE include setup.py include requirements.txt diff --git a/moon_manager/moon_manager/__init__.py b/moon_manager/moon_manager/__init__.py index 85c245e0..205f6d8c 100644 --- a/moon_manager/moon_manager/__init__.py +++ b/moon_manager/moon_manager/__init__.py @@ -3,4 +3,4 @@ # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. -__version__ = "4.4.0" +__version__ = "4.5.3" diff --git a/moon_manager/moon_manager/api/assignments.py b/moon_manager/moon_manager/api/assignments.py index 0b2cd20b..426789e6 100644 --- a/moon_manager/moon_manager/api/assignments.py +++ b/moon_manager/moon_manager/api/assignments.py @@ -12,6 +12,7 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -31,15 +32,16 @@ class SubjectAssignments(Resource): "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", ) + @validate_input("get", kwargs_state=[True, False, False,False,False]) @check_auth - def get(self, uuid=None, perimeter_id=None, category_id=None, + def get(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Retrieve all subject assignments or a specific one for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the subject :param category_id: uuid of the subject category - :param data_id: uuid of the subject scope + :param data_id: uuid of the subject scope (not used here) :param user_id: user ID who do the request :return: { "subject_data_id": { @@ -51,18 +53,16 @@ class SubjectAssignments(Resource): } :internal_api: get_subject_assignments """ - try: - data = PolicyManager.get_subject_assignments( - user_id=user_id, policy_id=uuid, - subject_id=perimeter_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_subject_assignments( + user_id=user_id, policy_id=uuid, + subject_id=perimeter_id, category_id=category_id) + return {"subject_assignments": data} + @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True}) @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, + def post(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Create a subject assignment. @@ -72,36 +72,32 @@ class SubjectAssignments(Resource): :param data_id: uuid of the subject scope (not used here) :param user_id: user ID who do the request :request body: { - "id": "UUID of the subject", - "category_id": "UUID of the category" - "data_id": "UUID of the scope" + "id": "UUID of the subject (mandatory)", + "category_id": "UUID of the category (mandatory)" + "data_id": "UUID of the scope (mandatory)" } :return: { "subject_data_id": { "policy_id": "ID of the policy", - "subject_id": "ID of the subject", - "category_id": "ID of the category", + "subject_id": "ID of the subject (mandatory)", + "category_id": "ID of the category (mandatory)", "assignments": "Assignments list (list of data_id)", } } :internal_api: update_subject_assignment """ - try: - data_id = request.json.get("data_id") - category_id = request.json.get("category_id") - perimeter_id = request.json.get("id") - data = PolicyManager.add_subject_assignment( - user_id=user_id, policy_id=uuid, - subject_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data_id = request.json.get("data_id") + category_id = request.json.get("category_id") + perimeter_id = request.json.get("id") + data = PolicyManager.add_subject_assignment( + user_id=user_id, policy_id=uuid, + subject_id=perimeter_id, category_id=category_id, + data_id=data_id) return {"subject_assignments": data} + @validate_input("delete", kwargs_state=[True, True, True, True, False]) @check_auth - def delete(self, uuid=None, perimeter_id=None, category_id=None, + def delete(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Delete a subject assignment for a given policy @@ -116,15 +112,12 @@ class SubjectAssignments(Resource): } :internal_api: delete_subject_assignment """ - try: - data = PolicyManager.delete_subject_assignment( - user_id=user_id, policy_id=uuid, - subject_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_subject_assignment( + user_id=user_id, policy_id=uuid, + subject_id=perimeter_id, category_id=category_id, + data_id=data_id) + return {"result": True} @@ -141,15 +134,16 @@ class ObjectAssignments(Resource): "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", ) + @validate_input("get", kwargs_state=[True, False, False,False,False]) @check_auth - def get(self, uuid=None, perimeter_id=None, category_id=None, + def get(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Retrieve all object assignment or a specific one for a given policy :param uuid: uuid of the policy :param perimeter_id: uuid of the object :param category_id: uuid of the object category - :param data_id: uuid of the object scope + :param data_id: uuid of the object scope (not used here) :param user_id: user ID who do the request :return: { "object_data_id": { @@ -161,18 +155,16 @@ class ObjectAssignments(Resource): } :internal_api: get_object_assignments """ - try: - data = PolicyManager.get_object_assignments( - user_id=user_id, policy_id=uuid, - object_id=perimeter_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_object_assignments( + user_id=user_id, policy_id=uuid, + object_id=perimeter_id, category_id=category_id) + return {"object_assignments": data} + @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True}) @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, + def post(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Create an object assignment. @@ -182,9 +174,9 @@ class ObjectAssignments(Resource): :param data_id: uuid of the object scope (not used here) :param user_id: user ID who do the request :request body: { - "id": "UUID of the action", - "category_id": "UUID of the category" - "data_id": "UUID of the scope" + "id": "UUID of the action (mandatory)", + "category_id": "UUID of the category (mandatory)", + "data_id": "UUID of the scope (mandatory)" } :return: { "object_data_id": { @@ -196,22 +188,20 @@ class ObjectAssignments(Resource): } :internal_api: update_object_assignment """ - try: - data_id = request.json.get("data_id") - category_id = request.json.get("category_id") - perimeter_id = request.json.get("id") - data = PolicyManager.add_object_assignment( - user_id=user_id, policy_id=uuid, - object_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data_id = request.json.get("data_id") + category_id = request.json.get("category_id") + perimeter_id = request.json.get("id") + data = PolicyManager.add_object_assignment( + user_id=user_id, policy_id=uuid, + object_id=perimeter_id, category_id=category_id, + data_id=data_id) + return {"object_assignments": data} + @validate_input("delete", kwargs_state=[True, True, True, True, False]) @check_auth - def delete(self, uuid=None, perimeter_id=None, category_id=None, + def delete(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Delete a object assignment for a given policy @@ -226,15 +216,11 @@ class ObjectAssignments(Resource): } :internal_api: delete_object_assignment """ - try: - data = PolicyManager.delete_object_assignment( - user_id=user_id, policy_id=uuid, - object_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.delete_object_assignment( + user_id=user_id, policy_id=uuid, + object_id=perimeter_id, category_id=category_id, + data_id=data_id) + return {"result": True} @@ -251,8 +237,9 @@ class ActionAssignments(Resource): "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", ) + @validate_input("get", kwargs_state=[True, False, False,False,False]) @check_auth - def get(self, uuid=None, perimeter_id=None, category_id=None, + def get(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Retrieve all action assignment or a specific one for a given policy @@ -271,18 +258,15 @@ class ActionAssignments(Resource): } :internal_api: get_action_assignments """ - try: - data = PolicyManager.get_action_assignments( - user_id=user_id, policy_id=uuid, - action_id=perimeter_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.get_action_assignments( + user_id=user_id, policy_id=uuid, + action_id=perimeter_id, category_id=category_id) + return {"action_assignments": data} + @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True}) @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, + def post(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Create an action assignment. @@ -292,9 +276,9 @@ class ActionAssignments(Resource): :param data_id: uuid of the action scope (not used here) :param user_id: user ID who do the request :request body: { - "id": "UUID of the action", - "category_id": "UUID of the category", - "data_id": "UUID of the scope" + "id": "UUID of the action (mandatory)", + "category_id": "UUID of the category (mandatory)", + "data_id": "UUID of the scope (mandatory)" } :return: { "action_data_id": { @@ -306,22 +290,20 @@ class ActionAssignments(Resource): } :internal_api: update_action_assignment """ - try: - data_id = request.json.get("data_id") - category_id = request.json.get("category_id") - perimeter_id = request.json.get("id") - data = PolicyManager.add_action_assignment( - user_id=user_id, policy_id=uuid, - action_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data_id = request.json.get("data_id") + category_id = request.json.get("category_id") + perimeter_id = request.json.get("id") + data = PolicyManager.add_action_assignment( + user_id=user_id, policy_id=uuid, + action_id=perimeter_id, category_id=category_id, + data_id=data_id) + return {"action_assignments": data} + @validate_input("delete", kwargs_state=[True, True, True, True, False]) @check_auth - def delete(self, uuid=None, perimeter_id=None, category_id=None, + def delete(self, uuid, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Delete a action assignment for a given policy @@ -336,13 +318,10 @@ class ActionAssignments(Resource): } :internal_api: delete_action_assignment """ - try: - data = PolicyManager.delete_action_assignment( - user_id=user_id, policy_id=uuid, - action_id=perimeter_id, category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_action_assignment( + user_id=user_id, policy_id=uuid, + action_id=perimeter_id, category_id=category_id, + data_id=data_id) + return {"result": True} diff --git a/moon_manager/moon_manager/api/base_exception.py b/moon_manager/moon_manager/api/base_exception.py new file mode 100644 index 00000000..0af3b6d0 --- /dev/null +++ b/moon_manager/moon_manager/api/base_exception.py @@ -0,0 +1,18 @@ + +class BaseException(Exception): + def __init__(self, message): + self._code = 500 + self._message = message + # Call the base class constructor with the parameters it needs + super(BaseException, self).__init__(message) + + @property + def code(self): + return self._code + + @property + def message(self): + return self._message + + def __str__(self): + return "Error " + str(self._code) + " " + self.__class__.__name__ + ': ' + self.message
\ No newline at end of file diff --git a/moon_manager/moon_manager/api/data.py b/moon_manager/moon_manager/api/data.py index b74ca385..d887ac2b 100644 --- a/moon_manager/moon_manager/api/data.py +++ b/moon_manager/moon_manager/api/data.py @@ -12,6 +12,7 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -31,9 +32,10 @@ class SubjectData(Resource): "<string:data_id>", ) + @validate_input("get", kwargs_state=[True, False, False, False]) @check_auth - def get(self, uuid=None, category_id=None, data_id=None, user_id=None): - """Retrieve all subject categories or a specific one if sid is given + def get(self, uuid, category_id=None, data_id=None, user_id=None): + """Retrieve all subject categories or a specific one if data_id is given for a given policy :param uuid: uuid of the policy @@ -46,60 +48,56 @@ class SubjectData(Resource): "data": { "subject_data_id": { "name": "name of the data", - "description": "description of the data" + "description": "description of the data (optional)" } } }] :internal_api: get_subject_data """ - try: - data = PolicyManager.get_subject_data(user_id=user_id, - policy_id=uuid, - category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + logger.info("api.get {} {} {}".format(uuid, category_id, data_id)) + data = PolicyManager.get_subject_data(user_id=user_id, + policy_id=uuid, + category_id=category_id, + data_id=data_id) + logger.info("api.get data = {}".format(data)) + return {"subject_data": data} + @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True}) @check_auth - def post(self, uuid=None, category_id=None, data_id=None, user_id=None): + def post(self, uuid, category_id=None, data_id=None, user_id=None): """Create or update a subject. :param uuid: uuid of the policy :param category_id: uuid of the subject category - :param data_id: uuid of the subject data + :param data_id: uuid of the subject data (not used here) :param user_id: user ID who do the request :request body: { - "name": "name of the data", - "description": "description of the data" + "name": "name of the data (mandatory)", + "description": "description of the data (optional)" } :return: { "policy_id": "policy_id1", "category_id": "category_id1", "data": { "subject_data_id": { - "name": "name of the data", - "description": "description of the data" + "name": "name of the data (mandatory)", + "description": "description of the data (optional)" } } } :internal_api: add_subject_data """ - try: - data = PolicyManager.set_subject_data(user_id=user_id, - policy_id=uuid, + data = PolicyManager.set_subject_data(user_id=user_id, + policy_id=uuid, category_id=category_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + return {"subject_data": data} + @validate_input("delete", kwargs_state=[True, False, False, False]) @check_auth - def delete(self, uuid=None, category_id=None, data_id=None, user_id=None): + def delete(self, uuid, category_id=None, data_id=None, user_id=None): """Delete a subject for a given policy :param uuid: uuid of the policy @@ -108,18 +106,15 @@ class SubjectData(Resource): :param user_id: user ID who do the request :return: [{ "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" }] :internal_api: delete_subject_data """ - try: - data = PolicyManager.delete_subject_data(user_id=user_id, - policy_id=uuid, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + logger.info("api.delete {} {}".format(uuid, data_id)) + data = PolicyManager.delete_subject_data(user_id=user_id, + policy_id=uuid, + data_id=data_id) + return {"result": True} @@ -136,8 +131,9 @@ class ObjectData(Resource): "<string:data_id>", ) + @validate_input("get", kwargs_state=[True, False, False, False]) @check_auth - def get(self, uuid=None, category_id=None, data_id=None, user_id=None): + def get(self, uuid, category_id=None, data_id=None, user_id=None): """Retrieve all object categories or a specific one if sid is given for a given policy @@ -151,34 +147,31 @@ class ObjectData(Resource): "data": { "object_data_id": { "name": "name of the data", - "description": "description of the data" + "description": "description of the data (optional)" } } }] :internal_api: get_object_data """ - try: - data = PolicyManager.get_object_data(user_id=user_id, - policy_id=uuid, - category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.get_object_data(user_id=user_id, + policy_id=uuid, + category_id=category_id, + data_id=data_id) + return {"object_data": data} + @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True}) @check_auth - def post(self, uuid=None, category_id=None, data_id=None, user_id=None): + def post(self, uuid, category_id=None, data_id=None, user_id=None): """Create or update a object. :param uuid: uuid of the policy :param category_id: uuid of the object category - :param data_id: uuid of the object data + :param data_id: uuid of the object data (not used here) :param user_id: user ID who do the request :request body: { - "name": "name of the data", - "description": "description of the data" + "name": "name of the data (mandatory)", + "description": "description of the data (optional)" } :return: { "policy_id": "policy_id1", @@ -186,25 +179,22 @@ class ObjectData(Resource): "data": { "object_data_id": { "name": "name of the data", - "description": "description of the data" + "description": "description of the data (optional)" } } } :internal_api: add_object_data """ - try: - data = PolicyManager.add_object_data(user_id=user_id, - policy_id=uuid, - category_id=category_id, - value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.add_object_data(user_id=user_id, + policy_id=uuid, + category_id=category_id, + value=request.json) + return {"object_data": data} + @validate_input("delete", kwargs_state=[True, False, False, False]) @check_auth - def delete(self, uuid=None, category_id=None, data_id=None, user_id=None): + def delete(self, uuid, category_id=None, data_id=None, user_id=None): """Delete a object for a given policy :param uuid: uuid of the policy @@ -213,18 +203,14 @@ class ObjectData(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_object_data """ - try: - data = PolicyManager.delete_object_data(user_id=user_id, - policy_id=uuid, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.delete_object_data(user_id=user_id, + policy_id=uuid, + data_id=data_id) + return {"result": True} @@ -241,8 +227,9 @@ class ActionData(Resource): "<string:data_id>", ) + @validate_input("get", kwargs_state=[True, False, False, False]) @check_auth - def get(self, uuid=None, category_id=None, data_id=None, user_id=None): + def get(self, uuid, category_id=None, data_id=None, user_id=None): """Retrieve all action categories or a specific one if sid is given for a given policy @@ -256,25 +243,22 @@ class ActionData(Resource): "data": { "action_data_id": { "name": "name of the data", - "description": "description of the data" + "description": "description of the data (optional)" } } }] :internal_api: get_action_data """ - try: - data = PolicyManager.get_action_data(user_id=user_id, - policy_id=uuid, - category_id=category_id, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.get_action_data(user_id=user_id, + policy_id=uuid, + category_id=category_id, + data_id=data_id) + return {"action_data": data} + @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True}) @check_auth - def post(self, uuid=None, category_id=None, data_id=None, user_id=None): + def post(self, uuid, category_id=None, data_id=None, user_id=None): """Create or update a action. :param uuid: uuid of the policy @@ -282,8 +266,8 @@ class ActionData(Resource): :param data_id: uuid of the action data :param user_id: user ID who do the request :request body: { - "name": "name of the data", - "description": "description of the data" + "name": "name of the data (mandatory)", + "description": "description of the data (optional)" } :return: { "policy_id": "policy_id1", @@ -291,25 +275,21 @@ class ActionData(Resource): "data": { "action_data_id": { "name": "name of the data", - "description": "description of the data" + "description": "description of the data (optional)" } } } :internal_api: add_action_data """ - try: - data = PolicyManager.add_action_data(user_id=user_id, - policy_id=uuid, - category_id=category_id, - value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.add_action_data(user_id=user_id, + policy_id=uuid, + category_id=category_id, + value=request.json) return {"action_data": data} + @validate_input("delete", kwargs_state=[True, False, False, False]) @check_auth - def delete(self, uuid=None, category_id=None, data_id=None, user_id=None): + def delete(self, uuid, category_id=None, data_id=None, user_id=None): """Delete a action for a given policy :param uuid: uuid of the policy @@ -318,18 +298,14 @@ class ActionData(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_action_data """ - try: - data = PolicyManager.delete_action_data(user_id=user_id, - policy_id=uuid, - data_id=data_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PolicyManager.delete_action_data(user_id=user_id, + policy_id=uuid, + data_id=data_id) + return {"result": True} diff --git a/moon_manager/moon_manager/api/json_export.py b/moon_manager/moon_manager/api/json_export.py new file mode 100644 index 00000000..1d3643e7 --- /dev/null +++ b/moon_manager/moon_manager/api/json_export.py @@ -0,0 +1,238 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import logging +from flask_restful import Resource +from python_moonutilities.security_functions import check_auth +from python_moondb.core import PDPManager +from python_moondb.core import PolicyManager +from python_moondb.core import ModelManager +from moon_manager.api.json_utils import JsonUtils, BaseException + +__version__ = "4.5.0" + +logger = logging.getLogger("moon.manager.api." + __name__) + + +class JsonExport(Resource): + + __urls__ = ( + "/export", + "/export/", + ) + + def _export_rules(self, json_content): + policies = PolicyManager.get_policies(self._user_id) + rules_array = [] + + for policy_key in policies: + rules = PolicyManager.get_rules(self._user_id, policy_key) + rules = rules["rules"] + # logger.info(rules) + for rule in rules: + rule_dict = dict() + JsonUtils.copy_field_if_exists(rule, rule_dict, "instructions", dict) + JsonUtils.copy_field_if_exists(rule, rule_dict, "enabled", True) + JsonUtils.convert_id_to_name(rule["meta_rule_id"], rule_dict, "meta_rule", "meta_rule", ModelManager, self._user_id) + JsonUtils.convert_id_to_name(policy_key, rule_dict, "policy", "policy", PolicyManager, self._user_id) + ids = rule["rule"] + rule_description = dict() + meta_rule = ModelManager.get_meta_rules(self._user_id, rule["meta_rule_id"]) + meta_rule = [v for v in meta_rule.values()] + meta_rule = meta_rule[0] + index_subject_data = len(meta_rule["subject_categories"])-1 + index_object_data = len(meta_rule["subject_categories"]) + len(meta_rule["object_categories"])-1 + index_action_data = len(meta_rule["subject_categories"]) + len(meta_rule["object_categories"]) + len(meta_rule["action_categories"])-1 + ids_subject_data = [ids[0]] if len(meta_rule["subject_categories"]) == 1 else ids[0:index_subject_data] + ids_object_data = [ids[index_object_data]] if len(meta_rule["object_categories"]) == 1 else ids[index_subject_data+1:index_object_data] + ids_action_date = [ids[index_action_data]] if len(meta_rule["action_categories"]) == 1 else ids[index_object_data+1:index_action_data] + JsonUtils.convert_ids_to_names(ids_subject_data, rule_description, "subject_data", "subject_data", PolicyManager, self._user_id, policy_key) + JsonUtils.convert_ids_to_names(ids_object_data, rule_description, "object_data", "object_data", PolicyManager, self._user_id, policy_key) + JsonUtils.convert_ids_to_names(ids_action_date, rule_description, "action_data", "action_data", PolicyManager, self._user_id, policy_key) + rule_dict["rule"] = rule_description + rules_array.append(rule_dict) + + if len(rules_array) > 0: + json_content['rules'] = rules_array + + def _export_meta_rules(self, json_content): + meta_rules = ModelManager.get_meta_rules(self._user_id) + meta_rules_array = [] + # logger.info(meta_rules) + for meta_rule_key in meta_rules: + #logger.info(meta_rules[meta_rule_key]) + meta_rule_dict = dict() + JsonUtils.copy_field_if_exists(meta_rules[meta_rule_key], meta_rule_dict, "name", str) + JsonUtils.copy_field_if_exists(meta_rules[meta_rule_key], meta_rule_dict, "description", str) + JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["subject_categories"], meta_rule_dict, "subject_categories", "subject_category", ModelManager, self._user_id) + JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["object_categories"], meta_rule_dict, "object_categories", "object_category", ModelManager, self._user_id) + JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["action_categories"], meta_rule_dict, "action_categories", "action_category", ModelManager, self._user_id) + logger.info("Exporting meta rule {}".format(meta_rule_dict)) + meta_rules_array.append(meta_rule_dict) + if len(meta_rules_array) > 0: + json_content['meta_rules'] = meta_rules_array + + def _export_subject_object_action_assignments(self, type_element, json_content): + export_method_data = getattr(PolicyManager, 'get_' + type_element + '_assignments') + policies = PolicyManager.get_policies(self._user_id) + element_assignments_array = [] + for policy_key in policies: + assignments = export_method_data(self._user_id, policy_key) + #logger.info(assignments) + for assignment_key in assignments: + assignment_dict = dict() + JsonUtils.convert_id_to_name(assignments[assignment_key][type_element + "_id"], assignment_dict, type_element, type_element , PolicyManager, self._user_id, policy_key) + JsonUtils.convert_id_to_name(assignments[assignment_key]["category_id"], assignment_dict, "category", type_element + "_category", ModelManager, self._user_id, policy_key) + JsonUtils.convert_ids_to_names(assignments[assignment_key]["assignments"], assignment_dict, "assignments", type_element + "_data", PolicyManager, self._user_id, policy_key) + element_assignments_array.append(assignment_dict) + logger.info("Exporting {}Â assignment {}".format(type_element, assignment_dict)) + if len(element_assignments_array) > 0: + json_content[type_element + '_assignments'] = element_assignments_array + + def _export_subject_object_action_datas(self, type_element, json_content): + export_method_data = getattr(PolicyManager, 'get_' + type_element + '_data') + policies = PolicyManager.get_policies(self._user_id) + element_datas_array = [] + for policy_key in policies: + datas = export_method_data(self._user_id, policy_key) + #logger.info("data found : {}".format(datas)) + for data_group in datas: + policy_id = data_group["policy_id"] + category_id = data_group["category_id"] + # logger.info(data_group["data"]) + for data_key in data_group["data"]: + data_dict = dict() + if type_element == 'subject': + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "name", str) + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "description", str) + else: + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "name", str) + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, "description", str) + + JsonUtils.convert_id_to_name(policy_id, data_dict, "policy", "policy", PolicyManager, self._user_id) + JsonUtils.convert_id_to_name(category_id, data_dict, "category", type_element + "_category", ModelManager, self._user_id, policy_key) + logger.info("Exporting {}Â data {}".format(type_element, data_dict)) + element_datas_array.append(data_dict) + + if len(element_datas_array) > 0: + json_content[type_element + '_data'] = element_datas_array + + def _export_subject_object_action_categories(self, type_element, json_content): + export_method = getattr(ModelManager, 'get_' + type_element + '_categories') + element_categories = export_method(self._user_id) + element_categories_array = [] + for element_category_key in element_categories: + element_category = dict() + JsonUtils.copy_field_if_exists(element_categories[element_category_key], element_category, "name", str) + JsonUtils.copy_field_if_exists(element_categories[element_category_key], element_category, "description", str) + element_categories_array.append(element_category) + logger.info("Exporting {}Â category {}".format(type_element, element_category)) + if len(element_categories_array) > 0: + json_content[type_element + '_categories'] = element_categories_array + + def _export_subject_object_action(self, type_element, json_content): + export_method = getattr(PolicyManager, 'get_' + type_element + 's') + policies = PolicyManager.get_policies(self._user_id) + element_dict = dict() + elements_array = [] + for policy_key in policies: + elements = export_method(self._user_id, policy_key) + for element_key in elements: + #logger.info("Exporting {}".format(elements[element_key])) + element = dict() + JsonUtils.copy_field_if_exists(elements[element_key], element, "name", str) + JsonUtils.copy_field_if_exists(elements[element_key], element, "description", str) + JsonUtils.copy_field_if_exists(elements[element_key], element, "extra", dict) + if element["name"] not in element_dict: + element["policies"] = [] + element_dict[element["name"]] = element + current_element = element_dict[element["name"]] + current_element["policies"].append({"name": JsonUtils.convert_id_to_name_string(policy_key, "policy", PolicyManager, self._user_id)}) + + for key in element_dict: + logger.info("Exporting {}Â {}".format(type_element, element_dict[key])) + elements_array.append(element_dict[key]) + + if len(elements_array) > 0: + json_content[type_element + 's'] = elements_array + + def _export_policies(self, json_content): + policies = PolicyManager.get_policies(self._user_id) + policies_array = [] + for policy_key in policies: + policy = dict() + JsonUtils.copy_field_if_exists(policies[policy_key], policy, "name", str) + JsonUtils.copy_field_if_exists(policies[policy_key], policy, "genre", str) + JsonUtils.copy_field_if_exists(policies[policy_key], policy, "description", str) + JsonUtils.convert_id_to_name(policies[policy_key]["model_id"], policy, "model", "model", ModelManager, self._user_id) + logger.info("Exporting policy {}".format(policy)) + policies_array.append(policy) + if len(policies_array) > 0: + json_content["policies"] = policies_array + + def _export_models(self, json_content): + models = ModelManager.get_models(self._user_id) + models_array = [] + for model_key in models: + model = dict() + JsonUtils.copy_field_if_exists(models[model_key], model, "name", str) + JsonUtils.copy_field_if_exists(models[model_key], model, "description", str) + # logger.info(models[model_key]["meta_rules"]) + JsonUtils.convert_ids_to_names(models[model_key]["meta_rules"], model, "meta_rules", "meta_rule", ModelManager, self._user_id) + logger.info("Exporting model {}".format(model)) + models_array.append(model) + if len(models_array) > 0: + json_content["models"] = models_array + + def _export_pdps(self, json_content): + pdps = PDPManager.get_pdp(self._user_id) + pdps_array = [] + for pdp_key in pdps: + logger.info("Exporting pdp {}".format(pdps[pdp_key])) + pdps_array.append(pdps[pdp_key]) + if len(pdps_array) > 0: + json_content["pdps"] = pdps_array + + def _export_json(self, user_id): + self._user_id = user_id + json_content = dict() + + logger.info("Exporting pdps...") + self._export_pdps(json_content) + logger.info("Exporting policies...") + self._export_policies(json_content) + logger.info("Exporting models...") + self._export_models(json_content) + # export subjects, subject_data, subject_categories, subject_assignements idem for object and action + list_element = [{"key": "subject"}, {"key": "object"}, {"key": "action"}] + for elt in list_element: + logger.info("Exporting {}s...".format(elt["key"])) + self._export_subject_object_action(elt["key"], json_content) + logger.info("Exporting {} categories...".format(elt["key"])) + self._export_subject_object_action_categories(elt["key"], json_content) + logger.info("Exporting {} data...".format(elt["key"])) + self._export_subject_object_action_datas(elt["key"], json_content) + logger.info("Exporting {} assignments...".format(elt["key"])) + self._export_subject_object_action_assignments(elt["key"], json_content) + logger.info("Exporting meta rules...") + self._export_meta_rules(json_content) + logger.info("Exporting rules...") + self._export_rules(json_content) + + return json_content + + @check_auth + def get(self, user_id=None): + """Import file. + + :param user_id: user ID who do the request + :return: { + + } + :internal_api: + """ + json_file = self._export_json(user_id) + logger.info(json_file) + return {"content": json_file} diff --git a/moon_manager/moon_manager/api/json_import.py b/moon_manager/moon_manager/api/json_import.py new file mode 100644 index 00000000..e57a27c1 --- /dev/null +++ b/moon_manager/moon_manager/api/json_import.py @@ -0,0 +1,524 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from flask import request +from flask_restful import Resource +import flask_restful +from flask import abort + +from python_moonutilities.security_functions import check_auth +from python_moonutilities import exceptions +import logging +import json + +from moon_manager.api.base_exception import BaseException +from moon_manager.api.json_utils import JsonUtils, UnknownName +from python_moondb.core import PDPManager +from python_moondb.core import PolicyManager +from python_moondb.core import ModelManager + + +__version__ = "4.5.0" + +logger = logging.getLogger("moon.manager.api." + __name__) + +INST_CALLBACK = 0 +DATA_CALLBACK = 1 +ASSIGNMENT_CALLBACK = 2 +CATEGORIES_CALLBACK = 3 + + +class ForbiddenOverride(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(ForbiddenOverride, self).__init__(message) + + +class UnknownPolicy(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(UnknownPolicy, self).__init__(message) + + +class UnknownModel(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(UnknownModel, self).__init__(message) + + +class UnknownData(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(UnknownData, self).__init__(message) + + +class MissingPolicy(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(MissingPolicy, self).__init__(message) + + +class InvalidJson(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(InvalidJson, self).__init__(message) + + +class JsonImport(Resource): + + __urls__ = ( + "/import", + "/import/", + ) + + def _reorder_rules_ids(self, rule, ordered_perimeter_categories_ids, json_data_ids, policy_id, get_function): + ordered_json_ids = [None]*len(ordered_perimeter_categories_ids) + for json_id in json_data_ids: + data = get_function(self._user_id, policy_id, data_id=json_id) + data = data[0] + if data["category_id"] not in ordered_perimeter_categories_ids: + raise InvalidJson("The category id {} of the rule {} does not match the meta rule".format( + data["category_id"], rule)) + if ordered_json_ids[ordered_perimeter_categories_ids.index(data["category_id"])] is not None: + raise InvalidJson("The category id {} of the rule {} shall not be used twice in the same rule".format( + data["category_id"], rule)) + ordered_json_ids[ordered_perimeter_categories_ids.index(data["category_id"])] = json_id + logger.info(ordered_json_ids) + return ordered_json_ids + + def _import_rules(self, json_rules): + if not isinstance(json_rules, list): + raise InvalidJson("rules shall be a list!") + + for json_rule in json_rules: + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_rule, json_to_use, "instructions", str) + JsonUtils.copy_field_if_exists(json_rule, json_to_use, "enabled", bool, default_value=True) + + json_ids = dict() + JsonUtils.convert_name_to_id(json_rule, json_ids, "policy", "policy_id", "policy", + PolicyManager, self._user_id) + JsonUtils.convert_name_to_id(json_rule, json_to_use, "meta_rule", "meta_rule_id", "meta_rule", ModelManager, self._user_id) + json_subject_ids = dict() + json_object_ids = dict() + json_action_ids = dict() + JsonUtils.convert_names_to_ids(json_rule["rule"], json_subject_ids, "subject_data", "subject", "subject_data", PolicyManager, self._user_id, json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_object_ids, "object_data", "object", "object_data", PolicyManager, self._user_id, json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_action_ids, "action_data", "action", "action_data", PolicyManager, self._user_id, json_ids["policy_id"]) + + meta_rule = ModelManager.get_meta_rules(self._user_id, json_to_use["meta_rule_id"]) + meta_rule = [v for v in meta_rule.values()] + meta_rule = meta_rule[0] + + json_to_use_rule = self._reorder_rules_ids(json_rule, meta_rule["subject_categories"], json_subject_ids["subject"], json_ids["policy_id"], PolicyManager.get_subject_data) + json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule["object_categories"], json_object_ids["object"], json_ids["policy_id"], PolicyManager.get_object_data) + json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule["action_categories"], json_action_ids["action"], json_ids["policy_id"], PolicyManager.get_action_data) + json_to_use["rule"] = json_to_use_rule + try: + logger.debug("Adding / updating a rule from json {}".format(json_to_use)) + PolicyManager.add_rule(self._user_id, json_ids["policy_id"], json_to_use["meta_rule_id"], json_to_use) + except exceptions.RuleExisting: + pass + except exceptions.PolicyUnknown: + raise UnknownPolicy("Unknown policy with id {}".format(json_ids["policy_id"])) + + def _import_meta_rules(self, json_meta_rules): + logger.info("Input meta rules : {}".format(json_meta_rules)) + for json_meta_rule in json_meta_rules: + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "name", str) + JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "description", str) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "subject_categories", "subject_categories", "subject_category", ModelManager, self._user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "object_categories", "object_categories", "object_category", ModelManager, self._user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "action_categories", "action_categories", "action_category", ModelManager, self._user_id) + logger.debug("Adding / updating a metarule from json {}".format(json_meta_rule)) + meta_rule = ModelManager.add_meta_rule(self._user_id, meta_rule_id=None, value=json_to_use) + logger.debug("Added / updated meta rule : {}".format(meta_rule)) + + def _import_subject_object_action_assignments(self, json_item_assignments, type_element): + import_method = getattr(PolicyManager, 'add_' + type_element + '_assignment') + get_method = getattr(PolicyManager, 'get_' + type_element + '_data') + + if not isinstance(json_item_assignments, list): + raise InvalidJson(type_element + " assignments shall be a list!") + + # get the policy id related to the user + policies = PolicyManager.get_policies(self._user_id) + + for json_item_assignment in json_item_assignments: + item_override = JsonUtils.get_override(json_item_assignment) + if item_override is True: + raise ForbiddenOverride("{} assignments do not support override flag !".format(type_element)) + + json_assignment = dict() + JsonUtils.convert_name_to_id(json_item_assignment, json_assignment, "category", "category_id", type_element + "_category", ModelManager, self._user_id) + + has_found_data = False + # loop over policies + for policy_id in policies: + json_data = dict() + try: + JsonUtils.convert_name_to_id(json_item_assignment, json_assignment, type_element, "id", type_element, PolicyManager, self._user_id, policy_id) + JsonUtils.convert_names_to_ids(json_item_assignment, json_data, "assignments", "data_id", type_element + "_data", PolicyManager, self._user_id, policy_id, json_assignment["category_id"]) + has_found_data = True + except UnknownName: + # the category or data has not been found in this policy : we look into the next one + continue + for data_id in json_data["data_id"]: + # find the policy related to the current data + data = get_method(self._user_id, policy_id, data_id, json_assignment["category_id"]) + if data is not None and len(data) == 1: + logger.debug("Adding / updating a {} assignment from json {}".format(type_element, + json_assignment)) + import_method(self._user_id, policy_id, json_assignment["id"], json_assignment["category_id"], + data_id) + else: + raise UnknownData("Unknown data with id {}".format(data_id)) + + # case the data has not been found in any policies + if has_found_data is False: + raise InvalidJson("The json contains unknown {} data or category : {}".format( + type_element, + json_item_assignment)) + + def _import_subject_object_action_datas(self, json_items_data, mandatory_policy_ids, type_element): + if type_element == "subject": + import_method = getattr(PolicyManager, 'set_' + type_element + '_data') + else: + import_method = getattr(PolicyManager, 'add_' + type_element + '_data') + # get_method = getattr(PolicyManager, 'get_' + type_element + '_data') + + if not isinstance(json_items_data, list): + raise InvalidJson(type_element + " data shall be a list!") + + for json_item_data in json_items_data: + item_override = JsonUtils.get_override(json_items_data) + if item_override is True: + raise ForbiddenOverride("{} datas do not support override flag !".format(type_element)) + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "name", str) + JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "description", str) + json_policy = dict() + # field_mandatory : not mandatory if there is some mandatory policies + JsonUtils.convert_names_to_ids(json_item_data, json_policy, "policies", "policy_id", "policy", + PolicyManager, self._user_id, field_mandatory=len(mandatory_policy_ids) == 0) + json_category = dict() + JsonUtils.convert_name_to_id(json_item_data, json_category, "category", "category_id", type_element+"_category", + ModelManager, self._user_id) + policy_ids = [] + if "policy_id" in json_policy: + policy_ids = json_policy["policy_id"] + + for policy_id in policy_ids: + if policy_id is not None and policy_id not in mandatory_policy_ids: + mandatory_policy_ids.append(policy_id) + + if len(mandatory_policy_ids) == 0: + raise InvalidJson("Invalid data, the policy shall be set when importing {}".format(json_item_data)) + category_id = None + if "category_id" in json_category: + category_id = json_category["category_id"] + if category_id is None: + raise InvalidJson("Invalid data, the category shall be set when importing {}".format(json_item_data)) + + for policy_id in mandatory_policy_ids: + try: + data = import_method(self._user_id, policy_id, category_id=category_id, value=json_to_use) + except exceptions.PolicyUnknown: + raise UnknownPolicy("Unknown policy with id {}".format(policy_id)) + except Exception as e: + logger.exception(str(e)) + raise e + + def _import_subject_object_action_categories(self, json_item_categories, type_element): + import_method = getattr(ModelManager, 'add_' + type_element + '_category') + get_method = getattr(ModelManager, 'get_' + type_element + '_categories') + + categories = get_method(self._user_id) + + if not isinstance(json_item_categories, list): + raise InvalidJson(type_element + " categories shall be a list!") + + for json_item_category in json_item_categories: + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_item_category, json_to_use, "name", str) + + # check if category with the same name exists : do this in moondb ? + existing_id = None + for category_key in categories: + if categories[category_key]["name"] == json_to_use["name"]: + existing_id = category_key + + JsonUtils.copy_field_if_exists(json_item_category, json_to_use, "description", str) + item_override = JsonUtils.get_override(json_item_category) + if item_override is True: + raise ForbiddenOverride("{} categories do not support override flag !".format(type_element)) + + try: + category = import_method(self._user_id, existing_id, json_to_use) + except (exceptions.SubjectCategoryExisting, exceptions.ObjectCategoryExisting, exceptions.ActionCategoryExisting): + # it already exists: do nothing + logger.warning("Ignored {} category with name {} is already in the database".format(type_element, json_to_use["name"])) + except Exception as e: + logger.warning("Error while importing the category : {}".format(str(e))) + logger.exception(str(e)) + raise e + + def _import_subject_object_action(self, json_items, mandatory_policy_ids, type_element): + import_method = getattr(PolicyManager, 'add_' + type_element) + get_method = getattr(PolicyManager, 'get_' + type_element + 's') + + if not isinstance(json_items, list): + raise InvalidJson(type_element + " items shall be a list!") + + for json_item in json_items: + json_without_policy_name = dict() + JsonUtils.copy_field_if_exists(json_item, json_without_policy_name, "name", str) + JsonUtils.copy_field_if_exists(json_item, json_without_policy_name, "description", str) + JsonUtils.copy_field_if_exists(json_item, json_without_policy_name, "extra", dict) + JsonUtils.convert_names_to_ids(json_item, json_without_policy_name, "policies", "policy_list", "policy", PolicyManager, self._user_id, field_mandatory=False) + policy_ids = json_without_policy_name["policy_list"] + for mandatory_policy_id in mandatory_policy_ids: + if mandatory_policy_id not in policy_ids: + policy_ids.append(mandatory_policy_id) + # policy_ids and json_without_policy_name are references to the same array... + # json_without_policy_name["policy_list"].append(mandatory_policy_id) + + item_override = JsonUtils.get_override(json_item) + if item_override is True: + raise ForbiddenOverride("{} does not support override flag !".format(type_element)) + + if len(policy_ids) == 0: + raise MissingPolicy("a {} needs at least one policy to be created or updated : {}".format(type_element, json.dumps(json_item))) + + for policy_id in policy_ids: + try: + items_in_db = get_method(self._user_id, policy_id) + key = None + for key_in_db in items_in_db: + if items_in_db[key_in_db]["name"] == json_without_policy_name["name"]: + key = key_in_db + break + element = import_method(self._user_id, policy_id, perimeter_id=key, value=json_without_policy_name) + logger.debug("Added / updated {} : {}".format(type_element, element)) + + except exceptions.PolicyUnknown: + raise UnknownPolicy("Unknown policy when adding a {}!".format(type_element)) + except Exception as e: + logger.exception(str(e)) + raise BaseException(str(e)) + + def _import_policies(self, json_policies): + policy_mandatory_ids = [] + + if not isinstance(json_policies, list): + raise InvalidJson("policies shall be a list!") + + for json_policy in json_policies: + # TODO put this in moondb + # policy_in_db = PolicyManager.get_policies_by_name(json_without_model_name["name"]) + policies = PolicyManager.get_policies(self._user_id) + policy_in_db = None + policy_id = None + for policy_key in policies: + if policies[policy_key]["name"] == json_policy["name"]: + policy_in_db = policies[policy_key] + policy_id = policy_key + # end TODO + if policy_in_db is None: + policy_does_exist = False + else: + policy_does_exist = True + + policy_override = JsonUtils.get_override(json_policy) + policy_mandatory = JsonUtils.get_mandatory(json_policy) + + if policy_override is False and policy_does_exist: + if policy_id: + policy_mandatory_ids.append(policy_id) + logger.warning("Existing policy not updated because of the override option is not set !") + continue + + json_without_model_name = dict() + JsonUtils.copy_field_if_exists(json_policy, json_without_model_name, "name", str) + JsonUtils.copy_field_if_exists(json_policy, json_without_model_name, "description", str) + JsonUtils.copy_field_if_exists(json_policy, json_without_model_name, "genre", str) + JsonUtils.convert_name_to_id(json_policy, json_without_model_name, "model", "model_id", "model", ModelManager, self._user_id, field_mandatory=False) + + if not policy_does_exist: + logger.debug("Creating policy {} ".format(json_without_model_name)) + added_policy = PolicyManager.add_policy(self._user_id, None, json_without_model_name) + if policy_mandatory is True: + keys = list(added_policy.keys()) + policy_mandatory_ids.append(keys[0]) + elif policy_override is True: + logger.debug("Updating policy {} ".format(json_without_model_name)) + updated_policy = PolicyManager.update_policy(self._user_id, policy_id, json_without_model_name) + if policy_mandatory is True: + policy_mandatory_ids.append(policy_id) + return policy_mandatory_ids + + def _import_models_with_new_meta_rules(self, json_models): + if not isinstance(json_models, list): + raise InvalidJson("models shall be a list!") + + for json_model in json_models: + logger.debug("json_model {}".format(json_model)) + models = ModelManager.get_models(self._user_id) + model_in_db = None + model_id = None + for model_key in models: + if ("id" in json_model and model_key == json_model["id"]) or ("name" in json_model and models[model_key]["name"] == json_model["name"]): + model_in_db = models[model_key] + model_id = model_key + + # this should not occur as the model has been put in db previously in _import_models_without_new_meta_rules + if model_in_db is None: + raise UnknownModel("Unknown model ") + + json_key = dict() + JsonUtils.convert_names_to_ids(json_model, json_key, "meta_rules", "meta_rule_id", "meta_rule", ModelManager, self._user_id) + for meta_rule_id in json_key["meta_rule_id"]: + if meta_rule_id not in model_in_db["meta_rules"]: + model_in_db["meta_rules"].append(meta_rule_id) + + ModelManager.update_model(self._user_id, model_id, model_in_db) + + def _import_models_without_new_meta_rules(self, json_models): + if not isinstance(json_models, list): + raise InvalidJson("models shall be a list!") + + for json_model in json_models: + json_without_new_metarules = dict() + JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "name", str) + + # TODO put this in moondb + # model_in_db = ModelManager.get_models_by_name(json_without_new_metarules["name"]) + models = ModelManager.get_models(self._user_id) + model_in_db = None + for model_key in models: + if models[model_key]["name"] == json_without_new_metarules["name"]: + model_in_db = models[model_key] + model_id = model_key + # end TODO + + JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "description", str) + if model_in_db is None: + model_does_exist = False + else: + json_without_new_metarules["meta_rule_id"] = model_in_db["meta_rules"] + model_does_exist = True + model_override = JsonUtils.get_override(json_model) + if not model_does_exist: + logger.debug("Creating model {} ".format(json_without_new_metarules)) + ModelManager.add_model(self._user_id, None, json_without_new_metarules) + elif model_override is True: + logger.debug("Updating model with id {} : {} ".format(model_id, json_without_new_metarules)) + ModelManager.update_model(self._user_id, model_id, json_without_new_metarules) + + def _import_pdps(self, json_pdps): + if not isinstance(json_pdps, list): + raise InvalidJson("pdps shall be a list!") + + for json_pdp in json_pdps: + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "name", str) + JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "keystone_project_id", str) + JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "security_pipeline", list) + JsonUtils.copy_field_if_exists(json_pdp, json_to_use, "description", str) + + pdps = PDPManager.get_pdp(self._user_id) + exists = False + for pdp_key in pdps: + if pdps[pdp_key]["name"] == json_to_use["name"]: + PDPManager.update_pdp(self._user_id, pdp_id=pdp_key, value=json_to_use) + exists = True + if exists is False: + PDPManager.add_pdp(self._user_id, value=json_to_use) + + def _import_json(self, user_id): + self._user_id = user_id + if 'file' in request.files: + file = request.files['file'] + logger.debug("Importing {} file...".format(file)) + json_content = json.load(file) + else: + json_content = request.json + logger.debug("Importing content: {} ...".format(json_content)) + + # first import the models without the meta rules as they are not yet defined + if "models" in json_content: + logger.info("Importing models...") + self._import_models_without_new_meta_rules(json_content["models"]) + + # import the policies that depends on the models + mandatory_policy_ids = [] + if "policies" in json_content: + logger.info("Importing policies...") + mandatory_policy_ids = self._import_policies(json_content["policies"]) + + # import subjects, subject_data, subject_categories, idem for object and action + list_element = [{"key": "subject"}, {"key": "object"}, {"key": "action"}] + for elt in list_element: + in_key = elt["key"] + key = in_key + "s" + if key in json_content: + logger.info("Importing {}...".format(key)) + self._import_subject_object_action(json_content[key], mandatory_policy_ids, in_key) + key = in_key + "_categories" + if key in json_content: + logger.info("Importing {}...".format(key)) + self._import_subject_object_action_categories(json_content[key], in_key) + key = in_key + "_data" + if key in json_content: + logger.info("Importing {}...".format(key)) + self._import_subject_object_action_datas(json_content[key], mandatory_policy_ids, in_key) + + # import meta rules + if "meta_rules" in json_content: + logger.info("Importing meta rules...") + self._import_meta_rules(json_content["meta_rules"]) + + # add the metarule to model + if "models" in json_content: + logger.info("Updating models with meta rules...") + self._import_models_with_new_meta_rules(json_content["models"]) + + # import subjects assignments, idem for object and action + for elt in list_element: + in_key = elt["key"] + key = in_key + "_assignments" + if key in json_content: + logger.info("Importing {}...".format(key)) + self._import_subject_object_action_assignments(json_content[key], in_key) + + # import rules + if "rules" in json_content: + logger.info("Importing rules...") + self._import_rules(json_content["rules"]) + + # import pdps + if "pdps" in json_content: + logger.info("Importing pdps...") + self._import_pdps(json_content["pdps"]) + + @check_auth + def post(self, user_id=None): + """Import file. + + :param user_id: user ID who do the request + :return: { + + } + :internal_api: + """ + self._import_json(user_id) + return "Import ok !" diff --git a/moon_manager/moon_manager/api/json_utils.py b/moon_manager/moon_manager/api/json_utils.py new file mode 100644 index 00000000..cc4c8b0f --- /dev/null +++ b/moon_manager/moon_manager/api/json_utils.py @@ -0,0 +1,255 @@ +import logging +from moon_manager.api.base_exception import BaseException + +logger = logging.getLogger("moon.manager.api." + __name__) + + +class UnknownName(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(UnknownName, self).__init__(message) + + +class UnknownId(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(UnknownId, self).__init__(message) + + +class MissingIdOrName(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(MissingIdOrName, self).__init__(message) + + +class UnknownField(BaseException): + def __init__(self, message): + + # Call the base class constructor with the parameters it needs + super(UnknownField, self).__init__(message) + + +class JsonUtils: + @staticmethod + def get_override(json_content): + if "override" in json_content: + return json_content["override"] + return False + + @staticmethod + def get_mandatory(json_content): + if "mandatory" in json_content: + return json_content["mandatory"] + return False + + @staticmethod + def copy_field_if_exists(json_in, json_out, field_name, type_field, default_value=None): + if field_name in json_in: + json_out[field_name] = json_in[field_name] + else: + if type_field is bool: + if default_value is None: + default_value = False + json_out[field_name] = default_value + if type_field is str: + if default_value is None: + default_value = "" + json_out[field_name] = default_value + if type_field is dict: + json_out[field_name] = dict() + if type_field is list: + json_out[field_name] = [] + + @staticmethod + def _get_element_in_db_from_id(element_type, element_id, user_id, policy_id, category_id, meta_rule_id, manager): + # the item is supposed to be in the db, we check it exists! + if element_type == "model": + data_db = manager.get_models(user_id, model_id=element_id) + elif element_type == "policy": + data_db = manager.get_policies(user_id, policy_id=element_id) + elif element_type == "subject": + data_db = manager.get_subjects(user_id, policy_id, perimeter_id=element_id) + elif element_type == "object": + data_db = manager.get_objects(user_id, policy_id, perimeter_id=element_id) + elif element_type == "action": + data_db = manager.get_actions(user_id, policy_id, perimeter_id=element_id) + elif element_type == "subject_category": + data_db = manager.get_subject_categories(user_id, category_id=element_id) + elif element_type == "object_category": + data_db = manager.get_object_categories(user_id, category_id=element_id) + elif element_type == "action_category": + data_db = manager.get_action_categories(user_id, category_id=element_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(user_id, meta_rule_id=element_id) + elif element_type == "subject_data": + data_db = manager.get_subject_data(user_id, policy_id, data_id=element_id, category_id=category_id) + elif element_type == "object_data": + data_db = manager.get_object_data(user_id, policy_id, data_id=element_id, category_id=category_id) + elif element_type == "action_data": + data_db = manager.get_action_data(user_id, policy_id, data_id=element_id, category_id=category_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(user_id, meta_rule_id=meta_rule_id) + else: + raise Exception("Conversion of {} not implemented yet!".format(element_type)) + + # logger.info(data_db) + + # do some post processing ... the result should be {key : { .... .... } } + if element_type == "subject_data" or element_type == "object_data" or element_type == "action_data": + if data_db is not None and isinstance(data_db, list): + # TODO remove comments after fixing the bug on moondb when adding metarule : we can have several identical entries ! + #if len(data_db) > 1: + # raise Exception("Several {} with the same id : {}".format(element_type, data_db)) + data_db = data_db[0] + + if data_db is not None and data_db["data"] is not None and isinstance(data_db["data"], dict): + # TODO remove comments after fixing the bug on moondb when adding metarule : we can have several identical entries ! + #if len(data_db["data"].values()) != 1: + # raise Exception("Several {} with the same id : {}".format(element_type, data_db)) + #data_db = data_db["data"] + # TODO remove these two lines after fixing the bug on moondb when adding metarule : we can have several identical entries ! + list_values = list(data_db["data"].values()) + data_db = list_values[0] + # logger.info("subject data after postprocessing {}".format(data_db)) + return data_db + + @staticmethod + def _get_element_id_in_db_from_name(element_type, element_name, user_id, policy_id, category_id, meta_rule_id, manager): + if element_type == "model": + data_db = manager.get_models(user_id) + elif element_type == "policy": + data_db = manager.get_policies(user_id) + elif element_type == "subject": + data_db = manager.get_subjects(user_id, policy_id) + elif element_type == "object": + data_db = manager.get_objects(user_id, policy_id) + elif element_type == "action": + data_db = manager.get_actions(user_id, policy_id) + elif element_type == "subject_category": + data_db = manager.get_subject_categories(user_id) + elif element_type == "object_category": + data_db = manager.get_object_categories(user_id) + elif element_type == "action_category": + data_db = manager.get_action_categories(user_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(user_id) + elif element_type == "subject_data": + data_db = manager.get_subject_data(user_id, policy_id, category_id=category_id) + elif element_type == "object_data": + data_db = manager.get_object_data(user_id, policy_id, category_id=category_id) + elif element_type == "action_data": + data_db = manager.get_action_data(user_id, policy_id, category_id=category_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(user_id) + elif element_type == "rule": + data_db = manager.get_rules(user_id, policy_id) + else: + raise BaseException("Conversion of {} not implemented yet!".format(element_type)) + + if isinstance(data_db, dict): + for key_id in data_db: + if isinstance(data_db[key_id], dict) and "name" in data_db[key_id]: + if data_db[key_id]["name"] == element_name: + return key_id + else: + for elt in data_db: + if isinstance(elt, dict) and "data" in elt: # we handle here subject_data, object_data and action_data... + for data_key in elt["data"]: + # logger.info("data from the db {} ".format(elt["data"][data_key])) + data = elt["data"][data_key] + if "name" in data and data["name"] == element_name: + return data_key + if "value" in data and data["value"]["name"] == element_name: + return data_key + return None + + @staticmethod + def convert_name_to_id(json_in, json_out, field_name_in, field_name_out, element_type, manager, user_id, policy_id=None, category_id=None, meta_rule_id=None, field_mandatory=True): + if field_name_in not in json_in: + raise UnknownField("The field {} is not in the input json".format(field_name_in)) + + if "id" in json_in[field_name_in]: + data_db = JsonUtils._get_element_in_db_from_id(element_type, json_in[field_name_in]["id"], user_id, policy_id, category_id, meta_rule_id, manager) + if data_db is None: + raise UnknownId("No {} with id {} found in database".format(element_type, json_in[field_name_in]["id"])) + json_out[field_name_out] = json_in[field_name_in]["id"] + + elif "name" in json_in[field_name_in]: + id_in_db = JsonUtils._get_element_id_in_db_from_name(element_type, json_in[field_name_in]["name"], user_id, policy_id, category_id, meta_rule_id, manager) + if id_in_db is None: + raise UnknownName("No {} with name {} found in database".format(element_type,json_in[field_name_in]["name"])) + json_out[field_name_out] = id_in_db + elif field_mandatory is True: + raise MissingIdOrName("No id or name found in the input json {}".format(json_in)) + + @staticmethod + def convert_id_to_name(id_, json_out, field_name_out, element_type, manager, user_id, + policy_id=None, category_id=None, meta_rule_id=None): + json_out[field_name_out] = {"name": JsonUtils.convert_id_to_name_string(id_, element_type, manager, user_id, policy_id, category_id, meta_rule_id)} + + @staticmethod + def __convert_results_to_element(element): + if isinstance(element, dict) and "name" not in element and "value" not in element: + list_values = [v for v in element.values()] + elif isinstance(element, list): + list_values = element + else: + list_values = [] + list_values.append(element) + return list_values[0] + + @staticmethod + def convert_id_to_name_string(id_, element_type, manager, user_id, + policy_id=None, category_id=None, meta_rule_id=None): + + element = JsonUtils._get_element_in_db_from_id(element_type, id_, user_id, policy_id, category_id, meta_rule_id, manager) + # logger.info(element) + if element is None: + raise UnknownId("No {} with id {} found in database".format(element_type, id_)) + res = JsonUtils.__convert_results_to_element(element) + # logger.info(res) + if "name" in res: + return res["name"] + if "value" in res and "name" in res["value"]: + return res["value"]["name"] + return None + + @staticmethod + def convert_names_to_ids(json_in, json_out, field_name_in, field_name_out, element_type, manager, user_id, policy_id=None, category_id=None, meta_rule_id=None, field_mandatory=True): + ids = [] + if field_name_in not in json_in: + raise UnknownField("The field {} is not in the input json".format(field_name_in)) + + for elt in json_in[field_name_in]: + if "id" in elt: + data_db = JsonUtils._get_element_in_db_from_id(element_type, elt["id"], user_id, policy_id, category_id, meta_rule_id, manager) + if data_db is None: + raise UnknownId("No {} with id {} found in database".format(element_type, elt["id"])) + ids.append(elt["id"]) + elif "name" in elt: + id_in_db = JsonUtils._get_element_id_in_db_from_name(element_type, elt["name"], user_id, policy_id, category_id, meta_rule_id, manager) + if id_in_db is None: + raise UnknownName("No {} with name {} found in database".format(element_type, elt["name"])) + ids.append(id_in_db) + elif field_mandatory is True: + raise MissingIdOrName("No id or name found in the input json {}".format(elt)) + json_out[field_name_out] = ids + + @staticmethod + def convert_ids_to_names(ids, json_out, field_name_out, element_type, manager, user_id, policy_id=None, category_id=None, meta_rule_id=None): + res_array = [] + for id_ in ids: + element = JsonUtils._get_element_in_db_from_id(element_type, id_, user_id, policy_id, category_id, meta_rule_id, manager) + if element is None: + raise UnknownId("No {} with id {} found in database".format(element_type, id_)) + res = JsonUtils.__convert_results_to_element(element) + # logger.info(res) + if "name" in res: + res_array.append({"name": res["name"]}) + if "value" in res and "name" in res["value"]: + res_array.append({"name": res["value"]["name"]}) + json_out[field_name_out] = res_array + diff --git a/moon_manager/moon_manager/api/meta_data.py b/moon_manager/moon_manager/api/meta_data.py index 28aab445..62ca050f 100644 --- a/moon_manager/moon_manager/api/meta_data.py +++ b/moon_manager/moon_manager/api/meta_data.py @@ -12,6 +12,7 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import ModelManager +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -29,6 +30,7 @@ class SubjectCategories(Resource): "/subject_categories/<string:category_id>", ) + @validate_input("get",kwargs_state=[False,False]) @check_auth def get(self, category_id=None, user_id=None): """Retrieve all subject categories or a specific one @@ -38,20 +40,17 @@ class SubjectCategories(Resource): :return: { "subject_category_id": { "name": "name of the category", - "description": "description of the category" + "description": "description of the category (optional)" } } :internal_api: get_subject_categories """ - try: - data = ModelManager.get_subject_categories( - user_id=user_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.get_subject_categories( + user_id=user_id, category_id=category_id) + return {"subject_categories": data} + @validate_input("post",body_state={"name":True}) @check_auth def post(self, category_id=None, user_id=None): """Create or update a subject category. @@ -59,26 +58,23 @@ class SubjectCategories(Resource): :param category_id: must not be used here :param user_id: user ID who do the request :request body: { - "name": "name of the category", - "description": "description of the category" + "name": "name of the category (mandatory)", + "description": "description of the category (optional)" } :return: { "subject_category_id": { "name": "name of the category", - "description": "description of the category" + "description": "description of the category (optional)" } } :internal_api: add_subject_category """ - try: - data = ModelManager.add_subject_category( - user_id=user_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.add_subject_category( + user_id=user_id, value=request.json) + return {"subject_categories": data} + @validate_input("delete",kwargs_state=[True,False]) @check_auth def delete(self, category_id=None, user_id=None): """Delete a subject category @@ -87,17 +83,14 @@ class SubjectCategories(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_subject_category """ - try: - data = ModelManager.delete_subject_category( - user_id=user_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.delete_subject_category( + user_id=user_id, category_id=category_id) + return {"result": True} @@ -112,6 +105,7 @@ class ObjectCategories(Resource): "/object_categories/<string:category_id>", ) + @validate_input("get",kwargs_state=[False,False]) @check_auth def get(self, category_id=None, user_id=None): """Retrieve all object categories or a specific one @@ -121,20 +115,17 @@ class ObjectCategories(Resource): :return: { "object_category_id": { "name": "name of the category", - "description": "description of the category" + "description": "description of the category (optional)" } } :internal_api: get_object_categories """ - try: - data = ModelManager.get_object_categories( - user_id=user_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.get_object_categories( + user_id=user_id, category_id=category_id) + return {"object_categories": data} + @validate_input("post", body_state={"name":True}) @check_auth def post(self, category_id=None, user_id=None): """Create or update a object category. @@ -142,26 +133,24 @@ class ObjectCategories(Resource): :param category_id: must not be used here :param user_id: user ID who do the request :request body: { - "name": "name of the category", - "description": "description of the category" + "name": "name of the category (mandatory)", + "description": "description of the category (optional)" } :return: { "object_category_id": { "name": "name of the category", - "description": "description of the category" + "description": "description of the category (optional)" } } :internal_api: add_object_category """ - try: - data = ModelManager.add_object_category( - user_id=user_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.add_object_category( + user_id=user_id, value=request.json) + return {"object_categories": data} + @validate_input("delete", kwargs_state=[True, False]) @check_auth def delete(self, category_id=None, user_id=None): """Delete an object category @@ -170,17 +159,14 @@ class ObjectCategories(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_object_category """ - try: - data = ModelManager.delete_object_category( - user_id=user_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.delete_object_category( + user_id=user_id, category_id=category_id) + return {"result": True} @@ -195,6 +181,7 @@ class ActionCategories(Resource): "/action_categories/<string:category_id>", ) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, category_id=None, user_id=None): """Retrieve all action categories or a specific one @@ -204,20 +191,18 @@ class ActionCategories(Resource): :return: { "action_category_id": { "name": "name of the category", - "description": "description of the category" + "description": "description of the category (optional)" } } :internal_api: get_action_categories """ - try: - data = ModelManager.get_action_categories( - user_id=user_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.get_action_categories( + user_id=user_id, category_id=category_id) + return {"action_categories": data} + @validate_input("post", body_state={"name":True}) @check_auth def post(self, category_id=None, user_id=None): """Create or update an action category. @@ -225,26 +210,24 @@ class ActionCategories(Resource): :param category_id: must not be used here :param user_id: user ID who do the request :request body: { - "name": "name of the category", - "description": "description of the category" + "name": "name of the category (mandatory)", + "description": "description of the category (optional)" } :return: { "action_category_id": { "name": "name of the category", - "description": "description of the category" + "description": "description of the category (optional)" } } :internal_api: add_action_category """ - try: - data = ModelManager.add_action_category( - user_id=user_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.add_action_category( + user_id=user_id, value=request.json) + return {"action_categories": data} + @validate_input("delete", kwargs_state=[True, False]) @check_auth def delete(self, category_id=None, user_id=None): """Delete an action @@ -253,15 +236,11 @@ class ActionCategories(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_action_category """ - try: - data = ModelManager.delete_action_category( - user_id=user_id, category_id=category_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.delete_action_category( + user_id=user_id, category_id=category_id) + return {"result": True} diff --git a/moon_manager/moon_manager/api/meta_rules.py b/moon_manager/moon_manager/api/meta_rules.py index 25ae5aac..3dc9996b 100644 --- a/moon_manager/moon_manager/api/meta_rules.py +++ b/moon_manager/moon_manager/api/meta_rules.py @@ -12,6 +12,7 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import ModelManager +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -30,6 +31,7 @@ class MetaRules(Resource): "/meta_rules/<string:meta_rule_id>/" ) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, meta_rule_id=None, user_id=None): """Retrieve all sub meta rules @@ -40,7 +42,6 @@ class MetaRules(Resource): "meta_rules": { "meta_rule_id1": { "name": "name of the meta rule", - "algorithm": "name of the meta rule algorithm", "subject_categories": ["subject_category_id1", "subject_category_id2"], "object_categories": ["object_category_id1"], @@ -50,27 +51,25 @@ class MetaRules(Resource): } :internal_api: get_meta_rules """ - try: - data = ModelManager.get_meta_rules( - user_id=user_id, meta_rule_id=meta_rule_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.get_meta_rules( + user_id=user_id, meta_rule_id=meta_rule_id) + return {"meta_rules": data} + @validate_input("post", body_state={"name":True, "subject_categories":True, "object_categories":True, "action_categories":True}) @check_auth def post(self, meta_rule_id=None, user_id=None): """Add a meta rule - :param meta_rule_id: Meta rule ID + :param meta_rule_id: Meta rule ID (not used here) :param user_id: user ID who do the request :request body: post = { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", + "name": "name of the meta rule (mandatory)", + "subject_categories": ["subject_category_id1 (mandatory)", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] + "object_categories": ["object_category_id1 (mandatory)"], + "action_categories": ["action_category_id1 (mandatory)"] } :return: { "meta_rules": { @@ -85,15 +84,13 @@ class MetaRules(Resource): } :internal_api: add_meta_rules """ - try: - data = ModelManager.add_meta_rule( - user_id=user_id, meta_rule_id=None, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.add_meta_rule( + user_id=user_id, meta_rule_id=None, value=request.json) + return {"meta_rules": data} + @validate_input("patch", kwargs_state=[True, False], body_state={"name":True, "subject_categories":True, "object_categories":True, "action_categories":True}) @check_auth def patch(self, meta_rule_id=None, user_id=None): """Update a meta rule @@ -120,28 +117,18 @@ class MetaRules(Resource): } :internal_api: set_meta_rules """ - try: - data = ModelManager.set_meta_rule( - user_id=user_id, meta_rule_id=meta_rule_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.set_meta_rule( + user_id=user_id, meta_rule_id=meta_rule_id, value=request.json) + return {"meta_rules": data} + @validate_input("delete", kwargs_state=[True, False]) @check_auth def delete(self, meta_rule_id=None, user_id=None): """Delete a meta rule :param meta_rule_id: Meta rule ID :param user_id: user ID who do the request - :request body: delete = { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", - "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - } :return: { "meta_rules": { "meta_rule_id1": { @@ -155,12 +142,9 @@ class MetaRules(Resource): } :internal_api: delete_meta_rules """ - try: - data = ModelManager.delete_meta_rule( - user_id=user_id, meta_rule_id=meta_rule_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.delete_meta_rule( + user_id=user_id, meta_rule_id=meta_rule_id) + return {"result": True} diff --git a/moon_manager/moon_manager/api/models.py b/moon_manager/moon_manager/api/models.py index 07b10d90..c3068367 100644 --- a/moon_manager/moon_manager/api/models.py +++ b/moon_manager/moon_manager/api/models.py @@ -11,6 +11,7 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import ModelManager +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -29,6 +30,7 @@ class Models(Resource): "/models/<string:uuid>/", ) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, uuid=None, user_id=None): """Retrieve all models @@ -38,20 +40,17 @@ class Models(Resource): :return: { "model_id1": { "name": "...", - "description": "...", + "description": "... (optional)", "meta_rules": ["meta_rule_id1", ] } } :internal_api: get_models """ - try: - data = ModelManager.get_models(user_id=user_id, model_id=uuid) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.get_models(user_id=user_id, model_id=uuid) + return {"models": data} + @validate_input("post", body_state={"name":True, "meta_rules":True}) @check_auth def post(self, uuid=None, user_id=None): """Create model. @@ -59,28 +58,25 @@ class Models(Resource): :param uuid: uuid of the model (not used here) :param user_id: user ID who do the request :request body: { - "name": "...", - "description": "...", + "name": "name of the model (mandatory)", + "description": "description of the model (optional)", "meta_rules": ["meta_rule_id1", ] } :return: { "model_id1": { - "name": "...", - "description": "...", + "name": "name of the model", + "description": "description of the model (optional)", "meta_rules": ["meta_rule_id1", ] } } :internal_api: add_model """ - try: - data = ModelManager.add_model( - user_id=user_id, model_id=uuid, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.add_model( + user_id=user_id, model_id=uuid, value=request.json) + return {"models": data} + @validate_input("delete", kwargs_state=[True, False]) @check_auth def delete(self, uuid=None, user_id=None): """Delete a model @@ -89,18 +85,16 @@ class Models(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_model """ - try: - data = ModelManager.delete_model(user_id=user_id, model_id=uuid) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = ModelManager.delete_model(user_id=user_id, model_id=uuid) + return {"result": True} + @validate_input("patch", kwargs_state=[True, False], body_state={"name":True, "meta_rules":True}) @check_auth def patch(self, uuid=None, user_id=None): """Update a model @@ -109,19 +103,15 @@ class Models(Resource): :param user_id: user ID who do the request :return: { "model_id1": { - "name": "...", - "description": "...", + "name": "name of the model", + "description": "... (optional)", "meta_rules": ["meta_rule_id1", ] } } :internal_api: update_model """ - try: - data = ModelManager.update_model( - user_id=user_id, model_id=uuid, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = ModelManager.update_model( + user_id=user_id, model_id=uuid, value=request.json) + return {"models": data} diff --git a/moon_manager/moon_manager/api/pdp.py b/moon_manager/moon_manager/api/pdp.py index 4f11135e..a5d7c007 100644 --- a/moon_manager/moon_manager/api/pdp.py +++ b/moon_manager/moon_manager/api/pdp.py @@ -17,6 +17,7 @@ from python_moondb.core import PDPManager from python_moondb.core import PolicyManager from python_moondb.core import ModelManager from python_moonutilities import configuration, exceptions +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -73,7 +74,7 @@ def add_pod(uuid, data): time.sleep(1) else: break - logger.info(req.text) + logger.info("Pod add request answer : {}".format(req.text)) def check_keystone_pid(k_pid): @@ -96,6 +97,7 @@ class PDP(Resource): "/pdp/<string:uuid>/", ) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, uuid=None, user_id=None): """Retrieve all pdp @@ -107,19 +109,17 @@ class PDP(Resource): "name": "...", "security_pipeline": [...], "keystone_project_id": "keystone_project_id1", - "description": "...", + "description": "... (optional)", } } :internal_api: get_pdp """ - try: - data = PDPManager.get_pdp(user_id=user_id, pdp_id=uuid) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PDPManager.get_pdp(user_id=user_id, pdp_id=uuid) + return {"pdps": data} + @validate_input("post", body_state={"name": True, "security_pipeline": True, "keystone_project_id": True}) @check_auth def post(self, uuid=None, user_id=None): """Create pdp. @@ -127,92 +127,84 @@ class PDP(Resource): :param uuid: uuid of the pdp (not used here) :param user_id: user ID who do the request :request body: { - "name": "...", - "security_pipeline": [...], - "keystone_project_id": "keystone_project_id1", - "description": "...", + "name": "name of the PDP (mandatory)", + "security_pipeline": ["may be empty"], + "keystone_project_id": "keystone_project_id1 (may be empty)", + "description": "description of the PDP (optional)", } :return: { "pdp_id1": { "name": "...", "security_pipeline": [...], "keystone_project_id": "keystone_project_id1", - "description": "...", + "description": "... (optional)", } } :internal_api: add_pdp """ - try: - data = dict(request.json) - if not data.get("keystone_project_id"): - data["keystone_project_id"] = None - else: - if check_keystone_pid(data.get("keystone_project_id")): - raise exceptions.PdpKeystoneMappingConflict - data = PDPManager.add_pdp( - user_id=user_id, pdp_id=None, value=request.json) - uuid = list(data.keys())[0] - logger.debug("data={}".format(data)) - logger.debug("uuid={}".format(uuid)) - add_pod(uuid=uuid, data=data[uuid]) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = dict(request.json) + if not data.get("keystone_project_id"): + data["keystone_project_id"] = None + else: + if check_keystone_pid(data.get("keystone_project_id")): + raise exceptions.PdpKeystoneMappingConflict + data = PDPManager.add_pdp( + user_id=user_id, pdp_id=None, value=request.json) + uuid = list(data.keys())[0] + logger.debug("data={}".format(data)) + logger.debug("uuid={}".format(uuid)) + add_pod(uuid=uuid, data=data[uuid]) + return {"pdps": data} + @validate_input("delete", kwargs_state=[True, False]) @check_auth - def delete(self, uuid=None, user_id=None): + def delete(self, uuid, user_id=None): """Delete a pdp :param uuid: uuid of the pdp to delete :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_pdp """ - try: - data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid) - delete_pod(uuid) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + data = PDPManager.delete_pdp(user_id=user_id, pdp_id=uuid) + delete_pod(uuid) + return {"result": True} + @validate_input("patch", kwargs_state=[True, False], body_state={"name": True, "security_pipeline": True, "keystone_project_id": True}) @check_auth - def patch(self, uuid=None, user_id=None): + def patch(self, uuid, user_id=None): """Update a pdp :param uuid: uuid of the pdp to update :param user_id: user ID who do the request :return: { "pdp_id1": { - "name": "...", - "security_pipeline": [...], - "keystone_project_id": "keystone_project_id1", - "description": "...", + "name": "name of the PDP", + "security_pipeline": ["may be empty"], + "keystone_project_id": "keystone_project_id1 (may be empty)", + "description": "description of the PDP (optional)", } } :internal_api: update_pdp """ - try: - _data = dict(request.json) - if not _data.get("keystone_project_id"): - _data["keystone_project_id"] = None - else: - if check_keystone_pid(_data.get("keystone_project_id")): - raise exceptions.PdpKeystoneMappingConflict - data = PDPManager.update_pdp( - user_id=user_id, pdp_id=uuid, value=_data) - logger.debug("data={}".format(data)) - logger.debug("uuid={}".format(uuid)) - add_pod(uuid=uuid, data=data[uuid]) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + _data = dict(request.json) + if not _data.get("keystone_project_id"): + _data["keystone_project_id"] = None + else: + if check_keystone_pid(_data.get("keystone_project_id")): + raise exceptions.PdpKeystoneMappingConflict + data = PDPManager.update_pdp( + user_id=user_id, pdp_id=uuid, value=_data) + logger.debug("data={}".format(data)) + logger.debug("uuid={}".format(uuid)) + add_pod(uuid=uuid, data=data[uuid]) + return {"pdps": data} diff --git a/moon_manager/moon_manager/api/perimeter.py b/moon_manager/moon_manager/api/perimeter.py index d3948bc1..6c39c43d 100644 --- a/moon_manager/moon_manager/api/perimeter.py +++ b/moon_manager/moon_manager/api/perimeter.py @@ -15,6 +15,8 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager +from python_moonutilities.security_functions import validate_input + __version__ = "4.3.2" @@ -35,6 +37,7 @@ class Subjects(Resource): "/policies/<string:uuid>/subjects/<string:perimeter_id>", ) + @validate_input("get", kwargs_state=[False, False, False]) @check_auth def get(self, uuid=None, perimeter_id=None, user_id=None): """Retrieve all subjects or a specific one if perimeter_id is @@ -47,67 +50,63 @@ class Subjects(Resource): "subject_id": { "name": "name of the subject", "keystone_id": "keystone id of the subject", - "description": "a description" + "description": "a description (optional)" } } :internal_api: get_subjects """ - try: - data = PolicyManager.get_subjects( - user_id=user_id, - policy_id=uuid, - perimeter_id=perimeter_id - ) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_subjects( + user_id=user_id, + policy_id=uuid, + perimeter_id=perimeter_id + ) + return {"subjects": data} + @validate_input("post", body_state={"name":True}) @check_auth - def post(self, uuid=None, perimeter_id=None, user_id=None): + def post(self, uuid, perimeter_id=None, user_id=None): """Create or update a subject. :param uuid: uuid of the policy :param perimeter_id: must not be used here :param user_id: user ID who do the request :request body: { - "name": "name of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" + "name": "name of the subject (mandatory)", + "description": "description of the subject (optional)", + "password": "password for the subject (optional)", + "email": "email address of the subject (optional)" } :return: { "subject_id": { "name": "name of the subject", "keystone_id": "keystone id of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" + "description": "description of the subject (optional)", + "password": "password for the subject (optional)", + "email": "email address of the subject (optional)" } } :internal_api: set_subject """ - try: - if not perimeter_id: - data = PolicyManager.get_subjects(user_id=user_id, - policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_subject( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + if not perimeter_id: + data = PolicyManager.get_subjects(user_id=user_id, + policy_id=uuid) + if 'name' in request.json: + for data_id, data_value in data.items(): + if data_value['name'] == request.json['name']: + perimeter_id = data_id + break + data = PolicyManager.add_subject( + user_id=user_id, policy_id=uuid, + perimeter_id=perimeter_id, value=request.json) + return {"subjects": data} + @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True}) @check_auth - def patch(self, uuid=None, perimeter_id=None, user_id=None): + def patch(self, uuid, perimeter_id=None, user_id=None): """Create or update a subject. :param uuid: uuid of the policy @@ -115,64 +114,59 @@ class Subjects(Resource): :param user_id: user ID who do the request :request body: { "name": "name of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" + "description": "description of the subject (optional)", + "password": "password for the subject (optional)", + "email": "email address of the subject (optional)" } :return: { "subject_id": { "name": "name of the subject", "keystone_id": "keystone id of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" + "description": "description of the subject (optional)", + "password": "password for the subject (optional)", + "email": "email address of the subject (optional)" } } :internal_api: set_subject """ - try: - if not perimeter_id: - data = PolicyManager.get_subjects(user_id=user_id, - policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_subject( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + if not perimeter_id: + data = PolicyManager.get_subjects(user_id=user_id, + policy_id=None) + if 'name' in request.json: + for data_id, data_value in data.items(): + if data_value['name'] == request.json['name']: + perimeter_id = data_id + break + data = PolicyManager.add_subject( + user_id=user_id, policy_id=uuid, + perimeter_id=perimeter_id, value=request.json) + return {"subjects": data} + @validate_input("delete", kwargs_state=[False, True, False]) @check_auth def delete(self, uuid=None, perimeter_id=None, user_id=None): """Delete a subject for a given policy - :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject + :param uuid: uuid of the policy (mandatory if perimeter_id is not set) + :param perimeter_id: uuid of the subject (mandatory if uuid is not set) :param user_id: user ID who do the request :return: { "subject_id": { "name": "name of the subject", "keystone_id": "keystone id of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" + "description": "description of the subject (optional)", + "password": "password for the subject (optional)", + "email": "email address of the subject (optional)" } } :internal_api: delete_subject """ - try: - data = PolicyManager.delete_subject( - user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_subject( + user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) + return {"result": True} @@ -190,6 +184,7 @@ class Objects(Resource): "/policies/<string:uuid>/objects/<string:perimeter_id>", ) + @validate_input("get", kwargs_state=[False, False, False]) @check_auth def get(self, uuid=None, perimeter_id=None, user_id=None): """Retrieve all objects or a specific one if perimeter_id is @@ -201,60 +196,56 @@ class Objects(Resource): :return: { "object_id": { "name": "name of the object", - "description": "description of the object" + "description": "description of the object (optional)" } } :internal_api: get_objects """ - try: - data = PolicyManager.get_objects( - user_id=user_id, - policy_id=uuid, - perimeter_id=perimeter_id - ) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_objects( + user_id=user_id, + policy_id=uuid, + perimeter_id=perimeter_id + ) + return {"objects": data} + @validate_input("post", body_state={"name":True}) @check_auth - def post(self, uuid=None, perimeter_id=None, user_id=None): + def post(self, uuid, perimeter_id=None, user_id=None): """Create or update a object. :param uuid: uuid of the policy :param perimeter_id: must not be used here :param user_id: user ID who do the request :request body: { - "object_name": "name of the object", - "object_description": "description of the object" + "object_name": "name of the object (mandatory)", + "object_description": "description of the object (optional)" } :return: { "object_id": { "name": "name of the object", - "description": "description of the object" + "description": "description of the object (optional)" } } :internal_api: set_object """ - try: - data = PolicyManager.get_objects(user_id=user_id, policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_object( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_objects(user_id=user_id, policy_id=uuid) + if 'name' in request.json: + for data_id, data_value in data.items(): + if data_value['name'] == request.json['name']: + perimeter_id = data_id + break + data = PolicyManager.add_object( + user_id=user_id, policy_id=uuid, + perimeter_id=perimeter_id, value=request.json) + return {"objects": data} + @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True}) @check_auth - def patch(self, uuid=None, perimeter_id=None, user_id=None): + def patch(self, uuid, perimeter_id=None, user_id=None): """Create or update a object. :param uuid: uuid of the policy @@ -262,54 +253,49 @@ class Objects(Resource): :param user_id: user ID who do the request :request body: { "object_name": "name of the object", - "object_description": "description of the object" + "object_description": "description of the object (optional)" } :return: { "object_id": { "name": "name of the object", - "description": "description of the object" + "description": "description of the object (optional)" } } :internal_api: set_object """ - try: - data = PolicyManager.get_objects(user_id=user_id, policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_object( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_objects(user_id=user_id, policy_id=uuid) + if 'name' in request.json: + for data_id, data_value in data.items(): + if data_value['name'] == request.json['name']: + perimeter_id = data_id + break + data = PolicyManager.add_object( + user_id=user_id, policy_id=uuid, + perimeter_id=perimeter_id, value=request.json) + return {"objects": data} + @validate_input("delete", kwargs_state=[False, True, False]) @check_auth def delete(self, uuid=None, perimeter_id=None, user_id=None): """Delete a object for a given policy - :param uuid: uuid of the policy - :param perimeter_id: uuid of the object + :param uuid: uuid of the policy (mandatory if perimeter_id is not set) + :param perimeter_id: uuid of the object (mandatory if uuid is not set) :param user_id: user ID who do the request :return: { "object_id": { "name": "name of the object", - "description": "description of the object" + "description": "description of the object (optional)" } } :internal_api: delete_object """ - try: - data = PolicyManager.delete_object( - user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_object( + user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) + return {"result": True} @@ -327,6 +313,7 @@ class Actions(Resource): "/policies/<string:uuid>/actions/<string:perimeter_id>", ) + @validate_input("get", kwargs_state=[False, False, False]) @check_auth def get(self, uuid=None, perimeter_id=None, user_id=None): """Retrieve all actions or a specific one if perimeter_id @@ -338,57 +325,53 @@ class Actions(Resource): :return: { "action_id": { "name": "name of the action", - "description": "description of the action" + "description": "description of the action (optional)" } } :internal_api: get_actions """ - try: - data = PolicyManager.get_actions( - user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_actions( + user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) + return {"actions": data} + @validate_input("post", body_state={"name":True}) @check_auth - def post(self, uuid=None, perimeter_id=None, user_id=None): + def post(self, uuid, perimeter_id=None, user_id=None): """Create or update a action. :param uuid: uuid of the policy :param perimeter_id: must not be used here :param user_id: user ID who do the request :request body: { - "name": "name of the action", - "description": "description of the action" + "name": "name of the action (mandatory)", + "description": "description of the action (optional)" } :return: { "action_id": { "name": "name of the action", - "description": "description of the action" + "description": "description of the action (optional)" } } :internal_api: set_action """ - try: - data = PolicyManager.get_actions(user_id=user_id, policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_action( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid) + if 'name' in request.json: + for data_id, data_value in data.items(): + if data_value['name'] == request.json['name']: + perimeter_id = data_id + break + data = PolicyManager.add_action( + user_id=user_id, policy_id=uuid, + perimeter_id=perimeter_id, value=request.json) + return {"actions": data} + @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True}) @check_auth - def patch(self, uuid=None, perimeter_id=None, user_id=None): + def patch(self, uuid, perimeter_id=None, user_id=None): """Create or update a action. :param uuid: uuid of the policy @@ -396,52 +379,47 @@ class Actions(Resource): :param user_id: user ID who do the request :request body: { "name": "name of the action", - "description": "description of the action" + "description": "description of the action (optional)" } :return: { "action_id": { "name": "name of the action", - "description": "description of the action" + "description": "description of the action (optional)" } } :internal_api: set_action """ - try: - data = PolicyManager.get_actions(user_id=user_id, policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_action( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid) + if 'name' in request.json: + for data_id, data_value in data.items(): + if data_value['name'] == request.json['name']: + perimeter_id = data_id + break + data = PolicyManager.add_action( + user_id=user_id, policy_id=uuid, + perimeter_id=perimeter_id, value=request.json) + return {"actions": data} + @validate_input("delete", kwargs_state=[False, True, False]) @check_auth def delete(self, uuid=None, perimeter_id=None, user_id=None): """Delete a action for a given policy - :param uuid: uuid of the policy - :param perimeter_id: uuid of the action + :param uuid: uuid of the policy (mandatory if perimeter_id is not set) + :param perimeter_id: uuid of the action (mandatory if uuid is not set) :param user_id: user ID who do the request :return: { "action_id": { "name": "name of the action", - "description": "description of the action" + "description": "description of the action (optional)" } } :internal_api: delete_action """ - try: - data = PolicyManager.delete_action( - user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_action( + user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id) + return {"result": True} diff --git a/moon_manager/moon_manager/api/policies.py b/moon_manager/moon_manager/api/policies.py index 0d7a52a9..9fe237b2 100644 --- a/moon_manager/moon_manager/api/policies.py +++ b/moon_manager/moon_manager/api/policies.py @@ -12,6 +12,8 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager +from python_moonutilities.security_functions import validate_input + __version__ = "4.3.2" @@ -30,6 +32,7 @@ class Policies(Resource): "/policies/<string:uuid>/", ) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, uuid=None, user_id=None): """Retrieve all policies @@ -38,53 +41,49 @@ class Policies(Resource): :param user_id: user ID who do the request :return: { "policy_id1": { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", + "name": "name of the policy (mandatory)", + "model_id": "ID of the model linked to this policy", + "genre": "authz of admin (optional, default to authz)", + "description": "description of the policy (optional)", } } :internal_api: get_policies """ - try: - data = PolicyManager.get_policies(user_id=user_id, policy_id=uuid) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.get_policies(user_id=user_id, policy_id=uuid) + return {"policies": data} + @validate_input("post", body_state={"name": True, "model_id":True}) @check_auth def post(self, uuid=None, user_id=None): """Create policy. - :param uuid: uuid of the policy (not used here) + :param uuid: uuid of the policy (not used here if a new policy is created) :param user_id: user ID who do the request :request body: { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", + "name": "name of the policy (mandatory)", + "model_id": "ID of the model linked to this policy", + "genre": "authz of admin (optional, default to authz)", + "description": "description of the policy (optional)", } :return: { "policy_id1": { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", + "name": "name of the policy (mandatory)", + "model_id": "ID of the model linked to this policy", + "genre": "authz of admin (optional, default to authz)", + "description": "description of the policy (optional)", } } :internal_api: add_policy """ - try: - data = PolicyManager.add_policy( - user_id=user_id, policy_id=uuid, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.add_policy( + user_id=user_id, policy_id=uuid, value=request.json) + return {"policies": data} + @validate_input("delete", kwargs_state=[ True, False]) @check_auth def delete(self, uuid=None, user_id=None): """Delete a policy @@ -93,18 +92,16 @@ class Policies(Resource): :param user_id: user ID who do the request :return: { "result": "True or False", - "message": "optional message" + "message": "optional message (optional)" } :internal_api: delete_policy """ - try: - data = PolicyManager.delete_policy(user_id=user_id, policy_id=uuid) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_policy(user_id=user_id, policy_id=uuid) + return {"result": True} + @validate_input("patch", kwargs_state=[True, False], body_state={"name": True, "model_id":True}) @check_auth def patch(self, uuid=None, user_id=None): """Update a policy @@ -113,20 +110,17 @@ class Policies(Resource): :param user_id: user ID who do the request :return: { "policy_id1": { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", + "name": "name of the policy (mandatory)", + "model_id": "ID of the model linked to this policy", + "genre": "authz of admin (optional, default to authz)", + "description": "description of the policy (optional)", } } :internal_api: update_policy """ - try: - data = PolicyManager.update_policy( - user_id=user_id, policy_id=uuid, value=request.json) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.update_policy( + user_id=user_id, policy_id=uuid, value=request.json) + return {"policies": data} diff --git a/moon_manager/moon_manager/api/rules.py b/moon_manager/moon_manager/api/rules.py index e6c46bf4..a0248097 100644 --- a/moon_manager/moon_manager/api/rules.py +++ b/moon_manager/moon_manager/api/rules.py @@ -11,6 +11,7 @@ from flask_restful import Resource import logging from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager +from python_moonutilities.security_functions import validate_input __version__ = "4.3.2" @@ -28,6 +29,7 @@ class Rules(Resource): "/policies/<string:uuid>/rules/<string:rule_id>/", ) + @validate_input("get", kwargs_state=[False, False, False]) @check_auth def get(self, uuid=None, rule_id=None, user_id=None): """Retrieve all rules or a specific one @@ -40,34 +42,32 @@ class Rules(Resource): "policy_id": "policy_id1", "meta_rule_id": "meta_rule_id1", "rule_id1": - ["subject_data_id1", "object_data_id1", "action_data_id1"], + ["subject_data_id1", "subject_data_id2", "object_data_id1", "action_data_id1"], "rule_id2": - ["subject_data_id2", "object_data_id2", "action_data_id2"], + ["subject_data_id3", "subject_data_id4", "object_data_id2", "action_data_id2"], ] } :internal_api: get_rules """ - try: - data = PolicyManager.get_rules(user_id=user_id, + + data = PolicyManager.get_rules(user_id=user_id, policy_id=uuid, rule_id=rule_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + return {"rules": data} + @validate_input("post", kwargs_state=[True, False, False], body_state={"meta_rule_id": True, "rule": True, "instructions": True}) @check_auth def post(self, uuid=None, rule_id=None, user_id=None): """Add a rule to a meta rule :param uuid: policy ID - :param rule_id: rule ID + :param rule_id: rule ID (not used here) :param user_id: user ID who do the request :request body: post = { - "meta_rule_id": "meta_rule_id1", - "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"], - "instructions": ( + "meta_rule_id": "meta_rule_id1", # mandatory + "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"], # mandatory + "instructions": ( # mandatory {"decision": "grant"}, ) "enabled": True @@ -108,17 +108,15 @@ class Rules(Resource): :internal_api: add_rule """ args = request.json - try: - data = PolicyManager.add_rule(user_id=user_id, - policy_id=uuid, - meta_rule_id=args['meta_rule_id'], - value=args) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.add_rule(user_id=user_id, + policy_id=uuid, + meta_rule_id=args['meta_rule_id'], + value=args) + return {"rules": data} + @validate_input("delete", kwargs_state=[True, True, False]) @check_auth def delete(self, uuid=None, rule_id=None, user_id=None): """Delete one rule linked to a specific sub meta rule @@ -129,12 +127,9 @@ class Rules(Resource): :return: { "result": true } :internal_api: delete_rule """ - try: - data = PolicyManager.delete_rule( - user_id=user_id, policy_id=uuid, rule_id=rule_id) - except Exception as e: - logger.error(e, exc_info=True) - return {"result": False, - "error": str(e)}, 500 + + data = PolicyManager.delete_rule( + user_id=user_id, policy_id=uuid, rule_id=rule_id) + return {"result": True} diff --git a/moon_manager/moon_manager/api/slaves.py b/moon_manager/moon_manager/api/slaves.py index f5b3fa14..769b681f 100644 --- a/moon_manager/moon_manager/api/slaves.py +++ b/moon_manager/moon_manager/api/slaves.py @@ -11,12 +11,11 @@ from flask import request from flask_restful import Resource import logging import requests -import time from python_moonutilities.security_functions import check_auth -from python_moondb.core import PDPManager -from python_moondb.core import PolicyManager -from python_moondb.core import ModelManager -from python_moonutilities import configuration, exceptions + +from python_moonutilities import configuration +from python_moonutilities.security_functions import validate_input + __version__ = "4.3.0" @@ -42,6 +41,7 @@ class Slaves(Resource): self.orchestrator_port = conf["components/orchestrator"].get("port", 80) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, uuid=None, user_id=None): """Retrieve all slaves @@ -66,6 +66,8 @@ class Slaves(Resource): )) return {"slaves": req.json().get("slaves", dict())} + @validate_input("patch", kwargs_state=[False, False], + body_state={"op": True, "variable": True, "value": True}) @check_auth def patch(self, uuid=None, user_id=None): """Update a slave diff --git a/moon_manager/moon_manager/http_server.py b/moon_manager/moon_manager/http_server.py index a98cab43..204e7e04 100644 --- a/moon_manager/moon_manager/http_server.py +++ b/moon_manager/moon_manager/http_server.py @@ -2,9 +2,9 @@ # This software is distributed under the terms and conditions of the 'Apache-2.0' # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from flask import Flask, jsonify +from flask import Flask, jsonify, Response, make_response from flask_cors import CORS, cross_origin +from json import dumps from flask_restful import Resource, Api import logging import sqlalchemy.exc @@ -21,7 +21,9 @@ from moon_manager.api.perimeter import Subjects, Objects, Actions from moon_manager.api.data import SubjectData, ObjectData, ActionData from moon_manager.api.assignments import SubjectAssignments, ObjectAssignments, ActionAssignments from moon_manager.api.rules import Rules -from python_moonutilities import configuration, exceptions +from moon_manager.api.json_import import JsonImport +from moon_manager.api.json_export import JsonExport +from python_moonutilities import configuration from python_moondb.core import PDPManager @@ -33,7 +35,7 @@ __API__ = ( Subjects, Objects, Actions, Rules, SubjectAssignments, ObjectAssignments, ActionAssignments, SubjectData, ObjectData, ActionData, - Models, Policies, PDP, Slaves + Models, Policies, PDP, Slaves, JsonImport, JsonExport ) @@ -98,38 +100,41 @@ class Root(Resource): if _method in dir(item): _methods.append(_method) tree[item.__name__]["methods"] = _methods - tree[item.__name__]["description"] = item.__doc__.strip() + tree[item.__name__]["description"] = item.__doc__.strip() if item.__doc__ else "" return { "version": __version__, "tree": tree } +class CustomApi(Api): + + @staticmethod + def handle_error(e): + try: + error_message = dumps({"result": False, 'message': str(e), "code": getattr(e, "code", 500)}) + logger.error(e, exc_info=True) + logger.error(error_message) + return make_response(error_message, getattr(e, "code", 500)) + except Exception as e2: # unhandled exception in the api... + logger.exception(str(e2)) + return make_response(error_message, 500) + + class HTTPServer(Server): def __init__(self, host="localhost", port=80, **kwargs): super(HTTPServer, self).__init__(host=host, port=port, **kwargs) self.app = Flask(__name__) + self.app.config['TRAP_HTTP_EXCEPTIONS'] = True conf = configuration.get_configuration("components/manager") self.manager_hostname = conf["components/manager"].get("hostname", "manager") self.manager_port = conf["components/manager"].get("port", 80) # TODO : specify only few urls instead of * CORS(self.app) - self.api = Api(self.app) + self.api = CustomApi(self.app, catch_all_404s=True) self.__set_route() - self.__hook_errors() - - def __hook_errors(self): - - def get_404_json(e): - return jsonify({"result": False, "code": 404, "description": str(e)}), 404 - self.app.register_error_handler(404, get_404_json) - - def get_400_json(e): - return jsonify({"result": False, "code": 400, "description": str(e)}), 400 - self.app.register_error_handler(400, lambda e: get_400_json) - self.app.register_error_handler(403, exceptions.AuthException) def __set_route(self): self.api.add_resource(Root, '/') @@ -143,7 +148,7 @@ class HTTPServer(Server): while True: try: PDPManager.get_pdp(user_id="admin", pdp_id=None) - except sqlalchemy.exc.ProgrammingError: + except (sqlalchemy.exc.ProgrammingError, sqlalchemy.exc.InternalError): time.sleep(1) if first: logger.warning("Waiting for the database...") @@ -154,4 +159,4 @@ class HTTPServer(Server): def run(self): self.__check_if_db_is_up() - self.app.run(debug=True, host=self._host, port=self._port) # nosec + self.app.run(host=self._host, port=self._port, threaded=True) # nosec diff --git a/moon_manager/moon_manager/server.py b/moon_manager/moon_manager/server.py index 70ddaee0..a8db8fd5 100644 --- a/moon_manager/moon_manager/server.py +++ b/moon_manager/moon_manager/server.py @@ -7,6 +7,7 @@ import logging from python_moonutilities import configuration, exceptions from moon_manager.http_server import HTTPServer + logger = logging.getLogger("moon.manager.server") diff --git a/moon_manager/tests/functional_pod/json/mls.json b/moon_manager/tests/functional_pod/json/mls.json new file mode 100644 index 00000000..01ef6deb --- /dev/null +++ b/moon_manager/tests/functional_pod/json/mls.json @@ -0,0 +1,89 @@ +{ + "pdps": [{"name" : "pdp_mls", "keystone_project_id" : "", "description": "", "policies": [{"name": "MLS policy example"}]}], + + "policies":[{ "name": "MLS policy example", "genre": "authz", "description": "", "model": {"name": "MLS"} , "mandatory" :false , "override":true}], + + "models":[{"name":"MLS", "description":"","meta_rules": [{"name" : "mls"}], "override":true}], + + + + + + "subjects": [{ "name":"adminuser", "description": "", "extra": {}, "policies": [{ "name": "MLS policy example"}]} , + { "name": "user1", "description": "", "extra": {}, "policies": [{ "name": "MLS policy example"}] }, + { "name": "user2", "description": "", "extra": {}, "policies": [{ "name": "MLS policy example"}] }], + + "subject_categories": [{ "name":"subject-security-level", "description": "" }], + + "subject_data": [{ "name":"low", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "subject-security-level"}}, + { "name":"medium", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "subject-security-level"}}, + { "name":"high", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "subject-security-level"}}], + + "subject_assignments":[{ "subject" : {"name": "adminuser"}, "category" : {"name": "subject-security-level"}, "assignments": [{"name" : "high"}]}, + { "subject" : {"name": "user1"}, "category" : {"name": "subject-security-level"}, "assignments": [{"name" : "medium"}] }], + + + + + + + "objects": [{ "name":"vm0", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]} , + {"name": "vm1", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]} ], + + "object_categories": [{"name":"object-security-level", "description": ""}], + + "object_data": [{ "name":"low", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "object-security-level"}}, + { "name":"medium", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "object-security-level"}}, + { "name":"high", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "object-security-level"}}], + + "object_assignments":[{ "object" : {"name": "vm0"}, "category" : {"name": "object-security-level"}, "assignments": [{"name" : "medium"}]}, + { "object" : {"name": "vm1"}, "category" : {"name": "object-security-level"}, "assignments": [{"name" : "low"}]}], + + + + + + + "actions": [{ "name": "start", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]} , + { "name": "stop", "description": "", "extra": {}, "policies": [{"name": "MLS policy example"}]}], + + "action_categories": [{"name":"action-type", "description": ""}], + + "action_data": [{"name":"vm-action", "description": "", "policies": [{"name": "MLS policy example"}], "category": {"name": "action-type"}}, + {"name":"storage-action", "description": "", "policies": [{"name" :"MLS policy example"}], "category": {"name": "action-type"}}], + + "action_assignments":[{ "action" : {"name": "start"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}]}, + { "action" : {"name": "stop"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}]}], + + + + + + + "meta_rules":[{"name":"mls", "description": "", + "subject_categories": [{"name": "subject-security-level"}], + "object_categories": [{"name": "object-security-level"}], + "action_categories": [{"name": "action-type"}] + }], + + "rules": [{ + "meta_rule": {"name" : "mls"}, + "rule": {"subject_data" : [{"name":"high"}], "object_data": [{"name": "medium"}], "action_data": [{"name": "vm-action"}]}, + "policy": {"name" :"MLS policy example"}, + "instructions" : {"decision" : "grant"} + }, { + "meta_rule": {"name" : "mls"}, + "rule": {"subject_data" : [{"name":"high"}], "object_data": [{"name": "low"}], "action_data": [{"name": "vm-action"}]}, + "policy": {"name" :"MLS policy example"}, + "instructions" : {"decision" : "grant"} + }, { + "meta_rule": {"name" : "mls"}, + "rule": {"subject_data" : [{"name":"medium"}], "object_data": [{"name": "low"}], "action_data": [{"name": "vm-action"}]}, + "policy": {"name" :"MLS policy example"}, + "instructions" : {"decision" : "grant"} + }] + + + + +}
\ No newline at end of file diff --git a/moon_manager/tests/functional_pod/json/rbac.json b/moon_manager/tests/functional_pod/json/rbac.json new file mode 100644 index 00000000..a75f291b --- /dev/null +++ b/moon_manager/tests/functional_pod/json/rbac.json @@ -0,0 +1,85 @@ +{ + "pdps": [{"name" : "pdp_rbac", "keystone_project_id" : "", "description": "", "policies": [{"name": "RBAC policy example"}]}], + + "policies":[{ "name": "RBAC policy example", "genre": "authz", "description": "", "model": {"name": "RBAC"} , "mandatory" :true , "override":true}], + + "models":[{"name":"RBAC", "description":"","meta_rules": [{"name" : "rbac"}], "override":true}], + + + + + + "subjects": [{ "name":"adminuser", "description": "", "extra": {}, "policies": [{ "name": "RBAC policy example"}]} , + { "name": "user1", "description": "", "extra": {}, "policies": [{ "name": "RBAC policy example"}] }, + { "name": "public", "description": "", "extra": {}, "policies": [] }], + + "subject_categories": [{ "name":"role", "description": "" }], + + "subject_data": [{ "name":"admin", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "role"}}, + { "name":"employee", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "role"}}, + { "name":"*", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "role"}}], + + "subject_assignments":[{ "subject" : {"name": "adminuser"}, "category" : {"name": "role"}, "assignments": [{"name" : "admin"}, {"name" : "employee"}, {"name" : "*"}]}, + { "subject" : {"name": "user1"}, "category" : {"name": "role"}, "assignments": [{"name" : "employee"}, {"name" : "*"}] }], + + + + + + + "objects": [{ "name":"vm0", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]} , + {"name": "vm1", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]} ], + + "object_categories": [{"name":"id", "description": ""}], + + "object_data": [{ "name":"vm0", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "id"}}, + { "name":"vm1", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "id"}}, + { "name":"*", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "id"}}], + + "object_assignments":[{ "object" : {"name": "vm0"}, "category" : {"name": "id"}, "assignments": [{"name" : "vm0"}, {"name" : "*"}]}, + { "object" : {"name": "vm1"}, "category" : {"name": "id"}, "assignments": [{"name" : "vm1"}, {"name" : "*"}]}], + + + + + + + "actions": [{ "name": "start", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]} , + { "name": "stop", "description": "", "extra": {}, "policies": [{"name": "RBAC policy example"}]}], + + "action_categories": [{"name":"action-type", "description": ""}], + + "action_data": [{"name":"vm-action", "description": "", "policies": [{"name": "RBAC policy example"}], "category": {"name": "action-type"}}, + {"name":"*", "description": "", "policies": [{"name" :"RBAC policy example"}], "category": {"name": "action-type"}}], + + "action_assignments":[{ "action" : {"name": "start"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}, {"name" : "*"}]}, + { "action" : {"name": "stop"}, "category" : {"name": "action-type"}, "assignments": [{"name" : "vm-action"}, {"name" : "*"}]}], + + + + + + + "meta_rules":[{"name":"rbac", "description": "", + "subject_categories": [{"name": "role"}], + "object_categories": [{"name": "id"}], + "action_categories": [{"name": "action-type"}] + }], + + "rules": [{ + "meta_rule": {"name" : "rbac"}, + "rule": {"subject_data" : [{"name":"admin"}], "object_data": [{"name": "vm0"}], "action_data": [{"name": "vm-action"}]}, + "policy": {"name" :"RBAC policy example"}, + "instructions" : {"decision" : "grant"}, + "enabled": true + }, { + "meta_rule": {"name" : "rbac"}, + "rule": {"subject_data" : [{"name":"employee"}], "object_data": [{"name": "vm1"}], "action_data": [{"name": "vm-action"}]}, + "policy": {"name" :"RBAC policy example"}, + "instructions" : {"decision" : "grant"} + }] + + + + +}
\ No newline at end of file diff --git a/moon_manager/tests/functional_pod/run_functional_tests.sh b/moon_manager/tests/functional_pod/run_functional_tests.sh index 7a95a491..960e9480 100644 --- a/moon_manager/tests/functional_pod/run_functional_tests.sh +++ b/moon_manager/tests/functional_pod/run_functional_tests.sh @@ -1,4 +1,11 @@ #!/usr/bin/env bash +if [ -d /data/dist ]; +then + pip install /data/dist/*.tar.gz --upgrade + pip install /data/dist/*.whl --upgrade +fi + + cd /data/tests/functional_pod pytest . diff --git a/moon_manager/tests/functional_pod/test_manager.py b/moon_manager/tests/functional_pod/test_manager.py index aab5fba4..454d861b 100644 --- a/moon_manager/tests/functional_pod/test_manager.py +++ b/moon_manager/tests/functional_pod/test_manager.py @@ -1,6 +1,45 @@ import json import requests +def test_import_rbac(context): + files = {'file': open('/data/tests/functional_pod/json/rbac.json', 'r')} + req = requests.post("http://{}:{}/import".format( + context.get("hostname"), + context.get("port")) + , files=files) + print(req) + result = req.json() + print(result) + req.raise_for_status() + +def test_import_mls(context): + files = {'file': open('/data/tests/functional_pod/json/mls.json', 'r')} + req = requests.post("http://{}:{}/import".format( + context.get("hostname"), + context.get("port")) + , files=files) + req.raise_for_status() + + +def test_export_rbac(context): + test_import_rbac(context) + req = requests.get("http://{}:{}/export".format( + context.get("hostname"), + context.get("port")), + data={"filename":"/data/tests/functional_pod/json/rbac_export.json"} + ) + req.raise_for_status() + + +def test_export_mls(context): + test_import_mls(context) + req = requests.get("http://{}:{}/export".format( + context.get("hostname"), + context.get("port")), + data={"filename":"/data/tests/functional_pod/json/mls_export.json"} + ) + req.raise_for_status() + def get_json(data): return json.loads(data.decode("utf-8")) diff --git a/moon_manager/tests/functional_pod/test_models.py b/moon_manager/tests/functional_pod/test_models.py index dcda9f32..8b4ceef5 100644 --- a/moon_manager/tests/functional_pod/test_models.py +++ b/moon_manager/tests/functional_pod/test_models.py @@ -32,9 +32,10 @@ def delete_models(context, name): request = None for key, value in models['models'].items(): if value['name'] == name: - request = requests.delete("http://{}:{}/models/{}".format(key, + request = requests.delete("http://{}:{}/models/{}".format( context.get("hostname"), - context.get("port")), + context.get("port"), + key), timeout=3) break return request diff --git a/moon_manager/tests/unit_python/api/import_export_utilities.py b/moon_manager/tests/unit_python/api/import_export_utilities.py new file mode 100644 index 00000000..12cb208e --- /dev/null +++ b/moon_manager/tests/unit_python/api/import_export_utilities.py @@ -0,0 +1,196 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import api.test_unit_models as test_models +import api.test_policies as test_policies +import api.test_perimeter as test_perimeter +import api.test_meta_data as test_categories +import api.test_data as test_data +import api.test_meta_rules as test_meta_rules +import api.test_assignemnt as test_assignments +import api.test_rules as test_rules +import logging + +logger = logging.getLogger("moon.manager.test.api." + __name__) + + +def clean_models(client): + req, models = test_models.get_models(client) + for key in models["models"]: + client.delete("/models/{}".format(key)) + + +def clean_policies(client): + req, policies = test_policies.get_policies(client) + for key in policies["policies"]: + req = client.delete("/policies/{}".format(key)) + assert req.status_code == 200 + + +def clean_subjects(client): + subjects = test_perimeter.get_subjects(client) + logger.info("subjects {}".format(subjects)) + for key in subjects[1]["subjects"]: + subject = subjects[1]["subjects"][key] + policy_keys = subject["policy_list"] + logger.info("subjects policy_keys {}".format(policy_keys)) + for policy_key in policy_keys: + client.delete("/policies/{}/subjects/{}".format(policy_key, key)) + client.delete("/subjects/{}".format(key)) + + +def clean_objects(client): + objects = test_perimeter.get_objects(client) + logger.info("objects {}".format(objects)) + for key in objects[1]["objects"]: + object_ = objects[1]["objects"][key] + policy_keys = object_["policy_list"] + logger.info("objects policy_keys {}".format(policy_keys)) + for policy_key in policy_keys: + client.delete("/policies/{}/objects/{}".format(policy_key, key)) + client.delete("/objects/{}".format(key)) + + +def clean_actions(client): + actions = test_perimeter.get_actions(client) + logger.info("actions {}".format(actions)) + for key in actions[1]["actions"]: + action = actions[1]["actions"][key] + policy_keys = action["policy_list"] + logger.info("action policy_keys {}".format(policy_keys)) + for policy_key in policy_keys: + client.delete("/policies/{}/actions/{}".format(policy_key, key)) + client.delete("/actions/{}".format(key)) + + +def clean_subject_categories(client): + req, categories = test_categories.get_subject_categories(client) + logger.info(categories) + for key in categories["subject_categories"]: + client.delete("/subject_categories/{}".format(key)) + + +def clean_object_categories(client): + req, categories = test_categories.get_object_categories(client) + logger.info(categories) + for key in categories["object_categories"]: + client.delete("/object_categories/{}".format(key)) + + +def clean_action_categories(client): + req, categories = test_categories.get_action_categories(client) + logger.info(categories) + for key in categories["action_categories"]: + client.delete("/action_categories/{}".format(key)) + + +def clean_subject_data(client): + req, policies = test_policies.get_policies(client) + logger.info("clean_subject_data on {}".format(policies)) + for policy_key in policies["policies"]: + req, data = test_data.get_subject_data(client, policy_id=policy_key) + logger.info("============= data {}".format(data)) + for key in data["subject_data"]: + logger.info("============= Deleting {}/{}".format(policy_key, key)) + client.delete("/policies/{}/subject_data/{}".format(policy_key, key)) + + +def clean_object_data(client): + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, data = test_data.get_object_data(client, policy_id=policy_key) + for key in data["object_data"]: + client.delete("/policies/{}/object_data/{}".format(policy_key, key)) + + +def clean_action_data(client): + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, data = test_data.get_action_data(client, policy_id=policy_key) + for key in data["action_data"]: + client.delete("/policies/{}/action_data/{}".format(policy_key, key)) + + +def clean_meta_rule(client): + req, meta_rules = test_meta_rules.get_meta_rules(client) + meta_rules = meta_rules["meta_rules"] + for meta_rule_key in meta_rules: + logger.info("clean_meta_rule.meta_rule_key={}".format(meta_rule_key)) + logger.info("clean_meta_rule.meta_rule={}".format(meta_rules[meta_rule_key])) + client.delete("/meta_rules/{}".format(meta_rule_key)) + + +def clean_subject_assignments(client): + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, assignments = test_assignments.get_subject_assignment(client, policy_key) + for key in assignments["subject_assignments"]: + subject_key = assignments["subject_assignments"][key]["subject_id"] + cat_key = assignments["subject_assignments"][key]["category_id"] + data_keys = assignments["subject_assignments"][key]["assignments"] + for data_key in data_keys: + client.delete("/policies/{}/subject_assignments/{}/{}/{}".format(policy_key, subject_key, + cat_key, data_key)) + + +def clean_object_assignments(client): + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, assignments = test_assignments.get_object_assignment(client, policy_key) + for key in assignments["object_assignments"]: + object_key = assignments["object_assignments"][key]["object_id"] + cat_key = assignments["object_assignments"][key]["category_id"] + data_keys = assignments["object_assignments"][key]["assignments"] + for data_key in data_keys: + client.delete("/policies/{}/object_assignments/{}/{}/{}".format(policy_key, object_key, + cat_key, data_key)) + + +def clean_action_assignments(client): + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, assignments = test_assignments.get_action_assignment(client, policy_key) + for key in assignments["action_assignments"]: + action_key = assignments["action_assignments"][key]["action_id"] + cat_key = assignments["action_assignments"][key]["category_id"] + data_keys = assignments["action_assignments"][key]["assignments"] + for data_key in data_keys: + client.delete("/policies/{}/action_assignments/{}/{}/{}".format(policy_key, action_key, + cat_key, data_key)) + + +def clean_rules(client): + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, rules = test_rules.get_rules(client, policy_key) + rules = rules["rules"] + rules = rules["rules"] + for rule_key in rules: + client.delete("/policies/{}/rules/{}".format(policy_key, rule_key)) + + +def clean_all(client): + clean_rules(client) + + clean_subject_assignments(client) + clean_object_assignments(client) + clean_action_assignments(client) + + clean_meta_rule(client) + + clean_subject_data(client) + clean_object_data(client) + clean_action_data(client) + + clean_actions(client) + clean_objects(client) + clean_subjects(client) + + clean_subject_categories(client) + clean_object_categories(client) + clean_action_categories(client) + + clean_policies(client) + clean_models(client) diff --git a/moon_manager/tests/unit_python/api/meta_data_test.py b/moon_manager/tests/unit_python/api/meta_data_test.py index 8fb39ae1..8609f0b5 100644 --- a/moon_manager/tests/unit_python/api/meta_data_test.py +++ b/moon_manager/tests/unit_python/api/meta_data_test.py @@ -54,6 +54,20 @@ def test_add_subject_categories(): assert value['description'] == "description of {}".format("testuser") +def test_add_subject_categories_with_empty_user(): + client = utilities.register_client() + req, subject_categories = add_subject_categories(client, "") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "Empty String" + + +def test_add_subject_categories_with_user_contain_space(): + client = utilities.register_client() + req, subject_categories = add_subject_categories(client, "test user") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "String contains space" + + def test_delete_subject_categories(): client = utilities.register_client() req = delete_subject_categories(client, "testuser") @@ -119,6 +133,20 @@ def test_add_object_categories(): assert value['description'] == "description of {}".format("testuser") +def test_add_object_categories_with_empty_user(): + client = utilities.register_client() + req, object_categories = add_object_categories(client, "") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "Empty String" + + +def test_add_object_categories_with_user_contain_space(): + client = utilities.register_client() + req, object_categories = add_object_categories(client, "test user") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "String contains space" + + def test_delete_object_categories(): client = utilities.register_client() req = delete_object_categories(client, "testuser") @@ -184,6 +212,20 @@ def test_add_action_categories(): assert value['description'] == "description of {}".format("testuser") +def test_add_action_categories_with_empty_user(): + client = utilities.register_client() + req, action_categories = add_action_categories(client, "") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "Empty String" + + +def test_add_action_categories_with_user_contain_space(): + client = utilities.register_client() + req, action_categories = add_action_categories(client, "test user") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "String contains space" + + def test_delete_action_categories(): client = utilities.register_client() req = delete_action_categories(client, "testuser") @@ -193,4 +235,4 @@ def test_delete_action_categories(): def test_delete_action_categories_without_id(): client = utilities.register_client() req = delete_action_categories_without_id(client) - assert req.status_code == 500
\ No newline at end of file + assert req.status_code == 500 diff --git a/moon_manager/tests/unit_python/api/meta_rules_test.py b/moon_manager/tests/unit_python/api/meta_rules_test.py index b5b1ecf8..a87c16f3 100644 --- a/moon_manager/tests/unit_python/api/meta_rules_test.py +++ b/moon_manager/tests/unit_python/api/meta_rules_test.py @@ -22,6 +22,46 @@ def add_meta_rules(client, name): return req, meta_rules +def add_meta_rules_without_subject_category_ids(client, name): + data = { + "name": name, + "subject_categories": [], + "object_categories": ["object_category_id1"], + "action_categories": ["action_category_id1"] + } + req = client.post("/meta_rules", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def update_meta_rules(client, name, metaRuleId): + data = { + "name": name, + "subject_categories": ["subject_category_id1_update", + "subject_category_id2_update"], + "object_categories": ["object_category_id1_update"], + "action_categories": ["action_category_id1_update"] + } + req = client.patch("/meta_rules/{}".format(metaRuleId), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def update_meta_rules_without_subject_category_ids(client, name): + data = { + "name": name, + "subject_categories": [], + "object_categories": ["object_category_id1"], + "action_categories": ["action_category_id1"] + } + req = client.post("/meta_rules", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + def delete_meta_rules(client, name): request, meta_rules = get_meta_rules(client) for key, value in meta_rules['meta_rules'].items(): @@ -57,6 +97,27 @@ def test_add_meta_rules(): assert value["action_categories"][0] == "action_category_id1" +def test_add_meta_rules_with_empty_user(): + client = utilities.register_client() + req, meta_rules = add_meta_rules(client, "") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "Empty String" + + +def test_add_meta_rules_with_user_contain_space(): + client = utilities.register_client() + req, meta_rules = add_meta_rules(client, "test user") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == "String contains space" + + +def test_add_meta_rules_without_subject_categories(): + client = utilities.register_client() + req, meta_rules = add_meta_rules_without_subject_category_ids(client, "testuser") + assert req.status_code == 500 + assert json.loads(req.data)["message"] == 'Empty Container' + + def test_delete_meta_rules(): client = utilities.register_client() req = delete_meta_rules(client, "testuser") @@ -67,3 +128,35 @@ def test_delete_meta_rules_without_id(): client = utilities.register_client() req = delete_meta_rules_without_id(client) assert req.status_code == 500 + + +def test_update_meta_rules(): + client = utilities.register_client() + req = add_meta_rules(client, "testuser") + meta_rule_id = list(req[1]['meta_rules'])[0] + req_update = update_meta_rules(client, "testuser", meta_rule_id) + assert req_update[0].status_code == 200 + value = list(req_update[1]["meta_rules"].values())[0] + assert value["subject_categories"][0] == "subject_category_id1_update" + delete_meta_rules(client, "testuser") + get_meta_rules(client) + + +def test_update_meta_rules_without_id(): + client = utilities.register_client() + req_update = update_meta_rules(client, "testuser", "") + assert req_update[0].status_code == 500 + + +def test_update_meta_rules_without_user(): + client = utilities.register_client() + req_update = update_meta_rules(client, "", "") + assert req_update[0].status_code == 500 + assert json.loads(req_update[0].data)["message"] == "Empty String" + + +def test_update_meta_rules_without_subject_categories(): + client = utilities.register_client() + req_update = update_meta_rules_without_subject_category_ids(client, "testuser") + assert req_update[0].status_code == 500 + assert json.loads(req_update[0].data)["message"] == "Empty Container" diff --git a/moon_manager/tests/unit_python/api/test_assignemnt.py b/moon_manager/tests/unit_python/api/test_assignemnt.py index 08688e04..22c727af 100644 --- a/moon_manager/tests/unit_python/api/test_assignemnt.py +++ b/moon_manager/tests/unit_python/api/test_assignemnt.py @@ -1,5 +1,7 @@ import api.utilities as utilities import json +from helpers import data_builder as builder +from uuid import uuid4 # subject_categories_test @@ -11,52 +13,84 @@ def get_subject_assignment(client, policy_id): return req, subject_assignment -def add_subject_assignment(client, policy_id, category_id): +def add_subject_assignment(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + subject_id = builder.create_subject(policy_id) + data_id = builder.create_subject_data(policy_id=policy_id, category_id=subject_category_id) + + data = { + "id": subject_id, + "category_id": subject_category_id, + "data_id": data_id + } + req = client.post("/policies/{}/subject_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subject_assignment = utilities.get_json(req.data) + return req, subject_assignment + + +def add_subject_assignment_without_cat_id(client): + data = { - "id": "id1", - "category_id": category_id, - "data_id": "data_id1" + "id": "subject_id", + "category_id": "", + "data_id": "data_id" } - req = client.post("/policies/{}/subject_assignments/{}".format(policy_id, category_id), data=json.dumps(data), + req = client.post("/policies/{}/subject_assignments".format("1111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) subject_assignment = utilities.get_json(req.data) return req, subject_assignment -def delete_subject_assignment(client, policy_id): - req = client.delete("/policies/{}/subject_assignments".format(policy_id)) +def delete_subject_assignment(client, policy_id, sub_id, cat_id,data_id): + req = client.delete("/policies/{}/subject_assignments/{}/{}/{}".format(policy_id, sub_id, cat_id,data_id)) return req -def test_get_subject_assignment(): - policy_id = utilities.get_policy_id() +def test_add_subject_assignment(): client = utilities.register_client() - req, subject_assignment = get_subject_assignment(client, policy_id) + req, subject_assignment = add_subject_assignment(client) assert req.status_code == 200 assert isinstance(subject_assignment, dict) assert "subject_assignments" in subject_assignment -def test_add_subject_assignment(): - policy_id = utilities.get_policy_id() +def test_add_subject_assignment_without_cat_id(): client = utilities.register_client() - req, subject_assignment = add_subject_assignment(client, policy_id, "111") + req, subject_assignment = add_subject_assignment_without_cat_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]" + + +def test_get_subject_assignment(): + client = utilities.register_client() + policy_id = builder.get_policy_id_with_subject_assignment() + req, subject_assignment = get_subject_assignment(client, policy_id) assert req.status_code == 200 assert isinstance(subject_assignment, dict) - value = subject_assignment["subject_assignments"] assert "subject_assignments" in subject_assignment - id = list(value.keys())[0] - assert value[id]['policy_id'] == policy_id - assert value[id]['category_id'] == "111" - assert value[id]['subject_id'] == "id1" def test_delete_subject_assignment(): client = utilities.register_client() - policy_id = utilities.get_policy_id() - success_req = delete_subject_assignment(client, policy_id) + policy_id = builder.get_policy_id_with_subject_assignment() + req, subject_assignment = get_subject_assignment(client, policy_id) + value = subject_assignment["subject_assignments"] + id = list(value.keys())[0] + success_req = delete_subject_assignment(client, policy_id, value[id]['subject_id'], value[id]['category_id'],value[id]['assignments'][0]) assert success_req.status_code == 200 + +def test_delete_subject_assignment_without_policy_id(): + client = utilities.register_client() + success_req = delete_subject_assignment(client, "", "id1", "111" ,"data_id1") + assert success_req.status_code == 404 + + # --------------------------------------------------------------------------- # object_categories_test @@ -68,25 +102,47 @@ def get_object_assignment(client, policy_id): return req, object_assignment -def add_object_assignment(client, policy_id, category_id): +def add_object_assignment(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + object_id = builder.create_object(policy_id) + data_id = builder.create_object_data(policy_id=policy_id, category_id=object_category_id) + + data = { + "id": object_id, + "category_id": object_category_id, + "data_id": data_id + } + + req = client.post("/policies/{}/object_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + object_assignment = utilities.get_json(req.data) + return req, object_assignment + + +def add_object_assignment_without_cat_id(client): + data = { - "id": "id1", - "category_id": category_id, - "data_id": "data_id1" + "id": "object_id", + "category_id": "", + "data_id": "data_id" } - req = client.post("/policies/{}/object_assignments/{}".format(policy_id, category_id), data=json.dumps(data), + req = client.post("/policies/{}/object_assignments".format("1111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) object_assignment = utilities.get_json(req.data) return req, object_assignment -def delete_object_assignment(client, policy_id): - req = client.delete("/policies/{}/object_assignments".format(policy_id)) +def delete_object_assignment(client, policy_id, obj_id, cat_id, data_id): + req = client.delete("/policies/{}/object_assignments/{}/{}/{}".format(policy_id, obj_id, cat_id, data_id)) return req def test_get_object_assignment(): - policy_id = utilities.get_policy_id() + policy_id = builder.get_policy_id_with_object_assignment() client = utilities.register_client() req, object_assignment = get_object_assignment(client, policy_id) assert req.status_code == 200 @@ -95,25 +151,35 @@ def test_get_object_assignment(): def test_add_object_assignment(): - policy_id = utilities.get_policy_id() client = utilities.register_client() - req, object_assignment = add_object_assignment(client, policy_id, "111") + req, object_assignment = add_object_assignment(client) assert req.status_code == 200 - assert isinstance(object_assignment, dict) - value = object_assignment["object_assignments"] assert "object_assignments" in object_assignment - id = list(value.keys())[0] - assert value[id]['policy_id'] == policy_id - assert value[id]['category_id'] == "111" - assert value[id]['object_id'] == "id1" + + +def test_add_object_assignment_without_cat_id(): + client = utilities.register_client() + req, object_assignment = add_object_assignment_without_cat_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]" def test_delete_object_assignment(): client = utilities.register_client() - policy_id = utilities.get_policy_id() - success_req = delete_object_assignment(client, policy_id) + policy_id = builder.get_policy_id_with_object_assignment() + req, object_assignment = get_object_assignment(client, policy_id) + value = object_assignment["object_assignments"] + id = list(value.keys())[0] + success_req = delete_object_assignment(client, policy_id, value[id]['object_id'], value[id]['category_id'],value[id]['assignments'][0]) assert success_req.status_code == 200 + +def test_delete_object_assignment_without_policy_id(): + client = utilities.register_client() + success_req = delete_object_assignment(client, "", "id1", "111","data_id1") + assert success_req.status_code == 404 + + # --------------------------------------------------------------------------- # action_categories_test @@ -125,25 +191,46 @@ def get_action_assignment(client, policy_id): return req, action_assignment -def add_action_assignment(client, policy_id, category_id): +def add_action_assignment(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + action_id = builder.create_action(policy_id) + data_id = builder.create_action_data(policy_id=policy_id, category_id=action_category_id) + + data = { + "id": action_id, + "category_id": action_category_id, + "data_id": data_id + } + req = client.post("/policies/{}/action_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + action_assignment = utilities.get_json(req.data) + return req, action_assignment + + +def add_action_assignment_without_cat_id(client): + data = { - "id": "id1", - "category_id": category_id, - "data_id": "data_id1" + "id": "action_id", + "category_id": "", + "data_id": "data_id" } - req = client.post("/policies/{}/action_assignments/{}".format(policy_id, category_id), data=json.dumps(data), + req = client.post("/policies/{}/action_assignments".format("1111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) action_assignment = utilities.get_json(req.data) return req, action_assignment -def delete_action_assignment(client, policy_id): - req = client.delete("/policies/{}/action_assignments".format(policy_id)) +def delete_action_assignment(client, policy_id, action_id, cat_id, data_id): + req = client.delete("/policies/{}/action_assignments/{}/{}/{}".format(policy_id, action_id, cat_id, data_id)) return req def test_get_action_assignment(): - policy_id = utilities.get_policy_id() + policy_id = builder.get_policy_id_with_action_assignment() client = utilities.register_client() req, action_assignment = get_action_assignment(client, policy_id) assert req.status_code == 200 @@ -152,23 +239,32 @@ def test_get_action_assignment(): def test_add_action_assignment(): - policy_id = utilities.get_policy_id() client = utilities.register_client() - req, action_assignment = add_action_assignment(client, policy_id, "111") + req, action_assignment = add_action_assignment(client) assert req.status_code == 200 - assert isinstance(action_assignment, dict) - value = action_assignment["action_assignments"] assert "action_assignments" in action_assignment - id = list(value.keys())[0] - assert value[id]['policy_id'] == policy_id - assert value[id]['category_id'] == "111" - assert value[id]['action_id'] == "id1" + + +def test_add_action_assignment_without_cat_id(): + client = utilities.register_client() + req, action_assignment = add_action_assignment_without_cat_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]" def test_delete_action_assignment(): client = utilities.register_client() - policy_id = utilities.get_policy_id() - success_req = delete_action_assignment(client, policy_id) + policy_id = builder.get_policy_id_with_action_assignment() + req, action_assignment = get_action_assignment(client, policy_id) + value = action_assignment["action_assignments"] + id = list(value.keys())[0] + success_req = delete_action_assignment(client, policy_id, value[id]['action_id'], value[id]['category_id'],value[id]['assignments'][0]) assert success_req.status_code == 200 -# ---------------------------------------------------------------------------
\ No newline at end of file + +def test_delete_action_assignment_without_policy_id(): + client = utilities.register_client() + success_req = delete_action_assignment(client, "", "id1", "111" ,"data_id1") + assert success_req.status_code == 404 + +# --------------------------------------------------------------------------- diff --git a/moon_manager/tests/unit_python/api/test_data.py b/moon_manager/tests/unit_python/api/test_data.py index 87a80c69..ff0856af 100644 --- a/moon_manager/tests/unit_python/api/test_data.py +++ b/moon_manager/tests/unit_python/api/test_data.py @@ -1,22 +1,36 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + import api.utilities as utilities import json - +from helpers import data_builder as builder +from uuid import uuid4 # subject_categories_test -def get_subject_data(client, policy_id): - req = client.get("/policies/{}/subject_data".format(policy_id)) +def get_subject_data(client, policy_id, category_id=None): + if category_id is None: + req = client.get("/policies/{}/subject_data".format(policy_id)) + else: + req = client.get("/policies/{}/subject_data/{}".format(policy_id, category_id)) subject_data = utilities.get_json(req.data) return req, subject_data -def add_subject_data(client, name, policy_id, category_id): +def add_subject_data(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) data = { "name": name, "description": "description of {}".format(name) } - req = client.post("/policies/{}/subject_data/{}".format(policy_id, category_id), data=json.dumps(data), + req = client.post("/policies/{}/subject_data/{}".format(policy_id, subject_category_id), data=json.dumps(data), headers={'Content-Type': 'application/json'}) subject_data = utilities.get_json(req.data) return req, subject_data @@ -37,9 +51,8 @@ def test_get_subject_data(): def test_add_subject_data(): - policy_id = utilities.get_policy_id() client = utilities.register_client() - req, subject_data = add_subject_data(client, "testuser", policy_id, "111") + req, subject_data = add_subject_data(client, "testuser") assert req.status_code == 200 assert isinstance(subject_data, dict) value = subject_data["subject_data"]['data'] @@ -51,27 +64,55 @@ def test_add_subject_data(): def test_delete_subject_data(): client = utilities.register_client() - policy_id = utilities.get_policy_id() + subject_category_id, object_category_id, action_category_id, meta_rule_id,policy_id = builder.create_new_policy() success_req = delete_subject_data(client, policy_id) assert success_req.status_code == 200 + +def test_add_subject_data_with_empty_user(): + client = utilities.register_client() + req, subject_data = add_subject_data(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_subject_data_with_user_contain_space(): + client = utilities.register_client() + req, subject_data = add_subject_data(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_delete_subject_data_without_policy_id(): + client = utilities.register_client() + success_req = delete_subject_data(client, "") + assert success_req.status_code == 404 + # --------------------------------------------------------------------------- # object_categories_test -def get_object_data(client, policy_id): - req = client.get("/policies/{}/object_data".format(policy_id)) +def get_object_data(client, policy_id, category_id=None): + if category_id is None: + req = client.get("/policies/{}/object_data".format(policy_id)) + else: + req = client.get("/policies/{}/object_data/{}".format(policy_id, category_id)) object_data = utilities.get_json(req.data) return req, object_data -def add_object_data(client, name, policy_id, category_id): +def add_object_data(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) data = { "name": name, "description": "description of {}".format(name) } - req = client.post("/policies/{}/object_data/{}".format(policy_id, category_id), data=json.dumps(data), + req = client.post("/policies/{}/object_data/{}".format(policy_id, object_category_id), data=json.dumps(data), headers={'Content-Type': 'application/json'}) object_data = utilities.get_json(req.data) return req, object_data @@ -92,16 +133,19 @@ def test_get_object_data(): def test_add_object_data(): - policy_id = utilities.get_policy_id() client = utilities.register_client() - req, object_data = add_object_data(client, "testuser", policy_id, "111") + req, object_data = add_object_data(client, "testuser") assert req.status_code == 200 assert isinstance(object_data, dict) value = object_data["object_data"]['data'] assert "object_data" in object_data id = list(value.keys())[0] - assert value[id]['value']['name'] == "testuser" - assert value[id]['value']['description'] == "description of {}".format("testuser") + print("-----------------------") + print(id) + print(value[id]) + print("-----------------------") + assert value[id]['name'] == "testuser" + assert value[id]['description'] == "description of {}".format("testuser") def test_delete_object_data(): @@ -110,23 +154,50 @@ def test_delete_object_data(): success_req = delete_object_data(client, policy_id) assert success_req.status_code == 200 + +def test_add_object_data_with_empty_user(): + client = utilities.register_client() + req, subject_data = add_object_data(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_object_data_with_user_contain_space(): + client = utilities.register_client() + req, object_data = add_object_data(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_delete_object_data_without_policy_id(): + client = utilities.register_client() + success_req = delete_object_data(client, "") + assert success_req.status_code == 404 # --------------------------------------------------------------------------- # action_categories_test -def get_action_data(client, policy_id): - req = client.get("/policies/{}/action_data".format(policy_id)) +def get_action_data(client, policy_id, category_id=None): + if category_id is None: + req = client.get("/policies/{}/action_data".format(policy_id)) + else: + req = client.get("/policies/{}/action_data/{}".format(policy_id, category_id)) action_data = utilities.get_json(req.data) return req, action_data -def add_action_data(client, name, policy_id, category_id): +def add_action_data(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) data = { "name": name, "description": "description of {}".format(name) } - req = client.post("/policies/{}/action_data/{}".format(policy_id, category_id), data=json.dumps(data), + req = client.post("/policies/{}/action_data/{}".format(policy_id, action_category_id), data=json.dumps(data), headers={'Content-Type': 'application/json'}) action_data = utilities.get_json(req.data) return req, action_data @@ -147,16 +218,15 @@ def test_get_action_data(): def test_add_action_data(): - policy_id = utilities.get_policy_id() client = utilities.register_client() - req, action_data = add_action_data(client, "testuser", policy_id, "111") + req, action_data = add_action_data(client, "testuser") assert req.status_code == 200 assert isinstance(action_data, dict) value = action_data["action_data"]['data'] assert "action_data" in action_data id = list(value.keys())[0] - assert value[id]['value']['name'] == "testuser" - assert value[id]['value']['description'] == "description of {}".format("testuser") + assert value[id]['name'] == "testuser" + assert value[id]['description'] == "description of {}".format("testuser") def test_delete_action_data(): @@ -165,4 +235,23 @@ def test_delete_action_data(): success_req = delete_action_data(client, policy_id) assert success_req.status_code == 200 -# ---------------------------------------------------------------------------
\ No newline at end of file + +def test_add_action_data_with_empty_user(): + client = utilities.register_client() + req, action_data = add_action_data(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_action_data_with_user_contain_space(): + client = utilities.register_client() + req, action_data = add_action_data(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_delete_action_data_without_policy_id(): + client = utilities.register_client() + success_req = delete_action_data(client, "") + assert success_req.status_code == 404 +# --------------------------------------------------------------------------- diff --git a/moon_manager/tests/unit_python/api/test_export.py b/moon_manager/tests/unit_python/api/test_export.py new file mode 100644 index 00000000..ac8e8d17 --- /dev/null +++ b/moon_manager/tests/unit_python/api/test_export.py @@ -0,0 +1,282 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import json +import api.utilities as utilities +import api.import_export_utilities as import_export_utilities + + +MODEL_WITHOUT_META_RULES = {"models": [{"name": "test model", "description": "model description", "meta_rules": []}]} + +POLICIES = {"models": [{"name": "test model", "description": "", "meta_rules": []}], + "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}]} + +SUBJECTS_OBJECTS_ACTIONS = {"models": [{"name": "test model", "description": "", "meta_rules": []}], + "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}], + "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {"field_extra_subject": "value extra subject"}, "policies": [{"name": "test policy"}]}], + "objects": [{"name": "test object", "description": "description of the object", "extra": {"field_extra_object": "value extra object"}, "policies": [{"name": "test policy"}]}], + "actions": [{"name": "test action", "description": "description of the action", "extra": {"field_extra_action": "value extra action"}, "policies": [{"name": "test policy"}]}]} + + +SUBJECT_OBJECT_ACTION_CATEGORIES = {"subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "action category description"}]} + +SUBJECT_OBJECT_ACTION_DATA = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "meta rule"}]}], + "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}], + "subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "action category description"}], + "subject_data": [{"name": "test subject data", "description": "subject data description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}], + "object_data": [{"name": "test object data", "description": "object data description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}], + "action_data": [{"name": "test action data", "description": "action data description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}], + "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]} + + +META_RULES = {"subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "object action description"}], + "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]} + + +ASSIGNMENTS = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "meta rule"}]}], + "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}], + "subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "action category description"}], + "subject_data": [{"name": "test subject data", "description": "subject data description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}], + "object_data": [{"name": "test object data", "description": "object data description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}], + "action_data": [{"name": "test action data", "description": "action data description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}], + "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}], + "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {"field_extra_subject": "value extra subject"}, "policies": [{"name": "test policy"}]}], + "objects": [{"name": "test object e0", "description": "description of the object", "extra": {"field_extra_object": "value extra object"}, "policies": [{"name": "test policy"}]}], + "actions": [{"name": "test action e0", "description": "description of the action", "extra": {"field_extra_action": "value extra action"}, "policies": [{"name": "test policy"}]}], + "subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "test subject data"}]}], + "object_assignments": [{"object": {"name": "test object e0"}, "category": {"name": "test object categories"}, "assignments": [{"name": "test object data"}]}], + "action_assignments": [{"action": {"name": "test action e0"}, "category": {"name": "test action categories"}, "assignments": [{"name": "test action data"}]}]} + +RULES = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "meta rule"}]}], + "policies": [{"name": "test policy", "genre": "authz", "description": "policy description", "model": {"name" : "test model"}}], + "subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "action category description"}], + "subject_data": [{"name": "test subject data", "description": "subject data description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}], + "object_data": [{"name": "test object data", "description": "object data description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}], + "action_data": [{"name": "test action data", "description": "action data description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}], + "meta_rules": [{"name": "meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}], + "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {"field_extra_subject": "value extra subject"}, "policies": [{"name": "test policy"}]}], + "objects": [{"name": "test object e1", "description": "description of the object", "extra": {"field_extra_object": "value extra object"}, "policies": [{"name": "test policy"}]}], + "actions": [{"name": "test action e1", "description": "description of the action", "extra": {"field_extra_action": "value extra action"}, "policies": [{"name": "test policy"}]}], + "subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "test subject data"}]}], + "object_assignments": [{"object": {"name": "test object e1"}, "category": {"name": "test object categories"}, "assignments": [{"name": "test object data"}]}], + "action_assignments": [{"action": {"name": "test action e1"}, "category": {"name": "test action categories"}, "assignments": [{"name": "test action data"}]}], + "rules": [{"meta_rule": {"name": "meta rule"}, "rule": {"subject_data": [{"name": "test subject data"}], "object_data": [{"name": "test object data"}], "action_data": [{"name": "test action data"}]}, "policy": {"name":"test policy"}, "instructions": {"decision": "grant"}, "enabled": True}] + } + + +def test_export_models(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(MODEL_WITHOUT_META_RULES)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + + assert "content" in data + assert "models" in data["content"] + assert isinstance(data["content"]["models"], list) + assert len(data["content"]["models"]) == 1 + model = data["content"]["models"][0] + assert model["name"] == "test model" + assert model["description"] == "model description" + assert isinstance(model["meta_rules"], list) + assert len(model["meta_rules"]) == 0 + + +def test_export_policies(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(POLICIES)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + + assert "content" in data + assert "policies" in data["content"] + assert isinstance(data["content"]["policies"], list) + assert len(data["content"]["policies"]) == 1 + policy = data["content"]["policies"][0] + assert policy["name"] == "test policy" + assert policy["genre"] == "authz" + assert policy["description"] == "policy description" + assert "model" in policy + assert "name" in policy["model"] + model = policy["model"] + assert model["name"] == "test model" + + +def test_export_subject_object_action(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(SUBJECTS_OBJECTS_ACTIONS)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + + assert "content" in data + type_elements = ["subject", "object", "action"] + for type_element in type_elements: + key = type_element + "s" + assert key in data["content"] + assert isinstance(data["content"][key], list) + assert len(data["content"][key]) == 1 + element = data["content"][key][0] + if type_element == "subject": + assert element["name"] == "testuser" + else: + assert element["name"] == "test "+ type_element + assert element["description"] == "description of the " + type_element + assert "policies" in element + assert isinstance(element["policies"], list) + assert len(element["policies"]) == 1 + assert isinstance(element["policies"][0], dict) + assert element["policies"][0]["name"] == "test policy" + assert isinstance(element["extra"], dict) + key_dict = "field_extra_" + type_element + value_dict = "value extra " + type_element + assert key_dict in element["extra"] + assert element["extra"][key_dict] == value_dict + + +def test_export_subject_object_action_categories(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(SUBJECT_OBJECT_ACTION_CATEGORIES)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + assert "content" in data + type_elements = ["subject", "object", "action"] + for type_element in type_elements: + key = type_element + "_categories" + assert key in data["content"] + assert isinstance(data["content"][key], list) + assert len(data["content"][key]) == 1 + category = data["content"][key][0] + assert category["name"] == "test " + type_element + " categories" + assert category["description"] == type_element + " category description" + + +def test_export_subject_object_action_data(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(SUBJECT_OBJECT_ACTION_DATA)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + assert "content" in data + type_elements = ["subject", "object", "action"] + for type_element in type_elements: + key = type_element + "_data" + assert key in data["content"] + assert isinstance(data["content"][key], list) + assert len(data["content"][key]) == 1 + data_elt = data["content"][key][0] + assert data_elt["name"] == "test " + type_element + " data" + assert data_elt["description"] == type_element + " data description" + assert isinstance(data_elt["policy"], dict) + assert data_elt["policy"]["name"] == "test policy" + assert isinstance(data_elt["category"], dict) + assert data_elt["category"]["name"] == "test " + type_element + " categories" + + +def test_export_assignments(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(ASSIGNMENTS)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + assert "content" in data + type_elements = ["subject", "object", "action"] + for type_element in type_elements: + key = type_element + "_assignments" + assert key in data["content"] + assert isinstance(data["content"][key], list) + assert len(data["content"][key]) == 1 + assignment_elt = data["content"][key][0] + assert type_element in assignment_elt + assert isinstance(assignment_elt[type_element], dict) + if type_element == "subject": + assert assignment_elt[type_element]["name"] == "testuser" + else: + assert assignment_elt[type_element]["name"] == "test " + type_element + " e0" + assert "category" in assignment_elt + assert isinstance(assignment_elt["category"], dict) + assert assignment_elt["category"]["name"] == "test " + type_element + " categories" + assert "assignments" in assignment_elt + assert isinstance(assignment_elt["assignments"], list) + assert len(assignment_elt["assignments"]) == 1 + assert assignment_elt["assignments"][0]["name"] == "test " + type_element + " data" + + import_export_utilities.clean_all(client) + + +def test_export_rules(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(RULES)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req = client.get("/export") + assert req.status_code == 200 + data = utilities.get_json(req.data) + assert "content" in data + assert "rules" in data["content"] + assert isinstance(data["content"]["rules"], list) + assert len(data["content"]["rules"]) == 1 + rule = data["content"]["rules"][0] + assert "instructions" in rule + assert "decision" in rule["instructions"] + assert rule["instructions"]["decision"] == "grant" + assert "enabled" in rule + assert rule["enabled"] + assert "meta_rule" in rule + assert rule["meta_rule"]["name"] == "meta rule" + assert "policy" in rule + assert rule["policy"]["name"] == "test policy" + assert "rule" in rule + rule = rule["rule"] + assert "subject_data" in rule + assert isinstance(rule["subject_data"], list) + assert len(rule["subject_data"]) == 1 + assert rule["subject_data"][0]["name"] == "test subject data" + assert "object_data" in rule + assert isinstance(rule["object_data"], list) + assert len(rule["object_data"]) == 1 + assert rule["object_data"][0]["name"] == "test object data" + assert "action_data" in rule + assert isinstance(rule["action_data"], list) + assert len(rule["action_data"]) == 1 + assert rule["action_data"][0]["name"] == "test action data" diff --git a/moon_manager/tests/unit_python/api/test_import.py b/moon_manager/tests/unit_python/api/test_import.py new file mode 100644 index 00000000..f1ab8251 --- /dev/null +++ b/moon_manager/tests/unit_python/api/test_import.py @@ -0,0 +1,498 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import api.utilities as utilities +import api.test_unit_models as test_models +import api.test_policies as test_policies +import api.test_meta_data as test_categories +import api.test_data as test_data +import api.test_meta_rules as test_meta_rules +import api.test_assignemnt as test_assignments +import api.test_rules as test_rules +import api.import_export_utilities as import_export_utilities + +import json + + +MODEL_WITHOUT_META_RULES = [ + {"models": [{"name": "test model", "description": "", "meta_rules": []}]}, + {"models": [{"name": "test model", "description": "new description", "meta_rules": [], "override": True}]}, + {"models": [{"name": "test model", "description": "description not taken into account", "meta_rules": [], "override": False}]} + ] + +POLICIES = [ + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "new description not taken into account", "model": {"name" : "test model"}, "mandatory": True}]}, + {"policies": [{"name": "test policy", "genre": "not authz ?", "description": "generates an exception", "model": {"name" : "test model"}, "override": True}]}, + {"models": [{"name": "test model", "description": "", "meta_rules": []}], "policies": [{"name": "test policy", "genre": "not authz ?", "description": "changes taken into account", "model": {"name" : "test model"}, "override": True}]}, +] + +SUBJECTS = [{"subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": []}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": []}]}, + {"policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {}, "mandatory": True}], "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": []}]}, + {"subjects": [{"name": "testuser", "description": "new description of the subject", "extra": {"email": "new-email@test.com"}, "policies": [{"name": "test other policy"}]}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": [{"name": "test policy"}]}]}] + + +OBJECTS = [ + {"objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": []}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], + "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": []}]}, + {"policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {}, "mandatory": True}], + "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": []}]}, + {"objects": [{"name": "test object", "description": "new description of the object", "extra": {"test": "test extra"}, + "policies": [{"name": "test other policy"}]}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], + "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": [{"name": "test policy"}]}]}, +] + + +ACTIONS = [{"actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": []}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": []}]}, + {"policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {}, "mandatory": True}], "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": []}]}, + {"actions": [{"name": "test action", "description": "new description of the action", "extra": {"test": "test extra"}, "policies": [{"name": "test other policy"}]}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {}, "mandatory": False}], "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": [{"name": "test policy"}]}]}] + + +SUBJECT_CATEGORIES = [{"subject_categories": [{"name": "test subject categories", "description": "subject category description"}]}, + {"subject_categories": [{"name": "test subject categories", "description": "new subject category description"}]}] + + +OBJECT_CATEGORIES = [{"object_categories": [{"name": "test object categories", "description": "object category description"}]}, + {"object_categories": [{"name": "test object categories", "description": "new object category description"}]}] + + +ACTION_CATEGORIES = [{"action_categories": [{"name": "test action categories", "description": "action category description"}]}, + {"action_categories": [{"name": "test action categories", "description": "new action category description"}]}] + +# meta_rules import is needed otherwise the search for data do not work !!! +PRE_DATA = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "good meta rule"}, {"name": "other good meta rule"}]}], + "policies": [{"name": "test other policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], + "subject_categories": [{"name": "test subject categories", "description": "subject category description"}, {"name": "other test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}, {"name": "other test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "action category description"}, {"name": "other test action categories", "description": "action category description"}], + "meta_rules": [{"name": "good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}, + {"name": "other good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "other test subject categories"}], "object_categories": [{"name": "other test object categories"}], "action_categories": [{"name": "other test action categories"}]}]} + +SUBJECT_DATA = [{"subject_data": [{"name": "not valid subject data", "description": "", "policies": [{}], "category": {}}]}, + {"subject_data": [{"name": "not valid subject data", "description": "", "policies": [{}], "category": {"name": "test subject categories"}}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], "subject_data": [{"name": "one valid subject data", "description": "description", "policies": [{}], "category": {"name": "test subject categories"}}]}, + {"subject_data": [{"name": "valid subject data", "description": "description", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}]}, + {"subject_data": [{"name": "valid subject data", "description": "new description", "policies": [{"name": "test other policy"}], "category": {"name": "test subject categories"}}]}] + +OBJECT_DATA = [{"object_data": [{"name": "not valid object data", "description": "", "policies": [{}], "category": {}}]}, + {"object_data": [{"name": "not valid object data", "description": "", "policies": [{}], "category": {"name": "test object categories"}}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], "object_data": [{"name": "one valid object data", "description": "description", "policies": [{}], "category": {"name": "test object categories"}}]}, + {"object_data": [{"name": "valid object data", "description": "description", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}]}, + {"object_data": [{"name": "valid object data", "description": "new description", "policies": [{"name": "test other policy"}], "category": {"name": "test object categories"}}]}] + + +ACTION_DATA = [{"action_data": [{"name": "not valid action data", "description": "", "policies": [{}], "category": {}}]}, + {"action_data": [{"name": "not valid action data", "description": "", "policies": [{}], "category": {"name": "test action categories"}}]}, + {"policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name": "test model"}, "mandatory": True}], "action_data": [{"name": "one valid action data", "description": "description", "policies": [{}], "category": {"name": "test action categories"}}]}, + {"action_data": [{"name": "valid action data", "description": "description", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}]}, + {"action_data": [{"name": "valid action data", "description": "new description", "policies": [{"name": "test other policy"}], "category": {"name": "test action categories"}}]}] + + +PRE_META_RULES = {"subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "object action description"}]} + +META_RULES = [{"meta_rules" :[{"name": "bad meta rule", "description": "not valid meta rule", "subject_categories": [{"name": "not valid category"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]}, + {"meta_rules": [{"name": "bad meta rule", "description": "not valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "not valid category"}], "action_categories": [{"name": "test action categories"}]}]}, + {"meta_rules": [{"name": "bad meta rule", "description": "not valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "not valid category"}]}]}, + {"meta_rules": [{"name": "good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}]}] + + +PRE_ASSIGNMENTS = {"models": [{"name": "test model", "description": "", "meta_rules": [{"name": "good meta rule"}]}], + "policies": [{"name": "test policy", "genre": "authz", "description": "description", "model": {"name" : "test model"}, "mandatory": True}], + "subject_categories": [{"name": "test subject categories", "description": "subject category description"}], + "object_categories": [{"name": "test object categories", "description": "object category description"}], + "action_categories": [{"name": "test action categories", "description": "object action description"}], + "subjects": [{"name": "testuser", "description": "description of the subject", "extra": {}, "policies": [{"name": "test policy"}]}], + "objects": [{"name": "test object", "description": "description of the object", "extra": {}, "policies": [{"name": "test policy"}]}], + "actions": [{"name": "test action", "description": "description of the action", "extra": {}, "policies": [{"name": "test policy"}]}], + "meta_rules": [{"name": "good meta rule", "description": "valid meta rule", "subject_categories": [{"name": "test subject categories"}], "object_categories": [{"name": "test object categories"}], "action_categories": [{"name": "test action categories"}]}], + "subject_data": [{"name": "subject data", "description": "test subject data", "policies": [{"name": "test policy"}], "category": {"name": "test subject categories"}}], + "object_data": [{"name": "object data", "description": "test object data", "policies": [{"name": "test policy"}], "category": {"name": "test object categories"}}], + "action_data": [{"name": "action data", "description": "test action data", "policies": [{"name": "test policy"}], "category": {"name": "test action categories"}}]} + + +SUBJECT_ASSIGNMENTS = [{"subject_assignments": [{"subject": {"name": "unknonw"}, "category" : {"name": "test subject categories"}, "assignments": [{"name": "subject data"}]}]}, + {"subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "unknown"}, "assignments": [{"name": "subject data"}]}]}, + {"subject_assignments": [{"subject": {"name": "testuser"}, "category" : {"name": "test subject categories"}, "assignments": [{"name": "unknwon"}]}]}, + {"subject_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "subject data"}]}]}] + +OBJECT_ASSIGNMENTS = [{"object_assignments": [{"object": {"name": "unknown"}, "category" : {"name": "test object categories"}, "assignments": [{"name": "object data"}]}]}, + {"object_assignments": [{"object": {"name": "test object"}, "category" : {"name": "unknown"}, "assignments": [{"name": "object data"}]}]}, + {"object_assignments": [{"object": {"name": "test object"}, "category" : {"name": "test object categories"}, "assignments": [{"name": "unknown"}]}]}, + {"object_assignments": [{"object": {"name": "test object"}, "category" : {"name": "test object categories"}, "assignments": [{"name": "object data"}]}]}] + +ACTION_ASSIGNMENTS = [{"action_assignments": [{"action": {"name": "unknown"}, "category" : {"name": "test action categories"}, "assignments": [{"name": "action data"}]}]}, + {"action_assignments": [{"action": {"name": "test action"}, "category" : {"name": "unknown"}, "assignments": [{"name": "action data"}]}]}, + {"action_assignments": [{"action": {"name": "test action"}, "category" : {"name": "test action categories"}, "assignments": [{"name": "unknown"}]}]}, + {"action_assignments": [{"action": {"name": "test action"}, "category" : {"name": "test action categories"}, "assignments": [{"name": "action data"}]}]}] + +RULES = [{"rules": [{"meta_rule": {"name": "unknown meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]}, + {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "unknown policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]}, + {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "unknown subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]}, + {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "unknown object data"}], "action_data": [{"name": "action data"}]}}]}, + {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "unknown action data"}]}}]}, + {"rules": [{"meta_rule": {"name": "good meta rule"}, "policy": {"name": "test policy"}, "instructions": {"decision": "grant"}, "enabled": True, "rule": {"subject_data": [{"name": "subject data"}], "object_data": [{"name": "object data"}], "action_data": [{"name": "action data"}]}}]}] + + +def test_import_models_without_new_meta_rules(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + counter = 0 + for models_description in MODEL_WITHOUT_META_RULES: + req = client.post("/import", content_type='application/json', data=json.dumps(models_description)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + req, models = test_models.get_models(client) + models = models["models"] + assert len(list(models.keys())) == 1 + values = list(models.values()) + assert values[0]["name"] == "test model" + if counter == 0: + assert len(values[0]["description"]) == 0 + if counter == 1 or counter == 2: + assert values[0]["description"] == "new description" + counter = counter + 1 + import_export_utilities.clean_all(client) + + +def test_import_policies(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + counter = -1 + for policy_description in POLICIES: + counter = counter + 1 + req = client.post("/import", content_type='application/json', data=json.dumps(policy_description)) + try: + data = utilities.get_json(req.data) + assert data == "Import ok !" + except Exception: + assert counter == 2 # this is an expected failure + continue + + req, policies = test_policies.get_policies(client) + policies = policies["policies"] + assert len(list(policies.keys())) == 1 + values = list(policies.values()) + assert values[0]["name"] == "test policy" + if counter < 3: + assert values[0]["genre"] == "authz" + assert values[0]["description"] == "description" + else: + assert values[0]["genre"] == "not authz ?" + assert values[0]["description"] == "changes taken into account" + assert len(values[0]["model_id"]) > 0 + import_export_utilities.clean_all(client) + + +def test_import_subject_object_action(): + client = utilities.register_client() + type_elements = ["object", "action"] + + for type_element in type_elements: + import_export_utilities.clean_all(client) + counter = -1 + # set the getters and the comparison values + if type_element == "subject": + elements = SUBJECTS + clean_method = import_export_utilities.clean_subjects + name = "testuser" + key_extra = "email" + value_extra = "new-email@test.com" + elif type_element == "object": + elements = OBJECTS + clean_method = import_export_utilities.clean_objects + name = "test object" + key_extra = "test" + value_extra = "test extra" + else: + elements = ACTIONS + clean_method = import_export_utilities.clean_actions + name = "test action" + key_extra = "test" + value_extra = "test extra" + + for element in elements: + counter = counter + 1 + if counter == 2 or counter == 4: + clean_method(client) + + req = client.post("/import", content_type='application/json', data=json.dumps(element)) + if counter < 2: + assert req.status_code == 500 + continue + + try: + data = utilities.get_json(req.data) + except Exception as e: + assert False + #assert counter < 2 # Â this is an expected failure + #continue + + assert data == "Import ok !" + get_elements = utilities.get_json(client.get("/"+type_element + "s").data) + get_elements = get_elements[type_element + "s"] + + assert len(list(get_elements.keys())) == 1 + values = list(get_elements.values()) + assert values[0]["name"] == name + if counter == 2 or counter == 4: + assert values[0]["description"] == "description of the " + type_element + #assert not values[0]["extra"] + if counter == 3: + assert values[0]["description"] == "new description of the " + type_element + assert values[0]["extra"][key_extra] == value_extra + + #Â assert len(values[0]["policy_list"]) == 1 + import_export_utilities.clean_all(client) + + +def test_import_subject_object_action_categories(): + client = utilities.register_client() + type_elements = ["subject", "object", "action"] + + for type_element in type_elements: + import_export_utilities.clean_all(client) + counter = -1 + # set the getters and the comparison values + if type_element == "subject": + elements = SUBJECT_CATEGORIES + get_method = test_categories.get_subject_categories + elif type_element == "object": + elements = OBJECT_CATEGORIES + get_method = test_categories.get_object_categories + else: + elements = ACTION_CATEGORIES + get_method = test_categories.get_action_categories + + for element in elements: + req = client.post("/import", content_type='application/json', data=json.dumps(element)) + counter = counter + 1 + data = utilities.get_json(req.data) + assert data == "Import ok !" + req, get_elements = get_method(client) + get_elements = get_elements[type_element + "_categories"] + assert len(list(get_elements.keys())) == 1 + values = list(get_elements.values()) + assert values[0]["name"] == "test " + type_element + " categories" + assert values[0]["description"] == type_element + " category description" + + +def test_import_meta_rules(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + # import some categories + req = client.post("/import", content_type='application/json', data=json.dumps(PRE_META_RULES)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + counter = -1 + for meta_rule in META_RULES: + counter = counter + 1 + req = client.post("/import", content_type='application/json', data=json.dumps(meta_rule)) + if counter != 3: + assert req.status_code == 500 + continue + else: + data = utilities.get_json(req.data) + assert data == "Import ok !" + assert req.status_code == 200 + + req, meta_rules = test_meta_rules.get_meta_rules(client) + meta_rules = meta_rules["meta_rules"] + key = list(meta_rules.keys())[0] + assert isinstance(meta_rules,dict) + assert meta_rules[key]["name"] == "good meta rule" + assert meta_rules[key]["description"] == "valid meta rule" + assert len(meta_rules[key]["subject_categories"]) == 1 + assert len(meta_rules[key]["object_categories"]) == 1 + assert len(meta_rules[key]["action_categories"]) == 1 + + subject_category_key = meta_rules[key]["subject_categories"][0] + object_category_key = meta_rules[key]["object_categories"][0] + action_category_key = meta_rules[key]["action_categories"][0] + + req, sub_cat = test_categories.get_subject_categories(client) + sub_cat = sub_cat["subject_categories"] + assert sub_cat[subject_category_key]["name"] == "test subject categories" + + req, ob_cat = test_categories.get_object_categories(client) + ob_cat = ob_cat["object_categories"] + assert ob_cat[object_category_key]["name"] == "test object categories" + + req, ac_cat = test_categories.get_action_categories(client) + ac_cat = ac_cat["action_categories"] + assert ac_cat[action_category_key]["name"] == "test action categories" + + import_export_utilities.clean_all(client) + + +def test_import_subject_object_action_assignments(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(PRE_ASSIGNMENTS)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + type_elements = ["subject", "object", "action"] + + for type_element in type_elements: + counter = -1 + if type_element == "subject": + datas = SUBJECT_ASSIGNMENTS + get_method = test_assignments.get_subject_assignment + elif type_element == "object": + datas = OBJECT_ASSIGNMENTS + get_method = test_assignments.get_object_assignment + else: + datas = ACTION_ASSIGNMENTS + get_method = test_assignments.get_action_assignment + + for assignments in datas: + counter = counter + 1 + req = client.post("/import", content_type='application/json', data=json.dumps(assignments)) + if counter != 3: + assert req.status_code == 500 + continue + else: + assert data == "Import ok !" + assert req.status_code == 200 + req, policies = test_policies.get_policies(client) + for policy_key in policies["policies"]: + req, get_assignments = get_method(client, policy_key) + get_assignments = get_assignments[type_element+"_assignments"] + assert len(get_assignments) == 1 + + +def test_import_rules(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(PRE_ASSIGNMENTS)) + data = utilities.get_json(req.data) + assert data == "Import ok !" + + counter = -1 + for rule in RULES: + counter = counter + 1 + req = client.post("/import", content_type='application/json', data=json.dumps(rule)) + + if counter < 5: + assert req.status_code == 500 + continue + + assert req.status_code == 200 + + req, rules = test_rules.test_get_rules() + rules = rules["rules"] + rules = rules["rules"] + assert len(rules) == 1 + rules = rules[0] + assert rules["enabled"] + assert rules["instructions"]["decision"] == "grant" + + req, meta_rules = test_meta_rules.get_meta_rules(client) + assert meta_rules["meta_rules"][list(meta_rules["meta_rules"].keys())[0]]["name"] == "good meta rule" + + +def test_import_subject_object_action_data(): + client = utilities.register_client() + type_elements = ["subject", "object", "action"] + + for type_element in type_elements: + import_export_utilities.clean_all(client) + req = client.post("/import", content_type='application/json', data=json.dumps(PRE_DATA)) + counter = -1 + # set the getters and the comparison values + if type_element == "subject": + elements = SUBJECT_DATA + get_method = test_data.get_subject_data + get_categories = test_categories.get_subject_categories + elif type_element == "object": + elements = OBJECT_DATA + get_method = test_data.get_object_data + get_categories = test_categories.get_object_categories + else: + elements = ACTION_DATA + get_method = test_data.get_action_data + get_categories = test_categories.get_action_categories + + for element in elements: + req = client.post("/import", content_type='application/json', data=json.dumps(element)) + counter = counter + 1 + if counter == 0 or counter == 1: + assert req.status_code == 500 + continue + assert req.status_code == 200 + data = utilities.get_json(req.data) + assert data == "Import ok !" + + req, policies = test_policies.get_policies(client) + policies = policies["policies"] + req, categories = get_categories(client) + categories = categories[type_element + "_categories"] + case_tested = False + for policy_key in policies.keys(): + policy = policies[policy_key] + for category_key in categories: + req, get_elements = get_method(client, policy_id=policy_key, category_id=category_key) + if len(get_elements[type_element+"_data"]) == 0: + continue + + # do this because the backend gives an element with empty data if the policy_key, + # category_key couple does not have any data... + get_elements = get_elements[type_element+"_data"] + if len(get_elements[0]["data"]) == 0: + continue + + if policy["name"] == "test policy": + assert len(get_elements) == 1 + el = get_elements[0] + assert isinstance(el["data"], dict) + if counter == 2: + assert len(el["data"].keys()) == 1 + el = el["data"][list(el["data"].keys())[0]] + if "value" in el: + el = el["value"] + assert el["name"] == "one valid " + type_element + " data" + if counter == 3: + assert len(el["data"].keys()) == 2 + el1 = el["data"][list(el["data"].keys())[0]] + el2 = el["data"][list(el["data"].keys())[1]] + if "value" in el1: + el1 = el1["value"] + el2 = el2["value"] + assert (el1["name"] == "one valid " + type_element + " data" and el2["name"] == "valid " + type_element + " data") or (el2["name"] == "one valid " + type_element + " data" and el1["name"] == "valid " + type_element + " data") + assert el1["description"] == "description" + assert el2["description"] == "description" + + case_tested = True + + if policy["name"] == "test other policy": + if counter == 4: + assert len(get_elements) == 1 + el = get_elements[0] + assert isinstance(el["data"], dict) + assert len(el["data"].keys()) == 1 + el = el["data"][list(el["data"].keys())[0]] + if "value" in el: + el = el["value"] + assert el["name"] == "valid " + type_element + " data" + assert el["description"] == "new description" + case_tested = True + + assert case_tested is True + + +def test_clean(): + client = utilities.register_client() + import_export_utilities.clean_all(client) + #restore the database as previously + utilities.get_policy_id() diff --git a/moon_manager/tests/unit_python/api/test_meta_data.py b/moon_manager/tests/unit_python/api/test_meta_data.py new file mode 100644 index 00000000..4cb86913 --- /dev/null +++ b/moon_manager/tests/unit_python/api/test_meta_data.py @@ -0,0 +1,235 @@ +import json +import api.utilities as utilities + +#subject_categories_test + + +def get_subject_categories(client): + req = client.get("/subject_categories") + subject_categories = utilities.get_json(req.data) + return req, subject_categories + + +def add_subject_categories(client, name): + data = { + "name": name, + "description": "description of {}".format(name) + } + req = client.post("/subject_categories", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subject_categories = utilities.get_json(req.data) + return req, subject_categories + + +def delete_subject_categories(client, name): + request, subject_categories = get_subject_categories(client) + for key, value in subject_categories['subject_categories'].items(): + if value['name'] == name: + return client.delete("/subject_categories/{}".format(key)) + + +def delete_subject_categories_without_id(client): + req = client.delete("/subject_categories/{}".format("")) + return req + + +def test_get_subject_categories(): + client = utilities.register_client() + req, subject_categories = get_subject_categories(client) + assert req.status_code == 200 + assert isinstance(subject_categories, dict) + assert "subject_categories" in subject_categories + + +def test_add_subject_categories(): + client = utilities.register_client() + req, subject_categories = add_subject_categories(client, "testuser") + assert req.status_code == 200 + assert isinstance(subject_categories, dict) + value = list(subject_categories["subject_categories"].values())[0] + assert "subject_categories" in subject_categories + assert value['name'] == "testuser" + assert value['description'] == "description of {}".format("testuser") + + +def test_add_subject_categories_with_empty_user(): + client = utilities.register_client() + req, subject_categories = add_subject_categories(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_subject_categories_with_user_contain_space(): + client = utilities.register_client() + req, subject_categories = add_subject_categories(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_delete_subject_categories(): + client = utilities.register_client() + req = delete_subject_categories(client, "testuser") + assert req.status_code == 200 + + +def test_delete_subject_categories_without_id(): + client = utilities.register_client() + req = delete_subject_categories_without_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Subject Category Unknown" + + +#--------------------------------------------------------------------------- +#object_categories_test + +def get_object_categories(client): + req = client.get("/object_categories") + object_categories = utilities.get_json(req.data) + return req, object_categories + + +def add_object_categories(client, name): + data = { + "name": name, + "description": "description of {}".format(name) + } + req = client.post("/object_categories", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + object_categories = utilities.get_json(req.data) + return req, object_categories + + +def delete_object_categories(client, name): + request, object_categories = get_object_categories(client) + for key, value in object_categories['object_categories'].items(): + if value['name'] == name: + return client.delete("/object_categories/{}".format(key)) + + +def delete_object_categories_without_id(client): + req = client.delete("/object_categories/{}".format("")) + return req + + +def test_get_object_categories(): + client = utilities.register_client() + req, object_categories = get_object_categories(client) + assert req.status_code == 200 + assert isinstance(object_categories, dict) + assert "object_categories" in object_categories + + +def test_add_object_categories(): + client = utilities.register_client() + req, object_categories = add_object_categories(client, "testuser") + assert req.status_code == 200 + assert isinstance(object_categories, dict) + value = list(object_categories["object_categories"].values())[0] + assert "object_categories" in object_categories + assert value['name'] == "testuser" + assert value['description'] == "description of {}".format("testuser") + + +def test_add_object_categories_with_empty_user(): + client = utilities.register_client() + req, object_categories = add_object_categories(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_object_categories_with_user_contain_space(): + client = utilities.register_client() + req, object_categories = add_object_categories(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_delete_object_categories(): + client = utilities.register_client() + req = delete_object_categories(client, "testuser") + assert req.status_code == 200 + + +def test_delete_object_categories_without_id(): + client = utilities.register_client() + req = delete_object_categories_without_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Object Category Unknown" + + +#--------------------------------------------------------------------------- +#action_categories_test + +def get_action_categories(client): + req = client.get("/action_categories") + action_categories = utilities.get_json(req.data) + return req, action_categories + + +def add_action_categories(client, name): + data = { + "name": name, + "description": "description of {}".format(name) + } + req = client.post("/action_categories", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + action_categories = utilities.get_json(req.data) + return req, action_categories + + +def delete_action_categories(client, name): + request, action_categories = get_action_categories(client) + for key, value in action_categories['action_categories'].items(): + if value['name'] == name: + return client.delete("/action_categories/{}".format(key)) + + +def delete_action_categories_without_id(client): + req = client.delete("/action_categories/{}".format("")) + return req + + +def test_get_action_categories(): + client = utilities.register_client() + req, action_categories = get_action_categories(client) + assert req.status_code == 200 + assert isinstance(action_categories, dict) + assert "action_categories" in action_categories + + +def test_add_action_categories(): + client = utilities.register_client() + req, action_categories = add_action_categories(client, "testuser") + assert req.status_code == 200 + assert isinstance(action_categories, dict) + value = list(action_categories["action_categories"].values())[0] + assert "action_categories" in action_categories + assert value['name'] == "testuser" + assert value['description'] == "description of {}".format("testuser") + + +def test_add_action_categories_with_empty_user(): + client = utilities.register_client() + req, action_categories = add_action_categories(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_action_categories_with_user_contain_space(): + client = utilities.register_client() + req, action_categories = add_action_categories(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_delete_action_categories(): + client = utilities.register_client() + req = delete_action_categories(client, "testuser") + assert req.status_code == 200 + + +def test_delete_action_categories_without_id(): + client = utilities.register_client() + req = delete_action_categories_without_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Action Category Unknown" diff --git a/moon_manager/tests/unit_python/api/test_meta_rules.py b/moon_manager/tests/unit_python/api/test_meta_rules.py new file mode 100644 index 00000000..80d648b4 --- /dev/null +++ b/moon_manager/tests/unit_python/api/test_meta_rules.py @@ -0,0 +1,175 @@ +import json +import api.utilities as utilities +from helpers import category_helper +from uuid import uuid4 + + +def get_meta_rules(client): + req = client.get("/meta_rules") + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def add_meta_rules(client, name): + subject_category = category_helper.add_subject_category(value={"name": "subject category name"+uuid4().hex, "description": "description 1"}) + subject_category_id = list(subject_category.keys())[0] + object_category = category_helper.add_object_category(value={"name": "object category name"+ uuid4().hex, "description": "description 1"}) + object_category_id = list(object_category.keys())[0] + action_category = category_helper.add_action_category(value={"name": "action category name"+uuid4().hex, "description": "description 1"}) + action_category_id = list(action_category.keys())[0] + + data = { + "name": name, + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + req = client.post("/meta_rules", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def add_meta_rules_without_subject_category_ids(client, name): + data = { + "name": name, + "subject_categories": [], + "object_categories": ["object_category_id1"], + "action_categories": ["action_category_id1"] + } + req = client.post("/meta_rules", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def update_meta_rules(client, name, metaRuleId): + subject_category = category_helper.add_subject_category( + value={"name": "subject category name update" + uuid4().hex, "description": "description 1"}) + subject_category_id = list(subject_category.keys())[0] + object_category = category_helper.add_object_category( + value={"name": "object category name update" + uuid4().hex, "description": "description 1"}) + object_category_id = list(object_category.keys())[0] + action_category = category_helper.add_action_category( + value={"name": "action category name update" + uuid4().hex, "description": "description 1"}) + action_category_id = list(action_category.keys())[0] + data = { + "name": name, + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + req = client.patch("/meta_rules/{}".format(metaRuleId), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def update_meta_rules_without_subject_category_ids(client, name): + data = { + "name": name, + "subject_categories": [], + "object_categories": ["object_category_id1"], + "action_categories": ["action_category_id1"] + } + req = client.post("/meta_rules", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + meta_rules = utilities.get_json(req.data) + return req, meta_rules + + +def delete_meta_rules(client, name): + request, meta_rules = get_meta_rules(client) + for key, value in meta_rules['meta_rules'].items(): + if value['name'] == name: + req = client.delete("/meta_rules/{}".format(key)) + break + return req + + +def delete_meta_rules_without_id(client): + req = client.delete("/meta_rules/{}".format("")) + return req + + +def test_get_meta_rules(): + client = utilities.register_client() + req, meta_rules = get_meta_rules(client) + assert req.status_code == 200 + assert isinstance(meta_rules, dict) + assert "meta_rules" in meta_rules + + +def test_add_meta_rules(): + client = utilities.register_client() + req, meta_rules = add_meta_rules(client, "testuser") + assert req.status_code == 200 + assert isinstance(meta_rules, dict) + value = list(meta_rules["meta_rules"].values())[0] + assert "meta_rules" in meta_rules + assert value['name'] == "testuser" + + +def test_add_meta_rules_with_empty_user(): + client = utilities.register_client() + req, meta_rules = add_meta_rules(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_meta_rules_with_user_contain_space(): + client = utilities.register_client() + req, meta_rules = add_meta_rules(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_add_meta_rules_without_subject_categories(): + client = utilities.register_client() + req, meta_rules = add_meta_rules_without_subject_category_ids(client, "testuser") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'subject_categories', [Empty Container]" + + +def test_delete_meta_rules(): + client = utilities.register_client() + req = delete_meta_rules(client, "testuser") + assert req.status_code == 200 + + +def test_delete_meta_rules_without_id(): + client = utilities.register_client() + req = delete_meta_rules_without_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Meta Rule Unknown" + + +def test_update_meta_rules(): + client = utilities.register_client() + req = add_meta_rules(client, "testuser") + meta_rule_id = list(req[1]['meta_rules'])[0] + req_update = update_meta_rules(client, "testuser", meta_rule_id) + assert req_update[0].status_code == 200 + delete_meta_rules(client, "testuser") + get_meta_rules(client) + + +def test_update_meta_rules_without_id(): + client = utilities.register_client() + req_update = update_meta_rules(client, "testuser", "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "400: Meta Rule Unknown" + + +def test_update_meta_rules_without_user(): + client = utilities.register_client() + req_update = update_meta_rules(client, "", "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]" + + +def test_update_meta_rules_without_subject_categories(): + client = utilities.register_client() + req_update = update_meta_rules_without_subject_category_ids(client, "testuser") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "Key: 'subject_categories', [Empty Container]" diff --git a/moon_manager/tests/unit_python/api/test_models.py b/moon_manager/tests/unit_python/api/test_models.py deleted file mode 100644 index 3c205d1d..00000000 --- a/moon_manager/tests/unit_python/api/test_models.py +++ /dev/null @@ -1,67 +0,0 @@ -import json -import api.utilities as utilities - - -def get_models(client): - req = client.get("/models") - models = utilities.get_json(req.data) - return req, models - - -def add_models(client, name): - data = { - "name": name, - "description": "description of {}".format(name), - "meta_rules": ["meta_rule_id1", "meta_rule_id2"] - } - req = client.post("/models", data=json.dumps(data), - headers={'Content-Type': 'application/json'}) - models = utilities.get_json(req.data) - return req, models - - -def delete_models(client, name): - request, models = get_models(client) - for key, value in models['models'].items(): - if value['name'] == name: - req = client.delete("/models/{}".format(key)) - break - return req - - -def delete_models_without_id(client): - req = client.delete("/models/{}".format("")) - return req - - -def test_get_models(): - client = utilities.register_client() - req, models= get_models(client) - assert req.status_code == 200 - assert isinstance(models, dict) - assert "models" in models - - -def test_add_models(): - client = utilities.register_client() - req, models = add_models(client, "testuser") - assert req.status_code == 200 - assert isinstance(models, dict) - value = list(models["models"].values())[0] - assert "models" in models - assert value['name'] == "testuser" - assert value["description"] == "description of {}".format("testuser") - assert value["meta_rules"][0] == "meta_rule_id1" - - -def test_delete_models(): - client = utilities.register_client() - req = delete_models(client, "testuser") - assert req.status_code == 200 - - -def test_delete_models_without_id(): - client = utilities.register_client() - req = delete_models_without_id(client) - assert req.status_code == 500 - diff --git a/moon_manager/tests/unit_python/api/test_pdp.py b/moon_manager/tests/unit_python/api/test_pdp.py index a2d0cb5a..1ac9b84f 100644 --- a/moon_manager/tests/unit_python/api/test_pdp.py +++ b/moon_manager/tests/unit_python/api/test_pdp.py @@ -1,6 +1,7 @@ import json import api.utilities as utilities -import pytest +from helpers import data_builder as builder +from uuid import uuid4 def get_pdp(client): @@ -16,6 +17,13 @@ def add_pdp(client, data): return req, pdp +def update_pdp(client, data, pdp_id): + req = client.patch("/pdp/{}".format(pdp_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + pdp = utilities.get_json(req.data) + return req, pdp + + def delete_pdp(client, key): req = client.delete("/pdp/{}".format(key)) return req @@ -35,9 +43,15 @@ def test_get_pdp(): def test_add_pdp(): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) data = { "name": "testuser", - "security_pipeline": ["policy_id_1", "policy_id_2"], + "security_pipeline": [policy_id], "keystone_project_id": "keystone_project_id", "description": "description of testuser" } @@ -60,3 +74,128 @@ def test_delete_pdp(): success_req = delete_pdp(client, key) break assert success_req.status_code == 200 + + +def test_add_pdp_with_empty_user(): + data = { + "name": "", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id", + "description": "description of testuser" + } + client = utilities.register_client() + req, models = add_pdp(client, data) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_pdp_with_user_contain_space(): + data = { + "name": "test user", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id", + "description": "description of testuser" + } + client = utilities.register_client() + req, models = add_pdp(client, data) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_add_pdp_without_security_pipeline(): + data = { + "name": "testuser", + "security_pipeline": [], + "keystone_project_id": "keystone_project_id", + "description": "description of testuser" + } + client = utilities.register_client() + req, meta_rules = add_pdp(client, data) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'security_pipeline', [Empty Container]" + + +def test_add_pdp_without_keystone(): + data = { + "name": "testuser", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "", + "description": "description of testuser" + } + client = utilities.register_client() + req, meta_rules = add_pdp(client, data) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'keystone_project_id', [Empty String]" + + +def test_update_pdp(): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1"+uuid4().hex, + object_category_name="object_category1"+uuid4().hex, + action_category_name="action_category1"+uuid4().hex, + meta_rule_name="meta_rule_1"+uuid4().hex, + model_name="model1"+uuid4().hex) + data_add = { + "name": "testuser", + "security_pipeline": [policy_id], + "keystone_project_id": "keystone_project_id", + "description": "description of testuser" + } + + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id_update = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) + data_update = { + "name": "testuser", + "security_pipeline": [policy_id_update], + "keystone_project_id": "keystone_project_id_update", + "description": "description of testuser" + } + client = utilities.register_client() + req = add_pdp(client, data_add) + pdp_id = list(req[1]['pdps'])[0] + req_update = update_pdp(client, data_update, pdp_id) + assert req_update[0].status_code == 200 + value = list(req_update[1]["pdps"].values())[0] + assert value["keystone_project_id"] == "keystone_project_id_update" + request, pdp = get_pdp(client) + for key, value in pdp['pdps'].items(): + if value['name'] == "testuser": + delete_pdp(client, key) + break + + +def test_update_pdp_without_id(): + client = utilities.register_client() + req_update = update_pdp(client, "testuser", "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == 'Invalid Key :name not found' + + +def test_update_pdp_without_user(): + data = { + "name": "", + "security_pipeline": ["policy_id_1", "policy_id_2"], + "keystone_project_id": "keystone_project_id", + "description": "description of testuser" + } + client = utilities.register_client() + req_update = update_pdp(client, data, "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]" + + +def test_update_pdp_without_security_pipeline(): + data = { + "name": "testuser", + "security_pipeline": [], + "keystone_project_id": "keystone_project_id", + "description": "description of testuser" + } + client = utilities.register_client() + req_update = update_pdp(client, data, "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "Key: 'security_pipeline', [Empty Container]"
\ No newline at end of file diff --git a/moon_manager/tests/unit_python/api/test_perimeter.py b/moon_manager/tests/unit_python/api/test_perimeter.py index db09780f..322d90c6 100644 --- a/moon_manager/tests/unit_python/api/test_perimeter.py +++ b/moon_manager/tests/unit_python/api/test_perimeter.py @@ -2,156 +2,282 @@ # import moon_manager.api import json import api.utilities as utilities +from helpers import data_builder as builder +from uuid import uuid4 def get_subjects(client): req = client.get("/subjects") - assert req.status_code == 200 subjects = utilities.get_json(req.data) - assert isinstance(subjects, dict) - assert "subjects" in subjects - return subjects + return req, subjects def add_subjects(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) data = { - "name": name, + "name": name + uuid4().hex, "description": "description of {}".format(name), "password": "password for {}".format(name), "email": "{}@moon".format(name) } - req = client.post("/subjects", data=json.dumps(data), + req = client.post("/policies/{}/subjects".format(policy_id), data=json.dumps(data), headers={'Content-Type': 'application/json'}) - assert req.status_code == 200 subjects = utilities.get_json(req.data) + return req, subjects + + +def delete_subject(client): + subjects = get_subjects(client) + value = subjects[1]['subjects'] + id = list(value.keys())[0] + policy_id = builder.get_policy_id_with_subject_assignment() + return client.delete("/policies/{}/subjects/{}".format(policy_id, id)) + + +def delete_subjects_without_perimeter_id(client): + req = client.delete("/subjects/{}".format("")) + return req + + +def test_perimeter_get_subject(): + client = utilities.register_client() + req, subjects = get_subjects(client) + assert req.status_code == 200 assert isinstance(subjects, dict) - key = list(subjects["subjects"].keys())[0] + assert "subjects" in subjects + + +def test_perimeter_add_subject(): + client = utilities.register_client() + req, subjects = add_subjects(client, "testuser") value = list(subjects["subjects"].values())[0] + assert req.status_code == 200 assert "subjects" in subjects - assert key == "1111111111111" - assert value['id'] == "1111111111111" - assert value['name'] == name - assert value["description"] == "description of {}".format(name) - assert value["email"] == "{}@moon".format(name) - return subjects + assert value["name"] is not None + assert value["email"] is not None -def add_subjects_without_name(client, name): +def test_perimeter_add_subject_without_name(): + client = utilities.register_client() data = { - "name": name, - "description": "description of {}".format(name), - "password": "password for {}".format(name), - "email": "{}@moon".format(name) + "name": "", + "description": "description of {}".format(""), + "password": "password for {}".format(""), + "email": "{}@moon".format("") } - req = client.post("/subjects", data=json.dumps(data), + req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) - assert req.status_code == 500 + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" -def delete_subject(client, name): - subjects = get_subjects(client) - for key, value in subjects['subjects'].items(): - if value['name'] == name: - req = client.delete("/subjects/{}".format(key)) - assert req.status_code == 200 - break - subjects = get_subjects(client) - assert name not in [x['name'] for x in subjects["subjects"].values()] +def test_perimeter_add_subject_with_name_contain_spaces(): + client = utilities.register_client() + data = { + "name": "test user", + "description": "description of {}".format("test user"), + "password": "password for {}".format("test user"), + "email": "{}@moon".format("test user") + } + req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_perimeter_delete_subject(): + client = utilities.register_client() + req = delete_subject(client) + assert req.status_code == 200 -def test_subject(): +def test_perimeter_delete_subjects_without_perimeter_id(): client = utilities.register_client() - get_subjects(client) - add_subjects(client, "testuser") - add_subjects_without_name(client, "") - delete_subject(client, "testuser") + req = delete_subjects_without_perimeter_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Subject Unknown" def get_objects(client): req = client.get("/objects") - assert req.status_code == 200 objects = utilities.get_json(req.data) - assert isinstance(objects, dict) - assert "objects" in objects - return objects + return req, objects def add_objects(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) data = { - "name": name, + "name": name + uuid4().hex, "description": "description of {}".format(name), } - req = client.post("/objects", data=json.dumps(data), + req = client.post("/policies/{}/objects/".format(policyId), data=json.dumps(data), headers={'Content-Type': 'application/json'}) - assert req.status_code == 200 objects = utilities.get_json(req.data) + return req, objects + + +def delete_object(client): + objects = get_objects(client) + value = objects[1]['objects'] + id = list(value.keys())[0] + policy_id = builder.get_policy_id_with_object_assignment() + return client.delete("/policies/{}/objects/{}".format(policy_id, id)) + + +def delete_objects_without_perimeter_id(client): + req = client.delete("/objects/{}".format("")) + return req + + +def test_perimeter_get_object(): + client = utilities.register_client() + req, objects = get_objects(client) + assert req.status_code == 200 assert isinstance(objects, dict) - key = list(objects["objects"].keys())[0] + assert "objects" in objects + + +def test_perimeter_add_object(): + client = utilities.register_client() + req, objects = add_objects(client, "testuser") value = list(objects["objects"].values())[0] + assert req.status_code == 200 assert "objects" in objects - assert value['name'] == name - assert value["description"] == "description of {}".format(name) - return objects + assert value['name'] is not None -def delete_objects(client, name): - objects = get_objects(client) - for key, value in objects['objects'].items(): - if value['name'] == name: - req = client.delete("/objects/{}".format(key)) - assert req.status_code == 200 - break - objects = get_objects(client) - assert name not in [x['name'] for x in objects["objects"].values()] +def test_perimeter_add_object_without_name(): + client = utilities.register_client() + data = { + "name": "", + "description": "description of {}".format(""), + } + req = client.post("/policies/{}/objects/".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" -def test_objects(): +def test_perimeter_add_object_with_name_contain_spaces(): client = utilities.register_client() - get_objects(client) - add_objects(client, "testuser") - delete_objects(client, "testuser") + data = { + "name": "test user", + "description": "description of {}".format("test user"), + } + req = client.post("/policies/{}/objects/".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_perimeter_delete_object(): + client = utilities.register_client() + req = delete_object(client) + assert req.status_code == 200 + + +def test_perimeter_delete_objects_without_perimeter_id(): + client = utilities.register_client() + req = delete_objects_without_perimeter_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Object Unknown" def get_actions(client): req = client.get("/actions") - assert req.status_code == 200 actions = utilities.get_json(req.data) - assert isinstance(actions, dict) - assert "actions" in actions - return actions + return req, actions def add_actions(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) data = { - "name": name, + "name": name + uuid4().hex, "description": "description of {}".format(name), } - req = client.post("/actions", data=json.dumps(data), + req = client.post("/policies/{}/actions".format(policyId), data=json.dumps(data), headers={'Content-Type': 'application/json'}) - assert req.status_code == 200 actions = utilities.get_json(req.data) + return req, actions + + +def delete_actions(client): + actions = get_actions(client) + value = actions[1]['actions'] + id = list(value.keys())[0] + policy_id = builder.get_policy_id_with_action_assignment() + return client.delete("/policies/{}/actions/{}".format(policy_id, id)) + + +def delete_actions_without_perimeter_id(client): + req = client.delete("/actions/{}".format("")) + return req + + +def test_perimeter_get_actions(): + client = utilities.register_client() + req, actions = get_actions(client) + assert req.status_code == 200 assert isinstance(actions, dict) - key = list(actions["actions"].keys())[0] + assert "actions" in actions + + +def test_perimeter_add_actions(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser") value = list(actions["actions"].values())[0] + assert req.status_code == 200 assert "actions" in actions - assert value['name'] == name - assert value["description"] == "description of {}".format(name) - return actions + assert value['name'] is not None -def delete_actions(client, name): - actions = get_actions(client) - for key, value in actions['actions'].items(): - if value['name'] == name: - req = client.delete("/actions/{}".format(key)) - assert req.status_code == 200 - break - actions = get_actions(client) - assert name not in [x['name'] for x in actions["actions"].values()] +def test_perimeter_add_actions_without_name(): + client = utilities.register_client() + data = { + "name": "", + "description": "description of {}".format(""), + } + req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_perimeter_add_actions_with_name_contain_spaces(): + client = utilities.register_client() + data = { + "name": "test user", + "description": "description of {}".format("test user"), + } + req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_perimeter_delete_actions(): + client = utilities.register_client() + req = delete_actions(client) + assert req.status_code == 200 -def test_actions(): +def test_perimeter_delete_actions_without_perimeter_id(): client = utilities.register_client() - get_actions(client) - add_actions(client, "testuser") - delete_actions(client, "testuser") + req = delete_actions_without_perimeter_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Action Unknown" diff --git a/moon_manager/tests/unit_python/api/test_policies.py b/moon_manager/tests/unit_python/api/test_policies.py index 4d4e387e..cd50f4c7 100644 --- a/moon_manager/tests/unit_python/api/test_policies.py +++ b/moon_manager/tests/unit_python/api/test_policies.py @@ -1,5 +1,12 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + import json +from uuid import uuid4 import api.utilities as utilities +from helpers import model_helper def get_policies(client): @@ -9,10 +16,12 @@ def get_policies(client): def add_policies(client, name): + req = model_helper.add_model(model_id="mls_model_id"+uuid4().hex) + model_id = list(req.keys())[0] data = { "name": name, "description": "description of {}".format(name), - "model_id": "modelId", + "model_id": model_id, "genre": "genre" } req = client.post("/policies", data=json.dumps(data), @@ -24,9 +33,8 @@ def add_policies(client, name): def delete_policies(client, name): request, policies = get_policies(client) for key, value in policies['policies'].items(): - if value['name'] == name: - req = client.delete("/policies/{}".format(key)) - break + req = client.delete("/policies/{}".format(key)) + break return req @@ -44,16 +52,15 @@ def test_get_policies(): def test_add_policies(): + policy_name = "testuser" + uuid4().hex client = utilities.register_client() - req, policies = add_policies(client, "testuser") + req, policies = add_policies(client, policy_name) assert req.status_code == 200 assert isinstance(policies, dict) value = list(policies["policies"].values())[0] assert "policies" in policies - assert value['name'] == "testuser" - assert value["description"] == "description of {}".format("testuser") - assert value["model_id"] == "modelId" - assert value["genre"] == "genre" + assert value['name'] == policy_name + assert value["description"] == "description of {}".format(policy_name) def test_delete_policies(): @@ -65,5 +72,6 @@ def test_delete_policies(): def test_delete_policies_without_id(): client = utilities.register_client() req = delete_policies_without_id(client) - assert req.status_code == 500 + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' diff --git a/moon_manager/tests/unit_python/api/test_rules.py b/moon_manager/tests/unit_python/api/test_rules.py index 86a3d390..af1501e4 100644 --- a/moon_manager/tests/unit_python/api/test_rules.py +++ b/moon_manager/tests/unit_python/api/test_rules.py @@ -1,5 +1,8 @@ import api.utilities as utilities import json +from helpers import data_builder as builder +from uuid import uuid4 +from helpers import policy_helper def get_rules(client, policy_id): @@ -8,9 +11,45 @@ def get_rules(client, policy_id): return req, rules -def add_rules(client, policy_id): +def add_rules(client): + sub_id, obj_id, act_id, meta_rule_id, policy_id = builder.create_new_policy("sub_cat" + uuid4().hex, + "obj_cat" + uuid4().hex, + "act_cat" + uuid4().hex) + sub_data_id = builder.create_subject_data(policy_id, sub_id) + obj_data_id = builder.create_object_data(policy_id, obj_id) + act_data_id = builder.create_action_data(policy_id, act_id) data = { - "meta_rule_id": "meta_rule_id1", + "meta_rule_id": meta_rule_id, + "rule": [sub_data_id, obj_data_id, act_data_id], + "instructions": ( + {"decision": "grant"}, + ), + "enabled": True + } + req = client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + rules = utilities.get_json(req.data) + return req, rules + + +def add_rules_without_policy_id(client): + data = { + "meta_rule_id": "meta_rule_id", + "rule": ["sub_data_id", "obj_data_id", "act_data_id"], + "instructions": ( + {"decision": "grant"}, + ), + "enabled": True + } + req = client.post("/policies/{}/rules".format(None), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + rules = utilities.get_json(req.data) + return req, rules + + +def add_rules_without_meta_rule_id(client, policy_id): + data = { + "meta_rule_id": "", "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"], "instructions": ( {"decision": "grant"}, @@ -23,6 +62,20 @@ def add_rules(client, policy_id): return req, rules +def add_rules_without_rule(client, policy_id): + data = { + "meta_rule_id": "meta_rule_id1", + "instructions": ( + {"decision": "grant"}, + ), + "enabled": True + } + req = client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + rules = utilities.get_json(req.data) + return req, rules + + def delete_rules(client, policy_id, meta_rule_id): req = client.delete("/policies/{}/rules/{}".format(policy_id, meta_rule_id)) return req @@ -35,24 +88,61 @@ def test_get_rules(): assert req.status_code == 200 assert isinstance(rules, dict) assert "rules" in rules + return req, rules def test_add_rules(): - policy_id = utilities.get_policy_id() client = utilities.register_client() - req, rules = add_rules(client, policy_id) + req, rules = add_rules(client, ) assert req.status_code == 200 - assert isinstance(rules, dict) - value = rules["rules"] - assert "rules" in rules - id = list(value.keys())[0] - assert value[id]["meta_rule_id"] == "meta_rule_id1" -def test_delete_rules(): +def test_add_rules_without_policy_id(): + client = utilities.register_client() + req, rules = add_rules_without_policy_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + +def test_add_rules_without_meta_rule_id(): + policy_id = utilities.get_policy_id() client = utilities.register_client() + req, rules = add_rules_without_meta_rule_id(client, policy_id) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'meta_rule_id', [Empty String]" + + +def test_add_rules_without_rule(): policy_id = utilities.get_policy_id() + client = utilities.register_client() + req, rules = add_rules_without_rule(client, policy_id) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == 'Invalid Key :rule not found' + + +def test_delete_rules_with_invalid_parameters(): + client = utilities.register_client() + rules = delete_rules(client, "", "") + assert rules.status_code == 404 + + +def test_delete_rules_without_policy_id(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy() + sub_data_id = builder.create_subject_data(policy_id, subject_category_id) + obj_data_id = builder.create_object_data(policy_id, object_category_id) + act_data_id = builder.create_action_data(policy_id, action_category_id) + data = { + "meta_rule_id": meta_rule_id, + "rule": [sub_data_id, obj_data_id, act_data_id], + "instructions": ( + {"decision": "grant"}, + ), + "enabled": True + } + client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) req, added_rules = get_rules(client, policy_id) - id = added_rules["rules"]['rules'][0]['id'] - rules = delete_rules(client, policy_id, id) + id = list(added_rules["rules"]["rules"])[0]["id"] + rules = delete_rules(client, None, id) assert rules.status_code == 200 diff --git a/moon_manager/tests/unit_python/api/test_unit_models.py b/moon_manager/tests/unit_python/api/test_unit_models.py new file mode 100644 index 00000000..d754b976 --- /dev/null +++ b/moon_manager/tests/unit_python/api/test_unit_models.py @@ -0,0 +1,186 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import json +import api.utilities as utilities +from helpers import data_builder as builder +from uuid import uuid4 + + +def get_models(client): + req = client.get("/models") + models = utilities.get_json(req.data) + return req, models + + +def add_models(client, name): + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule( + subject_category_name="subject_category"+uuid4().hex, + object_category_name="object_category"+uuid4().hex, action_category_name="action_category"+uuid4().hex, + meta_rule_name="meta_rule" + uuid4().hex) + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [meta_rule_id] + } + req = client.post("/models", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + models = utilities.get_json(req.data) + return req, models + + +def update_model(client, name, model_id): + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule( + subject_category_name="subject_category" + uuid4().hex, + object_category_name="object_category" + uuid4().hex, action_category_name="action_category" + uuid4().hex, + meta_rule_name="meta_rule" + uuid4().hex) + + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [meta_rule_id] + } + req = client.patch("/models/{}".format(model_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + models = utilities.get_json(req.data) + return req, models + + +def add_model_without_meta_rules_ids(client, name): + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [] + } + req = client.post("/models", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + models = utilities.get_json(req.data) + return req, models + + +def update_model_without_meta_rules_ids(client, name): + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [] + } + req = client.patch("/models", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + models = utilities.get_json(req.data) + return req, models + + +def delete_models(client, name): + request, models = get_models(client) + for key, value in models['models'].items(): + if value['name'] == name: + req = client.delete("/models/{}".format(key)) + break + return req + + +def delete_models_without_id(client): + req = client.delete("/models/{}".format("")) + return req + + +def clean_models(): + client = utilities.register_client() + req, models = get_models(client) + for key, value in models['models'].items(): + print(key) + print(value) + client.delete("/models/{}".format(key)) + + +def test_get_models(): + client = utilities.register_client() + req, models = get_models(client) + assert req.status_code == 200 + assert isinstance(models, dict) + assert "models" in models + + +def test_add_models(): + clean_models() + client = utilities.register_client() + req, models = add_models(client, "testuser") + assert req.status_code == 200 + assert isinstance(models, dict) + model_id = list(models["models"])[0] + assert "models" in models + assert models['models'][model_id]['name'] == "testuser" + assert models['models'][model_id]["description"] == "description of {}".format("testuser") + + +def test_delete_models(): + client = utilities.register_client() + req = delete_models(client, "testuser") + assert req.status_code == 200 + + +def test_delete_models_without_id(): + client = utilities.register_client() + req = delete_models_without_id(client) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Model Unknown" + + +def test_add_model_with_empty_user(): + clean_models() + client = utilities.register_client() + req, models = add_models(client, "") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + + +def test_add_model_with_user_contain_space(): + clean_models() + client = utilities.register_client() + req, models = add_models(client, "test user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + + +def test_add_model_without_meta_rules(): + clean_models() + client = utilities.register_client() + req, meta_rules = add_model_without_meta_rules_ids(client, "testuser") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'meta_rules', [Empty Container]" + + +def test_update_model(): + clean_models() + client = utilities.register_client() + req = add_models(client, "testuser") + model_id = list(req[1]['models'])[0] + req_update = update_model(client, "testuser", model_id) + assert req_update[0].status_code == 200 + model_id = list(req_update[1]["models"])[0] + assert req_update[1]["models"][model_id]["meta_rules"][0] is not None + delete_models(client, "testuser") + + +def test_update_meta_rules_without_id(): + clean_models() + client = utilities.register_client() + req_update = update_model(client, "testuser", "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "400: Model Unknown" + + +def test_update_meta_rules_without_user(): + client = utilities.register_client() + req_update = update_model(client, "", "") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]" + + +def test_update_meta_rules_without_meta_rules(): + client = utilities.register_client() + req_update = update_model_without_meta_rules_ids(client, "testuser") + assert req_update[0].status_code == 400 + assert json.loads(req_update[0].data)["message"] == "Key: 'meta_rules', [Empty Container]" diff --git a/moon_manager/tests/unit_python/api/utilities.py b/moon_manager/tests/unit_python/api/utilities.py index 66ca30c5..2e51fec8 100644 --- a/moon_manager/tests/unit_python/api/utilities.py +++ b/moon_manager/tests/unit_python/api/utilities.py @@ -1,5 +1,5 @@ import json - +from uuid import uuid4 def get_json(data): return json.loads(data.decode("utf-8")) @@ -13,14 +13,14 @@ def register_client(): def get_policy_id(): - import api.test_policies as policies - client = register_client() - policy_id = '' - req, policy = policies.get_policies(client) - for id in policy['policies']: - if id: - policy_id = id - break - if not policy_id: - policies.add_policies(client, "testuser") + from helpers import policy_helper + value = { + "name": "test_policy"+uuid4().hex, + "model_id": "", + "genre": "authz", + "description": "test", + } + policy_helper.add_policies(value=value) + req = policy_helper.get_policies() + policy_id = list(req.keys())[0] return policy_id diff --git a/moon_manager/tests/unit_python/conftest.py b/moon_manager/tests/unit_python/conftest.py index 902a41a2..d9899231 100644 --- a/moon_manager/tests/unit_python/conftest.py +++ b/moon_manager/tests/unit_python/conftest.py @@ -187,12 +187,14 @@ def no_requests(monkeypatch): 'DELETE', 'http://keystone:5000/v3/auth/tokens', headers={'X-Subject-Token': "111111111"} ) + + def match_request_text(request): + # request.url may be None, or '' prevents a TypeError. + return 'http://keystone:5000/v3/users?name=testuser' in request.url + m.register_uri( - 'POST', 'http://keystone:5000/v3/users?name=testuser&domain_id=default', - json={"users": {}} - ) - m.register_uri( - 'GET', 'http://keystone:5000/v3/users?name=testuser&domain_id=default', + requests_mock.ANY, '/v3/users', + additional_matcher=match_request_text, json={"users": {}} ) m.register_uri( diff --git a/moon_manager/tests/unit_python/api/__init__.py b/moon_manager/tests/unit_python/helpers/__init__.py index e69de29b..e69de29b 100644 --- a/moon_manager/tests/unit_python/api/__init__.py +++ b/moon_manager/tests/unit_python/helpers/__init__.py diff --git a/moon_manager/tests/unit_python/helpers/assignment_helper.py b/moon_manager/tests/unit_python/helpers/assignment_helper.py new file mode 100644 index 00000000..22a56e38 --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/assignment_helper.py @@ -0,0 +1,49 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +def get_action_assignments(policy_id, action_id=None, category_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_action_assignments("", policy_id, action_id, category_id) + + +def add_action_assignment(policy_id, action_id, category_id, data_id): + from python_moondb.core import PolicyManager + return PolicyManager.add_action_assignment("", policy_id, action_id, category_id, data_id) + + +def delete_action_assignment(policy_id, action_id, category_id, data_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_action_assignment("", policy_id, action_id, category_id, data_id) + + +def get_object_assignments(policy_id, object_id=None, category_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_object_assignments("", policy_id, object_id, category_id) + + +def add_object_assignment(policy_id, object_id, category_id, data_id): + from python_moondb.core import PolicyManager + return PolicyManager.add_object_assignment("", policy_id, object_id, category_id, data_id) + + +def delete_object_assignment(policy_id, object_id, category_id, data_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_object_assignment("", policy_id, object_id, category_id, data_id) + + +def get_subject_assignments(policy_id, subject_id=None, category_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_subject_assignments("", policy_id, subject_id, category_id) + + +def add_subject_assignment(policy_id, subject_id, category_id, data_id): + from python_moondb.core import PolicyManager + return PolicyManager.add_subject_assignment("", policy_id, subject_id, category_id, data_id) + + +def delete_subject_assignment(policy_id, subject_id, category_id, data_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_subject_assignment("", policy_id, subject_id, category_id, data_id) + diff --git a/moon_manager/tests/unit_python/helpers/category_helper.py b/moon_manager/tests/unit_python/helpers/category_helper.py new file mode 100644 index 00000000..6c419ca8 --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/category_helper.py @@ -0,0 +1,40 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +def add_subject_category(cat_id=None, value=None): + from python_moondb.core import ModelManager + category = ModelManager.add_subject_category(user_id=None, category_id=cat_id, value=value) + return category + + +def get_subject_category(cat_id=None): + from python_moondb.core import ModelManager + category = ModelManager.get_subject_categories(user_id=None, category_id=cat_id) + return category + + +def add_object_category(cat_id=None, value=None): + from python_moondb.core import ModelManager + category = ModelManager.add_object_category(user_id=None, category_id=cat_id, value=value) + return category + + +def get_object_category(cat_id=None): + from python_moondb.core import ModelManager + category = ModelManager.get_object_categories(user_id=None, category_id=cat_id) + return category + + +def add_action_category(cat_id=None, value=None): + from python_moondb.core import ModelManager + category = ModelManager.add_action_category(user_id=None, category_id=cat_id, value=value) + return category + + +def get_action_category(cat_id=None): + from python_moondb.core import ModelManager + category = ModelManager.get_action_categories(user_id=None, category_id=cat_id) + return category diff --git a/moon_manager/tests/unit_python/helpers/data_builder.py b/moon_manager/tests/unit_python/helpers/data_builder.py new file mode 100644 index 00000000..2a7c5979 --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/data_builder.py @@ -0,0 +1,209 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from .category_helper import * +from .policy_helper import * +from .data_helper import * +from helpers import model_helper +from .meta_rule_helper import * +import api.utilities as utilities +import json + + +def create_subject_category(name): + subject_category = add_subject_category( + value={"name": name + uuid4().hex, "description": "description 1"}) + return list(subject_category.keys())[0] + + +def create_object_category(name): + object_category = add_object_category( + value={"name": name + uuid4().hex, "description": "description 1"}) + return list(object_category.keys())[0] + + +def create_action_category(name): + action_category = add_action_category( + value={"name": name + uuid4().hex, "description": "description 1"}) + return list(action_category.keys())[0] + + +def create_model(meta_rule_id, model_name="test_model"): + value = { + "name": model_name + uuid4().hex, + "description": "test", + "meta_rules": [meta_rule_id] + + } + return value + + +def create_policy(model_id, policy_name="policy_1"): + value = { + "name": policy_name, + "model_id": model_id, + "genre": "authz", + "description": "test", + } + return value + + +def create_pdp(policies_ids): + value = { + "name": "test_pdp", + "security_pipeline": policies_ids, + "keystone_project_id": "keystone_project_id1", + "description": "...", + } + return value + + +def create_new_policy(subject_category_name="subjectCategory", object_category_name="objectCategory", + action_category_name="actionCategory", + model_name="test_model" + uuid4().hex, policy_name="policy_1" + uuid4().hex, + meta_rule_name="meta_rule1" + uuid4().hex): + subject_category_id, object_category_id, action_category_id, meta_rule_id = create_new_meta_rule( + subject_category_name=subject_category_name + uuid4().hex, + object_category_name=object_category_name + uuid4().hex, + action_category_name=action_category_name + uuid4().hex, meta_rule_name=meta_rule_name + uuid4().hex) + model = model_helper.add_model(value=create_model(meta_rule_id, model_name)) + model_id = list(model.keys())[0] + value = create_policy(model_id, policy_name) + policy = add_policies(value=value) + assert policy + policy_id = list(policy.keys())[0] + return subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id + + +def create_new_meta_rule(subject_category_name="subjectCategory", object_category_name="objectCategory", + action_category_name="actionCategory", + meta_rule_name="meta_rule1" + uuid4().hex): + subject_category_id = create_subject_category(subject_category_name) + object_category_id = create_object_category(object_category_name) + action_category_id = create_action_category(action_category_name) + value = {"name": meta_rule_name, + "algorithm": "name of the meta rule algorithm", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + meta_rule = add_meta_rule(value=value) + return subject_category_id, object_category_id, action_category_id, list(meta_rule.keys())[0] + + +def create_subject(policy_id): + value = { + "name": "testuser" + uuid4().hex, + "description": "test", + } + subject = add_subject(policy_id=policy_id, value=value) + return list(subject.keys())[0] + + +def create_object(policy_id): + value = { + "name": "testobject" + uuid4().hex, + "description": "test", + } + object = add_object(policy_id=policy_id, value=value) + return list(object.keys())[0] + + +def create_action(policy_id): + value = { + "name": "testaction" + uuid4().hex, + "description": "test", + } + action = add_action(policy_id=policy_id, value=value) + return list(action.keys())[0] + + +def create_subject_data(policy_id, category_id): + value = { + "name": "subject-security-level", + "description": {"low": "", "medium": "", "high": ""}, + } + subject_data = add_subject_data(policy_id=policy_id, category_id=category_id, value=value).get('data') + assert subject_data + return list(subject_data.keys())[0] + + +def create_object_data(policy_id, category_id): + value = { + "name": "object-security-level", + "description": {"low": "", "medium": "", "high": ""}, + } + object_data = add_object_data(policy_id=policy_id, category_id=category_id, value=value).get('data') + return list(object_data.keys())[0] + + +def create_action_data(policy_id, category_id): + value = { + "name": "action-type", + "description": {"vm-action": "", "storage-action": "", }, + } + action_data = add_action_data(policy_id=policy_id, category_id=category_id, value=value).get('data') + return list(action_data.keys())[0] + + +def get_policy_id_with_subject_assignment(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + subject_id = create_subject(policy_id) + data_id = create_subject_data(policy_id=policy_id, category_id=subject_category_id) + + data = { + "id": subject_id, + "category_id": subject_category_id, + "data_id": data_id + } + client.post("/policies/{}/subject_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + return policy_id + + +def get_policy_id_with_object_assignment(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + object_id = create_object(policy_id) + data_id = create_object_data(policy_id=policy_id, category_id=object_category_id) + + data = { + "id": object_id, + "category_id": object_category_id, + "data_id": data_id + } + + client.post("/policies/{}/object_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + return policy_id + + +def get_policy_id_with_action_assignment(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + action_id = create_action(policy_id) + data_id = create_action_data(policy_id=policy_id, category_id=action_category_id) + + data = { + "id": action_id, + "category_id": action_category_id, + "data_id": data_id + } + client.post("/policies/{}/action_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + return policy_id diff --git a/moon_manager/tests/unit_python/helpers/data_helper.py b/moon_manager/tests/unit_python/helpers/data_helper.py new file mode 100644 index 00000000..da6b9376 --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/data_helper.py @@ -0,0 +1,99 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +def get_action_data(policy_id, data_id=None, category_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_action_data("", policy_id, data_id, category_id) + + +def add_action_data(policy_id, data_id=None, category_id=None, value=None): + from python_moondb.core import PolicyManager + return PolicyManager.add_action_data("", policy_id, data_id, category_id, value) + + +def delete_action_data(policy_id, data_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_action_data("", policy_id, data_id) + + +def get_object_data(policy_id, data_id=None, category_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_object_data("", policy_id, data_id, category_id) + + +def add_object_data(policy_id, data_id=None, category_id=None, value=None): + from python_moondb.core import PolicyManager + return PolicyManager.add_object_data("", policy_id, data_id, category_id, value) + + +def delete_object_data(policy_id, data_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_object_data("", policy_id, data_id) + + +def get_subject_data(policy_id, data_id=None, category_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_subject_data("", policy_id, data_id, category_id) + + +def add_subject_data(policy_id, data_id=None, category_id=None, value=None): + from python_moondb.core import PolicyManager + return PolicyManager.set_subject_data("", policy_id, data_id, category_id, value) + + +def delete_subject_data(policy_id, data_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_subject_data("", policy_id, data_id) + + +def get_actions(policy_id, perimeter_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_actions("", policy_id, perimeter_id) + + +def add_action(policy_id, perimeter_id=None, value=None): + from python_moondb.core import PolicyManager + return PolicyManager.add_action("", policy_id, perimeter_id, value) + + +def delete_action(policy_id, perimeter_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_action("", policy_id, perimeter_id) + + +def get_objects(policy_id, perimeter_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_objects("", policy_id, perimeter_id) + + +def add_object(policy_id, perimeter_id=None, value=None): + from python_moondb.core import PolicyManager + return PolicyManager.add_object("", policy_id, perimeter_id, value) + + +def delete_object(policy_id, perimeter_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_object("", policy_id, perimeter_id) + + +def get_subjects(policy_id, perimeter_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_subjects("", policy_id, perimeter_id) + + +def add_subject(policy_id, perimeter_id=None, value=None): + from python_moondb.core import PolicyManager + return PolicyManager.add_subject("", policy_id, perimeter_id, value) + + +def delete_subject(policy_id, perimeter_id): + from python_moondb.core import PolicyManager + PolicyManager.delete_subject("", policy_id, perimeter_id) + + +def get_available_metadata(policy_id): + from python_moondb.core import PolicyManager + return PolicyManager.get_available_metadata("", policy_id) diff --git a/moon_manager/tests/unit_python/helpers/meta_rule_helper.py b/moon_manager/tests/unit_python/helpers/meta_rule_helper.py new file mode 100644 index 00000000..e882706b --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/meta_rule_helper.py @@ -0,0 +1,49 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from helpers import data_builder as builder +from uuid import uuid4 + + +def set_meta_rule(meta_rule_id, value=None): + from python_moondb.core import ModelManager + if not value: + action_category_id = builder.create_action_category("action_category_id1"+uuid4().hex) + subject_category_id = builder.create_subject_category("subject_category_id1"+uuid4().hex) + object_category_id = builder.create_object_category("object_category_id1"+uuid4().hex) + value = { + "name": "MLS_meta_rule", + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + return ModelManager.set_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value) + + +def add_meta_rule(meta_rule_id=None, value=None): + from python_moondb.core import ModelManager + if not value: + action_category_id = builder.create_action_category("action_category_id1"+uuid4().hex) + subject_category_id = builder.create_subject_category("subject_category_id1"+uuid4().hex) + object_category_id = builder.create_object_category("object_category_id1"+uuid4().hex) + value = { + "name": "MLS_meta_rule"+uuid4().hex, + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + return ModelManager.add_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value) + + +def get_meta_rules(meta_rule_id=None): + from python_moondb.core import ModelManager + return ModelManager.get_meta_rules(user_id=None, meta_rule_id=meta_rule_id) + + +def delete_meta_rules(meta_rule_id=None): + from python_moondb.core import ModelManager + ModelManager.delete_meta_rule(user_id=None, meta_rule_id=meta_rule_id) diff --git a/moon_manager/tests/unit_python/helpers/model_helper.py b/moon_manager/tests/unit_python/helpers/model_helper.py new file mode 100644 index 00000000..d2ffb85b --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/model_helper.py @@ -0,0 +1,51 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from helpers import data_builder as builder +from uuid import uuid4 + + +def get_models(model_id=None): + from python_moondb.core import ModelManager + return ModelManager.get_models(user_id=None, model_id=model_id) + + +def add_model(model_id=None, value=None): + from python_moondb.core import ModelManager + if not value: + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule( + subject_category_name="subject_category1"+uuid4().hex, + object_category_name="object_category1"+uuid4().hex, + action_category_name="action_category1"+uuid4().hex) + name = "MLS" if model_id is None else "MLS " + model_id + value = { + "name": name, + "description": "test", + "meta_rules": [meta_rule_id] + } + return ModelManager.add_model(user_id=None, model_id=model_id, value=value) + + +def delete_models(uuid=None, name=None): + from python_moondb.core import ModelManager + if not uuid: + for model_id, model_value in get_models(): + if name == model_value['name']: + uuid = model_id + break + ModelManager.delete_model(user_id=None, model_id=uuid) + + +def delete_all_models(): + from python_moondb.core import ModelManager + models_values = get_models() + print(models_values) + for model_id, model_value in models_values.items(): + ModelManager.delete_model(user_id=None, model_id=model_id) + + +def update_model(model_id=None, value=None): + from python_moondb.core import ModelManager + return ModelManager.update_model(user_id=None, model_id=model_id, value=value) diff --git a/moon_manager/tests/unit_python/helpers/pdp_helper.py b/moon_manager/tests/unit_python/helpers/pdp_helper.py new file mode 100644 index 00000000..3d169b06 --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/pdp_helper.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +def update_pdp(pdp_id, value): + from python_moondb.core import PDPManager + return PDPManager.update_pdp("", pdp_id, value) + + +def delete_pdp(pdp_id): + from python_moondb.core import PDPManager + PDPManager.delete_pdp("", pdp_id) + + +def add_pdp(pdp_id=None, value=None): + from python_moondb.core import PDPManager + return PDPManager.add_pdp("", pdp_id, value) + + +def get_pdp(pdp_id=None): + from python_moondb.core import PDPManager + return PDPManager.get_pdp("", pdp_id) diff --git a/moon_manager/tests/unit_python/helpers/policy_helper.py b/moon_manager/tests/unit_python/helpers/policy_helper.py new file mode 100644 index 00000000..c932ee3a --- /dev/null +++ b/moon_manager/tests/unit_python/helpers/policy_helper.py @@ -0,0 +1,61 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +def get_policies(): + from python_moondb.core import PolicyManager + return PolicyManager.get_policies("admin") + + +def add_policies(policy_id=None, value=None): + from python_moondb.core import PolicyManager + if not value: + value = { + "name": "test_policy", + "model_id": "", + "genre": "authz", + "description": "test", + } + return PolicyManager.add_policy("admin", policy_id=policy_id, value=value) + + +def delete_policies(uuid=None, name=None): + from python_moondb.core import PolicyManager + if not uuid: + for policy_id, policy_value in get_policies(): + if name == policy_value['name']: + uuid = policy_id + break + PolicyManager.delete_policy("admin", uuid) + + +def update_policy(policy_id, value): + from python_moondb.core import PolicyManager + return PolicyManager.update_policy("admin", policy_id, value) + + +def get_policy_from_meta_rules(meta_rule_id): + from python_moondb.core import PolicyManager + return PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id) + + +def get_rules(policy_id=None, meta_rule_id=None, rule_id=None): + from python_moondb.core import PolicyManager + return PolicyManager.get_rules("", policy_id, meta_rule_id, rule_id) + + +def add_rule(policy_id=None, meta_rule_id=None, value=None): + from python_moondb.core import PolicyManager + if not value: + value = { + "rule": ("high", "medium", "vm-action"), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + return PolicyManager.add_rule("", policy_id, meta_rule_id, value) + + +def delete_rule(policy_id=None, rule_id=None): + from python_moondb.core import PolicyManager + PolicyManager.delete_rule("", policy_id, rule_id) diff --git a/moon_manager/tests/unit_python/requirements.txt b/moon_manager/tests/unit_python/requirements.txt index 21975ce3..6c6e5bb8 100644 --- a/moon_manager/tests/unit_python/requirements.txt +++ b/moon_manager/tests/unit_python/requirements.txt @@ -2,4 +2,4 @@ flask flask_cors flask_restful python_moondb -python_moonutilities
\ No newline at end of file +python_moonutilities |