aboutsummaryrefslogtreecommitdiffstats
path: root/moon_manager
diff options
context:
space:
mode:
authorfrancois.cellier <francois.cellier@orange.com>2018-02-27 13:51:25 +0100
committerfrancois.cellier <francois.cellier@orange.com>2018-03-08 14:30:45 +0100
commit7343cf25ad890e18b2f5b8d35c6acfc821dfd5ec (patch)
tree635e01c4a17326a05c4ec40b3df48d2d33a0de59 /moon_manager
parentc5104c3308f7aa6cb44a678a25c553c027c249be (diff)
Add import and export pdps
Change-Id: I2c9b1f2b86af862887df4b890cd8b11db7c308ee
Diffstat (limited to 'moon_manager')
-rw-r--r--moon_manager/moon_manager/__init__.py2
-rw-r--r--moon_manager/moon_manager/api/base_exception.py18
-rw-r--r--moon_manager/moon_manager/api/json_export.py225
-rw-r--r--moon_manager/moon_manager/api/json_import.py518
-rw-r--r--moon_manager/moon_manager/api/json_utils.py255
-rw-r--r--moon_manager/moon_manager/http_server.py61
-rw-r--r--moon_manager/moon_manager/server.py1
-rw-r--r--moon_manager/tests/functional_pod/json/mls.json89
-rw-r--r--moon_manager/tests/functional_pod/json/rbac.json85
-rw-r--r--moon_manager/tests/functional_pod/test_manager.py39
-rw-r--r--moon_manager/tests/unit_python/api/__init__.py0
-rw-r--r--moon_manager/tests/unit_python/api/import_export_utilities.py181
-rw-r--r--moon_manager/tests/unit_python/api/meta_data_test.py2
-rw-r--r--moon_manager/tests/unit_python/api/test_assignemnt.py18
-rw-r--r--moon_manager/tests/unit_python/api/test_data.py21
-rw-r--r--moon_manager/tests/unit_python/api/test_export.py284
-rw-r--r--moon_manager/tests/unit_python/api/test_import.py515
-rw-r--r--moon_manager/tests/unit_python/api/test_rules.py1
-rw-r--r--moon_manager/tests/unit_python/api/utilities.py2
19 files changed, 2282 insertions, 35 deletions
diff --git a/moon_manager/moon_manager/__init__.py b/moon_manager/moon_manager/__init__.py
index 85c245e0..af7fced5 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.0"
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/json_export.py b/moon_manager/moon_manager/api/json_export.py
new file mode 100644
index 00000000..feb4fde2
--- /dev/null
+++ b/moon_manager/moon_manager/api/json_export.py
@@ -0,0 +1,225 @@
+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()
+ JsonUtils.convert_ids_to_names([ids[0]], rule_description, "subject_data", "subject_data", PolicyManager, self._user_id, policy_key)
+ JsonUtils.convert_ids_to_names([ids[1]], rule_description, "object_data", "object_data", PolicyManager, self._user_id, policy_key)
+ JsonUtils.convert_ids_to_names([ids[2]], rule_description, "action_data", "action_data", PolicyManager, self._user_id, policy_key)
+ rule_dict["rule"] = rule_description
+ logger.info("Exporting rule {}".format(rule_dict))
+ 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]["value"], data_dict, "name", str)
+ JsonUtils.copy_field_if_exists(data_group["data"][data_key]["value"], 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..a048baee
--- /dev/null
+++ b/moon_manager/moon_manager/api/json_import.py
@@ -0,0 +1,518 @@
+# 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 _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()
+ json_rule_to_use = 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"])
+ logger.info(json_rule_to_use)
+ for json_subject_id in json_subject_ids["subject"]:
+ for json_object_id in json_object_ids["object"]:
+ for json_action_id in json_action_ids["action"]:
+ json_to_use["rule"] = [json_subject_id, json_object_id, json_action_id]
+ try:
+ logger.info("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()
+ logger.info("Input meta rule : {}".format(json_meta_rule))
+ 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.info("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.info("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.info("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))
+ logger.info("json_item_data {}".format(json_item_data))
+ 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_name_to_id(json_item_data, json_policy, "policy", "policy_id", "policy",
+ PolicyManager, self._user_id, field_mandatory=len(mandatory_policy_ids) == 0)
+ logger.info("json_policy {}".format(json_policy))
+ json_category = dict()
+ JsonUtils.convert_name_to_id(json_item_data, json_category, "category", "category_id", type_element+"_category",
+ ModelManager, self._user_id)
+ logger.info("json_category {}".format(json_category))
+ policy_id = None
+ if "policy_id" in json_policy:
+ policy_id = json_policy["policy_id"]
+
+ 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:
+ # existing_datas = get_method(self._user_id, policy_id,category_id=category_id)
+ # logger.info(existing_datas)
+ logger.info("Adding / updating a {} data with policy id {} and category id {} from json {}".format(type_element, policy_id, category_id, json_to_use))
+ data = import_method(self._user_id, policy_id, category_id=category_id, value=json_to_use)
+ logger.info("Added / updated {} data : {}".format(type_element, data))
+ except exceptions.PolicyUnknown:
+ raise UnknownPolicy("Unknown policy with id {}".format(policy_id))
+ except Exception as e:
+ raise BaseException(str(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:
+ logger.info("Adding a {} category from json {}".format(type_element, json_to_use))
+ category = import_method(self._user_id, existing_id, json_to_use)
+ logger.info("Added category {}".format(category))
+ except (exceptions.SubjectCategoryExisting, exceptions.ObjectCategoryExisting, exceptions.ActionCategoryExisting):
+ # it already exists: do nothing
+ logger.info("Ignored {} category with name {} is already in the database".format(type_element, json_to_use["name"]))
+ except Exception as e:
+ logger.info("Error while importing the category : {}".format(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
+ if key is None:
+ logger.info("Adding a {} from json {} to the policy with id {}".format(type_element, json_without_policy_name, policy_id))
+ else:
+ logger.info("Updating a {} from json {} to the policy with id {}".format(type_element, json_without_policy_name, policy_id))
+ element = import_method(self._user_id, policy_id, perimeter_id=key, value=json_without_policy_name)
+ logger.info("Added / updated {} : {}".format(type_element, element))
+
+ except exceptions.PolicyUnknown:
+ raise UnknownPolicy("Unknown policy when adding a {}!".format(type_element))
+ except Exception as 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
+ logger.info(policies)
+ 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:
+ 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.info("Creating policy {} ".format(json_without_model_name))
+ added_policy = PolicyManager.add_policy(self._user_id, None, json_without_model_name)
+ logger.info("Added policy {}".format(added_policy))
+ if policy_mandatory is True:
+ keys = list(added_policy.keys())
+ policy_mandatory_ids.append(keys[0])
+ elif policy_override is True:
+ logger.info("Updating policy {} ".format(json_without_model_name))
+ updated_policy = PolicyManager.update_policy(self._user_id, policy_id, json_without_model_name)
+ logger.info("Updated policy {}".format(updated_policy))
+ 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.info("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
+
+ logger.info("model in db".format(model_in_db))
+ # 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("Unknwon model ")
+
+ json_key = dict()
+ JsonUtils.convert_names_to_ids(json_model, json_key, "meta_rules", "meta_rule_id", "meta_rule", ModelManager, self._user_id)
+ logger.info("json_key {}".format(json_key))
+ 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)
+
+ logger.info("Updating model with id {} : {} ".format(model_id, model_in_db))
+ 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:
+ logger.info("model_in_db {}".format(model_in_db))
+ # JsonUtils.convert_names_to_ids(model_in_db, json_without_new_metarules, "meta_rules", "meta_rule_id", "meta_rule", ModelManager, self._user_id)
+ 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.info("Creating model {} ".format(json_without_new_metarules))
+ ModelManager.add_model(self._user_id, None, json_without_new_metarules)
+ elif model_override is True:
+ logger.info("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.info("Importing {} file...".format(file))
+ json_content = json.load(file)
+ else:
+ json_content = request.json
+ logger.info("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/http_server.py b/moon_manager/moon_manager/http_server.py
index a98cab43..28d77ea0 100644
--- a/moon_manager/moon_manager/http_server.py
+++ b/moon_manager/moon_manager/http_server.py
@@ -2,10 +2,12 @@
# 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 werkzeug.exceptions import HTTPException
+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 flask_restful
import logging
import sqlalchemy.exc
import time
@@ -21,7 +23,10 @@ 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.base_exception import BaseException
+from moon_manager.api.json_export import JsonExport
+from python_moonutilities import configuration
from python_moondb.core import PDPManager
@@ -33,7 +38,7 @@ __API__ = (
Subjects, Objects, Actions, Rules,
SubjectAssignments, ObjectAssignments, ActionAssignments,
SubjectData, ObjectData, ActionData,
- Models, Policies, PDP, Slaves
+ Models, Policies, PDP, Slaves, JsonImport, JsonExport
)
@@ -105,31 +110,51 @@ class Root(Resource):
}
-class HTTPServer(Server):
+class CustomApi(Api):
+
+ def handle_error(self, e):
+ try:
+ error_message = dumps({'message': str(e)})
+ logger.error(error_message)
+ return make_response(error_message, e.code)
+ except Exception as e2: # unhandled exception in the api...
+ logger.error(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)
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)
+ # self.__hook_errors()
+
+ #def __hook_errors(self):
+ # def get_500_json(e):
+ # logger.error("get_500_json")
+ # return jsonify({"result": False, "code": 500, "description": str(e)}), 500
+ # self.app.register_error_handler(JsonUtilsException, get_500_json)
+ # self.app.register_error_handler(JsonImportException, get_500_json)
+ # self.app.register_error_handler(UnknownName, get_500_json)
+
+ # 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(500, lambda e: get_500_json)
+ # 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, '/')
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..d2a5c67c
--- /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": "", "policy": {"name" :"MLS policy example"}, "category": {"name": "subject-security-level"}},
+ { "name":"medium", "description": "", "policy": {"name" :"MLS policy example"}, "category": {"name": "subject-security-level"}},
+ { "name":"high", "description": "", "policy": {"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": "", "policy": {"name" :"MLS policy example"}, "category": {"name": "object-security-level"}},
+ { "name":"medium", "description": "", "policy": {"name" :"MLS policy example"}, "category": {"name": "object-security-level"}},
+ { "name":"high", "description": "", "policy": {"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": "", "policy": {"name": "MLS policy example"}, "category": {"name": "action-type"}},
+ {"name":"storage-action", "description": "", "policy": {"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..eddbb654
--- /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": "", "policy": {"name" :"RBAC policy example"}, "category": {"name": "role"}},
+ { "name":"employee", "description": "", "policy": {"name" :"RBAC policy example"}, "category": {"name": "role"}},
+ { "name":"*", "description": "", "policy": {"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": "", "policy": {"name" :"RBAC policy example"}, "category": {"name": "id"}},
+ { "name":"vm1", "description": "", "policy": {"name" :"RBAC policy example"}, "category": {"name": "id"}},
+ { "name":"*", "description": "", "policy": {"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": "", "policy": {"name": "RBAC policy example"}, "category": {"name": "action-type"}},
+ {"name":"*", "description": "", "policy": {"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/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/unit_python/api/__init__.py b/moon_manager/tests/unit_python/api/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/moon_manager/tests/unit_python/api/__init__.py
+++ /dev/null
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..15c3e333
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/import_export_utilities.py
@@ -0,0 +1,181 @@
+import api.utilities as utilities
+import api.test_models as test_models
+import api.test_policies as test_policies
+import api.test_perimeter as test_perimeter
+import api.meta_data_test as test_categories
+import api.test_data as test_data
+import api.meta_rules_test as test_meta_rules
+import api.test_assignemnt as test_assignments
+import api.test_rules as test_rules
+
+def clean_models(client):
+ req, models = test_models.get_models(client)
+ for key in models["models"]:
+ client.delete("/models/{}".format(key))
+ print("deleted model with id {}".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
+ print("deleted policy with id {}".format(key))
+
+
+def clean_subjects(client):
+ subjects = test_perimeter.get_subjects(client)
+ for key in subjects["subjects"]:
+ subject = subjects["subjects"][key]
+ policy_keys = subject["policy_list"]
+ for policy_key in policy_keys:
+ client.delete("/policies/{}/subjects/{}".format(policy_key,key))
+ client.delete("/subjects/{}".format(key))
+ print("deleted subject with id {}".format(key))
+
+
+def clean_objects(client):
+ objects = test_perimeter.get_objects(client)
+ for key in objects["objects"]:
+ object_ = objects["objects"][key]
+ policy_keys = object_["policy_list"]
+ for policy_key in policy_keys:
+ print("/policies/{}/objects/{}".format(policy_key, key))
+ req = client.delete("/policies/{}/objects/{}".format(policy_key, key))
+ client.delete("/objects/{}".format(key))
+ print("deleted object with id {}".format(key))
+
+
+def clean_actions(client):
+ actions = test_perimeter.get_actions(client)
+ for key in actions["actions"]:
+ action = actions["actions"][key]
+ policy_keys = action["policy_list"]
+ for policy_key in policy_keys:
+ client.delete("/policies/{}/actions/{}".format(policy_key, key))
+ client.delete("/actions/{}".format(key))
+ print("deleted action with id {}".format(key))
+
+
+def clean_subject_categories(client):
+ req, categories = test_categories.get_subject_categories(client)
+ print(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)
+ 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)
+ for key in categories["action_categories"]:
+ client.delete("/action_categories/{}".format(key))
+
+
+def clean_subject_data(client):
+ req, policies = test_policies.get_policies(client)
+ for policy_key in policies["policies"]:
+ req, data = test_data.get_subject_data(client, policy_id=policy_key)
+ print(data)
+ for key in data["subject_data"]:
+ 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)
+ print(data)
+ 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:
+ print(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:
+ req = 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:
+ req = 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:
+ req = 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)
+ print(rules)
+ 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_categories(client)
+ clean_object_categories(client)
+ clean_action_categories(client)
+
+ clean_subject_data(client)
+ clean_object_data(client)
+ clean_action_data(client)
+
+ clean_policies(client)
+ clean_models(client)
+ clean_actions(client)
+ clean_objects(client)
+ clean_subjects(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..0d67a8cd 100644
--- a/moon_manager/tests/unit_python/api/meta_data_test.py
+++ b/moon_manager/tests/unit_python/api/meta_data_test.py
@@ -193,4 +193,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/test_assignemnt.py b/moon_manager/tests/unit_python/api/test_assignemnt.py
index 08688e04..9fd83857 100644
--- a/moon_manager/tests/unit_python/api/test_assignemnt.py
+++ b/moon_manager/tests/unit_python/api/test_assignemnt.py
@@ -28,15 +28,6 @@ def delete_subject_assignment(client, policy_id):
return req
-def test_get_subject_assignment():
- policy_id = utilities.get_policy_id()
- client = utilities.register_client()
- req, subject_assignment = get_subject_assignment(client, policy_id)
- 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()
client = utilities.register_client()
@@ -51,6 +42,15 @@ def test_add_subject_assignment():
assert value[id]['subject_id'] == "id1"
+def test_get_subject_assignment():
+ policy_id = utilities.get_policy_id()
+ client = utilities.register_client()
+ req, subject_assignment = get_subject_assignment(client, policy_id)
+ assert req.status_code == 200
+ assert isinstance(subject_assignment, dict)
+ assert "subject_assignments" in subject_assignment
+
+
def test_delete_subject_assignment():
client = utilities.register_client()
policy_id = utilities.get_policy_id()
diff --git a/moon_manager/tests/unit_python/api/test_data.py b/moon_manager/tests/unit_python/api/test_data.py
index 714414bb..f636aaa5 100644
--- a/moon_manager/tests/unit_python/api/test_data.py
+++ b/moon_manager/tests/unit_python/api/test_data.py
@@ -5,8 +5,11 @@ import json
# 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
@@ -60,8 +63,11 @@ def test_delete_subject_data():
# 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
@@ -115,8 +121,11 @@ def test_delete_object_data():
# 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
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..25097180
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_export.py
@@ -0,0 +1,284 @@
+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", "policy": {"name": "test policy"}, "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "test object data", "description": "object data description", "policy": {"name": "test policy"}, "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "test action data", "description": "action data description", "policy": {"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", "policy": {"name": "test policy"}, "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "test object data", "description": "object data description", "policy": {"name": "test policy"}, "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "test action data", "description": "action data description", "policy": {"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", "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_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "test subject data"}]}],
+ "object_assignments": [{"object": {"name": "test object"}, "category": {"name": "test object categories"}, "assignments": [{"name": "test object data"}]}],
+ "action_assignments": [{"action": {"name": "test action"}, "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", "policy": {"name": "test policy"}, "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "test object data", "description": "object data description", "policy": {"name": "test policy"}, "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "test action data", "description": "action data description", "policy": {"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", "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_assignments": [{"subject": {"name": "testuser"}, "category": {"name": "test subject categories"}, "assignments": [{"name": "test subject data"}]}],
+ "object_assignments": [{"object": {"name": "test object"}, "category": {"name": "test object categories"}, "assignments": [{"name": "test object data"}]}],
+ "action_assignments": [{"action": {"name": "test action"}, "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)
+
+ print(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)
+
+ print(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)
+
+ print(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
+ #TODO change this after bug fix on extra
+ if False:
+ 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)
+ print(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)
+ print(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)
+ print(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
+ 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"
+
+
+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)
+ print(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"] == True
+ 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..ef2267ed
--- /dev/null
+++ b/moon_manager/tests/unit_python/api/test_import.py
@@ -0,0 +1,515 @@
+import api.utilities as utilities
+import api.test_models as test_models
+import api.test_policies as test_policies
+import api.test_perimeter as test_perimeter
+import api.meta_data_test as test_categories
+import api.test_data as test_data
+import api.meta_rules_test 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": "", "policy": {}, "category": {}}]},
+ {"subject_data": [{"name": "not valid subject data", "description": "", "policy": {}, "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", "policy": {}, "category": {"name": "test subject categories"}}]},
+ {"subject_data": [{"name": "valid subject data", "description": "description", "policy": {"name": "test policy"}, "category": {"name": "test subject categories"}}]},
+ {"subject_data": [{"name": "valid subject data", "description": "new description", "policy": {"name": "test other policy"}, "category": {"name": "test subject categories"}}]}]
+
+OBJECT_DATA = [{"object_data": [{"name": "not valid object data", "description": "", "policy": {}, "category": {}}]},
+ {"object_data": [{"name": "not valid object data", "description": "", "policy": {}, "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", "policy": {}, "category": {"name": "test object categories"}}]},
+ {"object_data": [{"name": "valid object data", "description": "description", "policy": {"name": "test policy"}, "category": {"name": "test object categories"}}]},
+ {"object_data": [{"name": "valid object data", "description": "new description", "policy": {"name": "test other policy"}, "category": {"name": "test object categories"}}]}]
+
+
+ACTION_DATA = [{"action_data": [{"name": "not valid action data", "description": "", "policy": {}, "category": {}}]},
+ {"action_data": [{"name": "not valid action data", "description": "", "policy": {}, "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", "policy": {}, "category": {"name": "test action categories"}}]},
+ {"action_data": [{"name": "valid action data", "description": "description", "policy": {"name": "test policy"}, "category": {"name": "test action categories"}}]},
+ {"action_data": [{"name": "valid action data", "description": "new description", "policy": {"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", "policy": {"name": "test policy"}, "category": {"name": "test subject categories"}}],
+ "object_data": [{"name": "object data", "description": "test object data", "policy": {"name": "test policy"}, "category": {"name": "test object categories"}}],
+ "action_data": [{"name": "action data", "description": "test action data", "policy": {"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 as e:
+ 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
+ get_method = test_perimeter.get_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
+ get_method = test_perimeter.get_objects
+ clean_method = import_export_utilities.clean_objects
+ name = "test object"
+ key_extra = "test"
+ value_extra = "test extra"
+ else:
+ elements = ACTIONS
+ get_method = test_perimeter.get_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
+ print("counter {}".format(counter))
+ 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:
+ print(str(e))
+ assert False
+ #assert counter < 2 #  this is an expected failure
+ #continue
+
+ assert data == "Import ok !"
+ get_elements = get_method(client)
+ get_elements = get_elements[type_element + "s"]
+
+ assert len(list(get_elements.keys())) == 1
+ values = list(get_elements.values())
+ assert values[0]["name"] == name
+ print(values[0])
+ if counter == 2 or counter == 4:
+ assert values[0]["description"] == "description of the " + type_element
+ print(values[0])
+ #assert not values[0]["extra"]
+ if counter == 3:
+ #TODO uncomment this if update shall be done through import !
+ #assert values[0]["description"] == "new description of the " + type_element
+ #assert values[0]["extra"][key_extra] == value_extra
+ assert True
+
+ # 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]
+ print(meta_rules)
+ 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:
+ print(data)
+ print(req)
+ 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"]
+ policy_key = rules["policy_id"]
+ rules = rules["rules"]
+ print(rules)
+ assert len(rules) == 1
+ rules = rules[0]
+ assert rules["enabled"] == True
+ assert rules["instructions"]["decision"] == "grant"
+
+ req, meta_rules = test_meta_rules.get_meta_rules(client)
+ print(meta_rules)
+ 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
+ print(counter)
+ 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"]
+ print("categories {}".format(categories))
+ print("policies {}".format(policies))
+ print("data in import {}".format(element))
+ case_tested = False
+ for policy_key in policies.keys():
+ print("policy in test {}".format(policy_key))
+ policy = policies[policy_key]
+ print("policy {}".format(policy))
+ for category_key in categories:
+ print("category in test {}".format(category_key))
+ print("looking for {} data with policy {} and category {}".format(type_element, policy_key,category_key))
+ 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"]
+ print("test")
+ if len(get_elements[0]["data"]) == 0:
+ print("test2")
+ continue
+
+ print("get_elements {}".format(get_elements))
+
+ 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"]
+ print(el)
+ 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]]
+ print(el)
+ 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) \ No newline at end of file
diff --git a/moon_manager/tests/unit_python/api/test_rules.py b/moon_manager/tests/unit_python/api/test_rules.py
index 86a3d390..0b302494 100644
--- a/moon_manager/tests/unit_python/api/test_rules.py
+++ b/moon_manager/tests/unit_python/api/test_rules.py
@@ -35,6 +35,7 @@ def test_get_rules():
assert req.status_code == 200
assert isinstance(rules, dict)
assert "rules" in rules
+ return req, rules
def test_add_rules():
diff --git a/moon_manager/tests/unit_python/api/utilities.py b/moon_manager/tests/unit_python/api/utilities.py
index 66ca30c5..ce897619 100644
--- a/moon_manager/tests/unit_python/api/utilities.py
+++ b/moon_manager/tests/unit_python/api/utilities.py
@@ -21,6 +21,8 @@ def get_policy_id():
if id:
policy_id = id
break
+ print("policy id {}".format(policy_id))
if not policy_id:
policies.add_policies(client, "testuser")
+ policy_id = get_policy_id()
return policy_id