From 7bb53c64da2dcf88894bfd31503accdd81498f3d Mon Sep 17 00:00:00 2001 From: Thomas Duval Date: Wed, 3 Jun 2020 10:06:52 +0200 Subject: Update to new version 5.4 Signed-off-by: Thomas Duval Change-Id: Idcd868133d75928a1ffd74d749ce98503e0555ea --- moon_utilities/moon_utilities/json_utils.py | 2076 +++++++++++++++++++++++++++ 1 file changed, 2076 insertions(+) create mode 100644 moon_utilities/moon_utilities/json_utils.py (limited to 'moon_utilities/moon_utilities/json_utils.py') diff --git a/moon_utilities/moon_utilities/json_utils.py b/moon_utilities/moon_utilities/json_utils.py new file mode 100644 index 00000000..52ab5be4 --- /dev/null +++ b/moon_utilities/moon_utilities/json_utils.py @@ -0,0 +1,2076 @@ +# Software Name: MOON + +# Version: 5.4 + +# SPDX-FileCopyrightText: Copyright (c) 2018-2020 Orange and its contributors +# SPDX-License-Identifier: Apache-2.0 + +# This software is distributed under the 'Apache License 2.0', +# the text of which is available at 'http://www.apache.org/licenses/LICENSE-2.0.txt' +# or see the "LICENSE" file for more details. + + +import html +import json +import logging + +from moon_utilities import exceptions + +LOGGER = logging.getLogger("moon.utilities." + __name__) + + +class Manager: + __policy_manager = None + __model_manager = None + __pdp_manager = None + + def get_meta_rules(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def set_subject_data(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def set_object_data(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def set_action_data(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_subject_data(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_object_data(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_action_data(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_rule(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_meta_rule(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_subject_assignment(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_object_assignment(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_action_assignment(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_subject_assignments(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_object_assignments(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_action_assignments(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_policies(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_subject_category(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_object_category(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_action_category(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_subject_categories(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_object_categories(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_action_categories(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_subject(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_object(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_action(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_subjects(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_objects(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_actions(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_policy(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def update_policy(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_models(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def update_model(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_model(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_pdp(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def update_pdp(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def add_pdp(self, **kwargs): + raise NotImplementedError # pragma: no cover + + def get_rules(self, **kwargs): + raise NotImplementedError # pragma: no cover + + +class CacheManager(Manager): + __policy_manager = None + __model_manager = None + __pdp_manager = None + + def __init__(self, cache): + self.__cache = cache + + def get_meta_rules(self, **kwargs): + return self.__cache.meta_rules + + def set_subject_data(self, **kwargs): + value = kwargs.get("value", {}) + value["category_id"] = kwargs.get("category_id", "") + value["policy_id"] = kwargs.get("policy_id", "") + return self.__cache.add_subject_data( + policy_id=kwargs.get("policy_id", ""), + category_id=kwargs.get("category_id", ""), + data=value + ) + + def set_object_data(self, **kwargs): + value = kwargs.get("value", {}) + value["category_id"] = kwargs.get("category_id", "") + value["policy_id"] = kwargs.get("policy_id", "") + return self.__cache.add_object_data( + policy_id=kwargs.get("policy_id", ""), + category_id=kwargs.get("category_id", ""), + data=value + ) + + def set_action_data(self, **kwargs): + value = kwargs.get("value", {}) + value["category_id"] = kwargs.get("category_id", "") + value["policy_id"] = kwargs.get("policy_id", "") + return self.__cache.add_action_data( + policy_id=kwargs.get("policy_id", ""), + category_id=kwargs.get("category_id", ""), + data=value + ) + + def get_subject_data(self, **kwargs): + if "policy_id" in kwargs: + results = [] + for data in self.__cache.subject_data: + if data.get("policy_id") == kwargs["policy_id"]: + if data.get("category_id") == kwargs.get("category_id"): + results.append(data) + elif not kwargs.get("category_id"): + results.append(data) + if "data_id" in kwargs: + for res in results: + if kwargs.get("data_id") in res.get("data"): + return [res, ] + else: + return results + else: + return self.__cache.subject_data + + def get_object_data(self, **kwargs): + if "policy_id" in kwargs: + results = [] + for data in self.__cache.object_data: + if data.get("policy_id") == kwargs["policy_id"]: + if data.get("category_id") == kwargs.get("category_id"): + results.append(data) + elif not kwargs.get("category_id"): + results.append(data) + return results + else: + return self.__cache.object_data + + def get_action_data(self, **kwargs): + if "policy_id" in kwargs: + results = [] + for data in self.__cache.action_data: + if data.get("policy_id") == kwargs["policy_id"]: + if data.get("category_id") == kwargs.get("category_id"): + results.append(data) + elif not kwargs.get("category_id"): + results.append(data) + return results + else: + return self.__cache.action_data + + def add_rule(self, **kwargs): + value = { + 'policy_id': kwargs.get('policy_id'), + 'meta_rule_id': kwargs.get('meta_rule_id'), + 'value': kwargs.get('value') + } + return self.__cache.add_rule(value) + + def add_meta_rule(self, **kwargs): + return self.__cache.add_meta_rule(kwargs.get("value")) + + def add_subject_assignment(self, **kwargs): + return self.__cache.add_subject_assignment( + policy_id=kwargs.get("policy_id"), + perimeter_id=kwargs.get("subject_id"), + category_id=kwargs.get("category_id"), + data_id=kwargs.get("data_id"), + ) + + def add_object_assignment(self, **kwargs): + return self.__cache.add_object_assignment( + policy_id=kwargs.get("policy_id"), + perimeter_id=kwargs.get("object_id"), + category_id=kwargs.get("category_id"), + data_id=kwargs.get("data_id"), + ) + + def add_action_assignment(self, **kwargs): + return self.__cache.add_action_assignment( + policy_id=kwargs.get("policy_id"), + perimeter_id=kwargs.get("action_id"), + category_id=kwargs.get("category_id"), + data_id=kwargs.get("data_id"), + ) + + def get_subject_assignments(self, **kwargs): + return self.__cache.subject_assignments + + def get_object_assignments(self, **kwargs): + return self.__cache.object_assignments + + def get_action_assignments(self, **kwargs): + return self.__cache.action_assignments + + def get_policies(self, **kwargs): + return self.__cache.policies + + def add_subject_category(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + if kwargs.get("category_id"): + if kwargs.get("category_id") in self.__cache.subject_categories: + raise exceptions.SubjectCategoryExisting + self.__cache.add_subject_category(kwargs.get("value")) + + def add_object_category(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + if kwargs.get("category_id"): + if kwargs.get("category_id") in self.__cache.object_categories: + raise exceptions.ObjectCategoryExisting + self.__cache.add_object_category(kwargs.get("value")) + + def add_action_category(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + if kwargs.get("category_id"): + if kwargs.get("category_id") in self.__cache.action_categories: + raise exceptions.ActionCategoryExisting + self.__cache.add_action_category(kwargs.get("value")) + + def get_subject_categories(self, **kwargs): + return self.__cache.subject_categories + + def get_object_categories(self, **kwargs): + return self.__cache.object_categories + + def get_action_categories(self, **kwargs): + return self.__cache.action_categories + + def add_subject(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + value = kwargs.get("value") + if kwargs.get("policy_id"): + value["policy_list"] = [kwargs.get("policy_id")] + if kwargs.get("perimeter_id"): + return self.__cache.update_subject(kwargs.get("perimeter_id"), value) + else: + return self.__cache.add_subject(value) + + def add_object(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + value = kwargs.get("value") + if kwargs.get("policy_id"): + value["policy_list"] = [kwargs.get("policy_id")] + if kwargs.get("perimeter_id"): + return self.__cache.update_object(kwargs.get("perimeter_id"), value) + else: + return self.__cache.add_object(value) + + def add_action(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + value = kwargs.get("value") + if kwargs.get("policy_id"): + value["policy_list"] = [kwargs.get("policy_id")] + if kwargs.get("perimeter_id"): + return self.__cache.update_action(kwargs.get("perimeter_id"), value) + else: + return self.__cache.add_action(value) + + def get_subjects(self, **kwargs): + results = {} + subjects = self.__cache.subjects + for policy_id in subjects: + results.update(subjects[policy_id]) + return results + + def get_objects(self, **kwargs): + results = {} + objects = self.__cache.objects + for policy_id in objects: + results.update(objects[policy_id]) + return results + + def get_actions(self, **kwargs): + results = {} + actions = self.__cache.actions + for policy_id in actions: + results.update(actions[policy_id]) + return results + + def add_policy(self, **kwargs): + return self.__cache.add_policy(kwargs.get("value")) + + def update_policy(self, **kwargs): + self.__cache.update_policy(kwargs.get("policy_id"), kwargs.get("value")) + + def get_models(self, **kwargs): + return self.__cache.models + + def update_model(self, **kwargs): + self.__cache.update_model(kwargs.get("model_id"), kwargs.get("value")) + + def add_model(self, **kwargs): + if kwargs.get("value", {}).get("name") != html.escape(kwargs.get("value", {}).get("name")): + raise exceptions.ValidationContentError('Forbidden characters in string') + self.__cache.add_model(kwargs.get("value")) + + def get_pdp(self, **kwargs): + return self.__cache.pdp + + def update_pdp(self, **kwargs): + self.__cache.add_pdp(pdp_id=kwargs.get("pdp_id"), data=kwargs.get("value")) + + def add_pdp(self, **kwargs): + self.__cache.add_pdp(data=kwargs.get("value")) + + def get_rules(self, **kwargs): + return self.__cache.rules + + +class DBManager(Manager): + __policy_manager = None + __model_manager = None + __pdp_manager = None + + def __init__(self, driver): # pragma: no cover + self.__policy_manager = driver.PolicyManager + self.__model_manager = driver.ModelManager + self.__pdp_manager = driver.PDPManager + + @property + def meta_rules(self): + return self.get_meta_rules() + + def get_meta_rules(self, **kwargs): + return self.__model_manager.get_meta_rules( + moon_user_id=kwargs.get("moon_user_id"), + meta_rule_id=kwargs.get("meta_rule_id") + ) + + def set_subject_data(self, **kwargs): + value = self.__policy_manager.set_subject_data( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + category_id=kwargs.get("category_id"), + value=kwargs.get("value") + ) + return value + + def set_object_data(self, **kwargs): + return self.__policy_manager.add_object_data( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + category_id=kwargs.get("category_id"), + value=kwargs.get("value") + ) + + def set_action_data(self, **kwargs): + return self.__policy_manager.add_action_data( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + category_id=kwargs.get("category_id"), + value=kwargs.get("value") + ) + + @property + def subject_data(self): + _data = [] + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + for category in self.__model_manager.get_subject_categories(moon_user_id="admin"): + _data += self.__policy_manager.get_subject_data(moon_user_id="admin", + policy_id=policy, + category_id=category) + return _data + + def get_subject_data(self, **kwargs): + return self.__policy_manager.get_subject_data( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + data_id=kwargs.get("data_id"), + category_id=kwargs.get("category_id") + ) + + @property + def object_data(self): + _data = [] + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _data += self.__policy_manager.get_object_data(moon_user_id="admin", + policy_id=policy) + return _data + + def get_object_data(self, **kwargs): + return self.__policy_manager.get_object_data( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + data_id=kwargs.get("data_id"), + category_id=kwargs.get("category_id") + ) + + @property + def action_data(self): + _data = [] + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _data += self.__policy_manager.get_action_data(moon_user_id="admin", + policy_id=policy) + return _data + + def get_action_data(self, **kwargs): + return self.__policy_manager.get_action_data( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + data_id=kwargs.get("data_id"), + category_id=kwargs.get("category_id") + ) + + def add_rule(self, **kwargs): + return self.__policy_manager.add_rule( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + meta_rule_id=kwargs.get("meta_rule_id"), + value=kwargs.get("value") + ) + + def add_meta_rule(self, **kwargs): + return self.__model_manager.add_meta_rule( + moon_user_id=kwargs.get("moon_user_id"), + meta_rule_id=kwargs.get("meta_rule_id"), + value=kwargs.get("value") + ) + + @property + def subject_assignments(self): + _assignments = {} + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _assignments.update(self.__policy_manager.get_subject_assignments( + moon_user_id="admin", + policy_id=policy)) + return _assignments + + def add_subject_assignment(self, **kwargs): + return self.__policy_manager.add_subject_assignment( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + subject_id=kwargs.get("subject_id"), + category_id=kwargs.get("category_id"), + data_id=kwargs.get("data_id") + ) + + @property + def object_assignments(self): + _assignments = {} + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _assignments.update(self.__policy_manager.get_object_assignments( + moon_user_id="admin", + policy_id=policy)) + return _assignments + + def add_object_assignment(self, **kwargs): + return self.__policy_manager.add_object_assignment( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + object_id=kwargs.get("object_id"), + category_id=kwargs.get("category_id"), + data_id=kwargs.get("data_id") + ) + + @property + def action_assignments(self): + _assignments = {} + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _assignments.update(self.__policy_manager.get_action_assignments( + moon_user_id="admin", + policy_id=policy)) + return _assignments + + def add_action_assignment(self, **kwargs): + return self.__policy_manager.add_action_assignment( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + action_id=kwargs.get("action_id"), + category_id=kwargs.get("category_id"), + data_id=kwargs.get("data_id") + ) + + def get_subject_assignments(self, **kwargs): + return self.__policy_manager.get_subject_assignments( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + category_id=kwargs.get("category_id") + ) + + def get_object_assignments(self, **kwargs): + return self.__policy_manager.get_object_assignments( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + category_id=kwargs.get("category_id") + ) + + def get_action_assignments(self, **kwargs): + return self.__policy_manager.get_action_assignments( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + category_id=kwargs.get("category_id") + ) + + def get_policies(self, **kwargs): + return self.__policy_manager.get_policies(moon_user_id=kwargs.get("moon_user_id")) + + @property + def subject_categories(self): + return self.__model_manager.get_subject_categories(moon_user_id="admin") + + def add_subject_category(self, **kwargs): + return self.__model_manager.add_subject_category( + moon_user_id=kwargs.get("moon_user_id"), + category_id=kwargs.get("category_id"), + value=kwargs.get("value") + ) + + @property + def object_categories(self): + return self.__model_manager.get_object_categories(moon_user_id="admin") + + def add_object_category(self, **kwargs): + return self.__model_manager.add_object_category( + moon_user_id=kwargs.get("moon_user_id"), + category_id=kwargs.get("category_id"), + value=kwargs.get("value") + ) + + @property + def action_categories(self): + return self.__model_manager.get_action_categories(moon_user_id="admin") + + def add_action_category(self, **kwargs): + return self.__model_manager.add_action_category( + moon_user_id=kwargs.get("moon_user_id"), + category_id=kwargs.get("category_id"), + value=kwargs.get("value") + ) + + def get_subject_categories(self, **kwargs): + return self.__model_manager.get_subject_categories( + moon_user_id=kwargs.get("moon_user_id") + ) + + def get_object_categories(self, **kwargs): + return self.__model_manager.get_object_categories( + moon_user_id=kwargs.get("moon_user_id") + ) + + def get_action_categories(self, **kwargs): + return self.__model_manager.get_action_categories( + moon_user_id=kwargs.get("moon_user_id") + ) + + @property + def subjects(self): + _perimeter = {} + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _perimeter.update(self.__policy_manager.get_subjects(moon_user_id="admin", + policy_id=policy)) + return _perimeter + + def add_subject(self, **kwargs): + if kwargs.get("perimeter_id"): + return self.__policy_manager.update_subject( + moon_user_id=kwargs.get("moon_user_id"), + perimeter_id=kwargs.get("perimeter_id"), + value=kwargs.get("value") + ) + else: + return self.__policy_manager.add_subject( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + value=kwargs.get("value") + ) + + @property + def objects(self): + _perimeter = {} + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _perimeter.update(self.__policy_manager.get_objects(moon_user_id="admin", + policy_id=policy)) + return _perimeter + + def add_object(self, **kwargs): + if kwargs.get("perimeter_id"): + return self.__policy_manager.update_object( + moon_user_id=kwargs.get("moon_user_id"), + perimeter_id=kwargs.get("perimeter_id"), + value=kwargs.get("value") + ) + else: + return self.__policy_manager.add_object( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + value=kwargs.get("value") + ) + + @property + def actions(self): + _perimeter = {} + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _perimeter.update(self.__policy_manager.get_actions(moon_user_id="admin", + policy_id=policy)) + return _perimeter + + def add_action(self, **kwargs): + if kwargs.get("perimeter_id"): + return self.__policy_manager.update_action( + moon_user_id=kwargs.get("moon_user_id"), + perimeter_id=kwargs.get("perimeter_id"), + value=kwargs.get("value") + ) + else: + return self.__policy_manager.add_action( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + value=kwargs.get("value") + ) + + def get_subjects(self, **kwargs): + return self.__policy_manager.get_subjects( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id") + ) + + def get_objects(self, **kwargs): + return self.__policy_manager.get_objects( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id") + ) + + def get_actions(self, **kwargs): + return self.__policy_manager.get_actions( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id") + ) + + @property + def policies(self): + return self.__policy_manager.get_policies(moon_user_id="admin") + + def add_policy(self, **kwargs): + return self.__policy_manager.add_policy( + moon_user_id=kwargs.get("moon_user_id"), + value=kwargs.get("value") + ) + + def update_policy(self, **kwargs): + return self.__policy_manager.update_policy( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id"), + value=kwargs.get("value")) + + @property + def models(self): + return self.get_models() + + def get_models(self, **kwargs): + return self.__model_manager.get_models(moon_user_id=kwargs.get("moon_user_id")) + + def update_model(self, **kwargs): + return self.__model_manager.update_model( + moon_user_id=kwargs.get("moon_user_id"), + model_id=kwargs.get("model_id"), + value=kwargs.get("value") + ) + + def add_model(self, **kwargs): + return self.__model_manager.add_model( + moon_user_id=kwargs.get("moon_user_id"), + value=kwargs.get("value") + ) + + @property + def pdp(self): + return self.get_pdp() + + def get_pdp(self, **kwargs): + return self.__pdp_manager.get_pdp(moon_user_id=kwargs.get("moon_user_id")) + + def update_pdp(self, **kwargs): + return self.__pdp_manager.update_pdp( + moon_user_id=kwargs.get("moon_user_id"), + pdp_id=kwargs.get("pdp_id"), + value=kwargs.get("value") + ) + + def add_pdp(self, **kwargs): + return self.__pdp_manager.add_pdp( + moon_user_id=kwargs.get("moon_user_id"), + value=kwargs.get("value") + ) + + @property + def rules(self): + _rules = [] + for policy in self.__policy_manager.get_policies(moon_user_id="admin"): + _rules.append(self.__policy_manager.get_rules(moon_user_id="admin", + policy_id=policy)) + return _rules + + def get_rules(self, **kwargs): + return self.__policy_manager.get_rules( + moon_user_id=kwargs.get("moon_user_id"), + policy_id=kwargs.get("policy_id") + ) + + +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(moon_user_id=user_id, model_id=element_id) + elif element_type == "policy": + data_db = manager.get_policies(moon_user_id=user_id, policy_id=element_id) + elif element_type == "subject": + data_db = manager.get_subjects(moon_user_id=user_id, policy_id=policy_id, perimeter_id=element_id) + elif element_type == "object": + data_db = manager.get_objects(moon_user_id=user_id, policy_id=policy_id, perimeter_id=element_id) + elif element_type == "action": + data_db = manager.get_actions(moon_user_id=user_id, policy_id=policy_id, perimeter_id=element_id) + elif element_type == "subject_category": + data_db = manager.get_subject_categories(moon_user_id=user_id, category_id=element_id) + elif element_type == "object_category": + data_db = manager.get_object_categories(moon_user_id=user_id, category_id=element_id) + elif element_type == "action_category": + data_db = manager.get_action_categories(moon_user_id=user_id, category_id=element_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(moon_user_id=user_id, meta_rule_id=element_id) + elif element_type == "subject_data": + data_db = manager.get_subject_data(moon_user_id=user_id, policy_id=policy_id, data_id=element_id, + category_id=category_id) + elif element_type == "object_data": + data_db = manager.get_object_data(moon_user_id=user_id, policy_id=policy_id, data_id=element_id, + category_id=category_id) + elif element_type == "action_data": + data_db = manager.get_action_data(moon_user_id=user_id, policy_id=policy_id, + data_id=element_id, + category_id=category_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(moon_user_id=user_id, meta_rule_id=meta_rule_id) + else: + raise Exception("Conversion of {} not implemented yet!".format(element_type)) + + # 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] + 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(moon_user_id=user_id) + elif element_type == "policy": + data_db = manager.get_policies(moon_user_id=user_id) + elif element_type == "subject": + data_db = manager.get_subjects(moon_user_id=user_id, policy_id=policy_id) + elif element_type == "object": + data_db = manager.get_objects(moon_user_id=user_id, policy_id=policy_id) + elif element_type == "action": + data_db = manager.get_actions(moon_user_id=user_id,policy_id= policy_id) + elif element_type == "subject_category": + data_db = manager.get_subject_categories(moon_user_id=user_id) + elif element_type == "object_category": + data_db = manager.get_object_categories(moon_user_id=user_id) + elif element_type == "action_category": + data_db = manager.get_action_categories(moon_user_id=user_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(moon_user_id=user_id) + elif element_type == "subject_data": + data_db = manager.get_subject_data(moon_user_id=user_id, policy_id=policy_id, + category_id=category_id) + elif element_type == "object_data": + data_db = manager.get_object_data(moon_user_id=user_id, policy_id=policy_id, + category_id=category_id) + elif element_type == "action_data": + data_db = manager.get_action_data(moon_user_id=user_id, policy_id=policy_id, + category_id=category_id) + elif element_type == "meta_rule": + data_db = manager.get_meta_rules(moon_user_id=user_id) + elif element_type == "rule": + data_db = manager.get_rules(moon_user_id=user_id, policy_id=policy_id) + else: + raise exceptions.MoonError("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"]: + 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 exceptions.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 exceptions.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 exceptions.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 exceptions.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) + if element is None: + raise exceptions.UnknownId("No {} with id {} found in database".format( + element_type, id_)) + res = JsonUtils.__convert_results_to_element(element) + 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 exceptions.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 exceptions.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: + LOGGER.debug("No {} with name {} found in database".format(element_type, elt["name"])) + raise exceptions.UnknownName( + "No {} with name {} found in database".format(element_type, elt["name"])) + ids.append(id_in_db) + elif "attr" in elt: + ids.append("attributes:" + elt['attr']) + elif field_mandatory is True: + raise exceptions.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 exceptions.UnknownId("No {} with id {} found in database".format( + element_type, id_)) + res = JsonUtils.__convert_results_to_element(element) + 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 + + +class JsonImport(object): + __user_id = None + __manager = None + __driver = None + + def __init__(self, driver_name="db", driver=None): + self.__driver = driver_name + if driver_name == "db": + self.__manager = DBManager(driver) + else: + self.__manager = CacheManager(driver) + + @property + def driver(self): + return self.__manager + + def _reorder_rules_ids(self, rule, ordered_perimeter_categories_ids, json_data_ids, policy_id, + get_function): + ordered_json_ids = [None] * len(ordered_perimeter_categories_ids) + _exc = None + data = get_function(moon_user_id=self.__user_id, policy_id=policy_id) + for _data in data: + for item in json_data_ids: + if not _data['data']: + continue + if _data.get('data').get(item): + index = ordered_perimeter_categories_ids.index(_data["category_id"]) + if _data["category_id"] not in ordered_perimeter_categories_ids: + _exc = exceptions.InvalidJson( + "The category id {} of the rule {} does not match the meta rule".format( + _data["category_id"], rule)) + continue + if ordered_json_ids[index] is not None: + _exc = exceptions.InvalidJson( + "The category id {} of the rule {} shall not be used " + "twice in the same rule".format( + _data["category_id"], rule)) + ordered_json_ids[index] = item + if None in ordered_json_ids: + for cpt, _id in enumerate(ordered_perimeter_categories_ids): + if _id.startswith("attributes:"): + if not ordered_json_ids[cpt]: + ordered_json_ids[cpt] = json_data_ids[cpt] + + if _exc: + raise _exc + return ordered_json_ids + + def _import_rules(self, json_rules): + if not isinstance(json_rules, list): + raise exceptions.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", + self.__manager, self.__user_id) + JsonUtils.convert_name_to_id(json_rule, json_to_use, "meta_rule", "meta_rule_id", + "meta_rule", self.__manager, self.__user_id) + json_subject_ids = dict() + json_object_ids = dict() + json_action_ids = dict() + JsonUtils.convert_names_to_ids(json_rule["rule"], json_subject_ids, "subject_data", + "subject", "subject_data", self.__manager, + self.__user_id, + json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_object_ids, "object_data", + "object", "object_data", self.__manager, + self.__user_id, + json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_action_ids, "action_data", + "action", "action_data", self.__manager, + self.__user_id, + json_ids["policy_id"]) + + meta_rule = self.__manager.get_meta_rules( + moon_user_id=self.__user_id, + meta_rule_id=json_to_use["meta_rule_id"] + ) + meta_rule = [v for v in meta_rule.values()] + meta_rule = meta_rule[0] + + json_to_use_rule = self._reorder_rules_ids(json_rule, meta_rule["subject_categories"], + json_subject_ids["subject"], + json_ids["policy_id"], + self.__manager.get_subject_data) + json_to_use_rule = json_to_use_rule + self._reorder_rules_ids( + json_rule, meta_rule["object_categories"], + json_object_ids["object"], + json_ids["policy_id"], + self.__manager.get_object_data) + json_to_use_rule = json_to_use_rule + self._reorder_rules_ids( + json_rule, + meta_rule["action_categories"], + json_action_ids["action"], + json_ids["policy_id"], + self.__manager.get_action_data) + json_to_use["rule"] = json_to_use_rule + try: + LOGGER.debug("Adding / updating a rule from json {}".format(json_to_use)) + self.__manager.add_rule( + moon_user_id=self.__user_id, + policy_id=json_ids["policy_id"], + meta_rule_id=json_to_use["meta_rule_id"], + value=json_to_use + ) + except exceptions.RuleExisting as e: + LOGGER.error("rule existing {}".format(e)) + except exceptions.PolicyUnknown: + raise exceptions.PolicyUnknown("Unknown policy with id {}".format( + json_ids["policy_id"])) + + def _import_meta_rules(self, json_meta_rules): + imported_mrule = [] + for json_meta_rule in json_meta_rules: + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "name", str) + JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "description", str) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "subject_categories", + "subject_categories", "subject_category", + self.__manager, + self.__user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "object_categories", + "object_categories", "object_category", + self.__manager, + self.__user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "action_categories", + "action_categories", "action_category", + self.__manager, + self.__user_id) + LOGGER.debug("Adding / updating a metarule from json {}".format(json_meta_rule)) + try: + meta_rule = self.__manager.add_meta_rule( + moon_user_id=self.__user_id, + meta_rule_id=None, + value=json_to_use + ) + LOGGER.debug("Added / updated meta rule : {}".format(meta_rule)) + imported_mrule.append(meta_rule) + except exceptions.MetaRuleExisting: + pass + return imported_mrule + + def _import_subject_object_action_assignments(self, json_item_assignments, type_element): + import_method = None + get_method = None + if type_element == "subject": + import_method = self.__manager.add_subject_assignment + get_method = self.__manager.get_subject_data + elif type_element == "object": + import_method = self.__manager.add_object_assignment + get_method = self.__manager.get_object_data + elif type_element == "action": + import_method = self.__manager.add_action_assignment + get_method = self.__manager.get_action_data + + if not isinstance(json_item_assignments, list): + raise exceptions.InvalidJson(type_element + " assignments shall be a list!") + + # get the policy id related to the user + policies = self.__manager.get_policies(moon_user_id=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 exceptions.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", + self.__manager, + 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, + self.__manager, + self.__user_id, policy_id) + JsonUtils.convert_names_to_ids(json_item_assignment, json_data, "assignments", + "data_id", type_element + "_data", + self.__manager, + self.__user_id, policy_id, + json_assignment["category_id"]) + has_found_data = True + except exceptions.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(moon_user_id=self.__user_id, policy_id=policy_id, + data_id=data_id, + category_id=json_assignment["category_id"]) + if data is not None and len(data) == 1: + LOGGER.debug( + "Adding / updating a {} assignment from json {}".format( + type_element, + json_assignment)) + args = {"moon_user_id": self.__user_id, "policy_id": policy_id, + type_element + "_id": json_assignment["id"], + "category_id": json_assignment["category_id"], "data_id": data_id} + try: + import_method(**args) + except exceptions.SubjectAssignmentExisting: + pass + except exceptions.ObjectAssignmentExisting: + pass + except exceptions.ActionAssignmentExisting: + pass + else: + raise exceptions.DataUnknown("Unknown data with id {}".format(data_id)) + + # case the data has not been found in any policies + if has_found_data is False: + raise exceptions.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): + import_method = None + if type_element == "subject": + import_method = self.__manager.set_subject_data + elif type_element == "object": + import_method = self.__manager.set_object_data + elif type_element == "action": + import_method = self.__manager.set_action_data + + if not isinstance(json_items_data, list): + raise exceptions.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 exceptions.ForbiddenOverride( + "{} datas do not support override flag !".format(type_element)) + json_to_use = dict() + JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "name", str) + JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "description", str) + json_policy = dict() + # field_mandatory : not mandatory if there is some mandatory policies + JsonUtils.convert_names_to_ids(json_item_data, json_policy, "policies", "policy_id", + "policy", + self.__manager, self.__user_id, + field_mandatory=len(mandatory_policy_ids) == 0) + json_category = dict() + JsonUtils.convert_name_to_id(json_item_data, json_category, "category", "category_id", + type_element + "_category", + self.__manager, self.__user_id) + policy_ids = [] + if "policy_id" in json_policy: + policy_ids = json_policy["policy_id"] + + for policy_id in policy_ids: + if policy_id is not None and policy_id not in mandatory_policy_ids: + mandatory_policy_ids.append(policy_id) + + if len(mandatory_policy_ids) == 0: + raise exceptions.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 exceptions.InvalidJson( + "Invalid data, the category shall be set when importing {}".format( + json_item_data)) + + for policy_id in mandatory_policy_ids: + try: + import_method(moon_user_id=self.__user_id, policy_id=policy_id, + category_id=category_id, + value=json_to_use) + except exceptions.PolicyUnknown: + raise exceptions.PolicyUnknown("Unknown policy with id {}".format(policy_id)) + except exceptions.SubjectScopeExisting: + pass + except exceptions.ObjectScopeExisting: + pass + except exceptions.ActionScopeExisting: + pass + except Exception as e: + LOGGER.exception(str(e)) + raise e + + def _import_subject_object_action_categories(self, json_item_categories, type_element): + imported_oac = [] + import_method = None + get_method = None + if type_element == "subject": + import_method = self.__manager.add_subject_category + get_method = self.__manager.get_subject_categories + elif type_element == "object": + import_method = self.__manager.add_object_category + get_method = self.__manager.get_object_categories + elif type_element == "action": + import_method = self.__manager.add_action_category + get_method = self.__manager.get_action_categories + + categories = get_method(moon_user_id=self.__user_id) + + if not isinstance(json_item_categories, list): + raise exceptions.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 exceptions.ForbiddenOverride( + "{} categories do not support override flag !".format(type_element)) + + try: + import_method(moon_user_id=self.__user_id, category_id=existing_id, + value=json_to_use) + except (exceptions.SubjectCategoryExisting, exceptions.ObjectCategoryExisting, + exceptions.ActionCategoryExisting): + # it already exists: do nothing + LOGGER.warning("Ignored {} category with name {} is already in the database".format( + type_element, json_to_use["name"])) + except Exception as e: + LOGGER.warning("Error while importing the category : {}".format(str(e))) + LOGGER.exception(str(e)) + raise e + imported_oac.append({ + 'category': type_element, + 'name': json_to_use["name"]}) + return imported_oac + + def _import_subject_object_action(self, json_items, mandatory_policy_ids, type_element): + import_method = None + get_method = None + if type_element == "subject": + import_method = self.__manager.add_subject + get_method = self.__manager.get_subjects + elif type_element == "object": + import_method = self.__manager.add_object + get_method = self.__manager.get_objects + elif type_element == "action": + import_method = self.__manager.add_action + get_method = self.__manager.get_actions + + if not isinstance(json_items, list): + raise exceptions.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) + + policy_list_ids = {} + JsonUtils.convert_names_to_ids(json_item, policy_list_ids, "policies", + "policy_list", "policy", self.__manager, + self.__user_id, + field_mandatory=False) + policy_ids = policy_list_ids["policy_list"] + # json_without_policy_name["policies"] = [] + 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 exceptions.ForbiddenOverride("{} does not support override flag !".format( + type_element)) + + if len(policy_ids) == 0: + raise exceptions.PolicyUnknown( + "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(moon_user_id=self.__user_id, policy_id=policy_id) + items_in_db = items_in_db.get(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 + try: + element = import_method(moon_user_id=self.__user_id, policy_id=policy_id, + perimeter_id=key, + value=json_without_policy_name) + LOGGER.debug("Added / updated {} : {}".format(type_element, element)) + except exceptions.PolicyExisting: + pass + + except exceptions.PolicyUnknown: + LOGGER.error("Unknown policy when adding a {}!".format( + type_element)) + raise exceptions.PolicyUnknown("Unknown policy when adding a {}!".format( + type_element)) + except Exception as e: + LOGGER.exception(str(e)) + raise e + + def _import_policies(self, json_policies): + policy_mandatory_ids = [] + policy_mandatory_names = [] + + if not isinstance(json_policies, list): + raise exceptions.InvalidJson("policies shall be a list!") + + for json_policy in json_policies: + # TODO put this in moondb + # policy_in_db = + # self.driver.PolicyManager.get_policies_by_name(json_without_model_name["name"]) + policies = self.__manager.get_policies(moon_user_id=self.__user_id) + policy_in_db = None + policy_id = None + for policy_key in policies: + if policies[policy_key]["name"] == json_policy["name"]: + policy_in_db = policies[policy_key] + policy_id = policy_key + # end TODO + if policy_in_db is None: + policy_does_exist = False + else: + policy_does_exist = True + + policy_override = JsonUtils.get_override(json_policy) + policy_mandatory = JsonUtils.get_mandatory(json_policy) + + if policy_override is False and policy_does_exist: + if policy_id: + policy_mandatory_ids.append(policy_id) + policy_mandatory_names.append(json_policy["name"]) + 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", self.__manager, self.__user_id, + field_mandatory=False) + + if not policy_does_exist: + LOGGER.debug("Creating policy {} ".format(json_without_model_name)) + added_policy = self.__manager.add_policy( + moon_user_id=self.__user_id, + value=json_without_model_name) + if policy_mandatory is True: + keys = list(added_policy.keys()) + policy_mandatory_ids.append(keys[0]) + policy_mandatory_names.append(json_policy["name"]) + elif policy_override is True: + LOGGER.debug("Updating policy {} ".format(json_without_model_name)) + self.__manager.update_policy(moon_user_id=self.__user_id, + policy_id=policy_id, + value=json_without_model_name) + if policy_mandatory is True: + policy_mandatory_ids.append(policy_id) + policy_mandatory_names.append(json_policy["name"]) + return [policy_mandatory_ids, policy_mandatory_names] + + def _import_models_with_new_meta_rules(self, json_models): + if not isinstance(json_models, list): + raise exceptions.InvalidJson("models shall be a list!") + + for json_model in json_models: + models = self.__manager.get_models(moon_user_id=self.__user_id) + model_in_db = None + model_id = None + for model_key in models: + if ("id" in json_model and model_key == json_model["id"]) or ( + "name" in json_model and models[model_key]["name"] == json_model["name"]): + model_in_db = models[model_key] + model_id = model_key + + # this should not occur as the model has been put in db previously in + # import_models_without_new_meta_rules + if model_in_db is None: + raise exceptions.ModelUnknown("Unknown model") + + json_key = dict() + JsonUtils.convert_names_to_ids(json_model, json_key, "meta_rules", "meta_rule_id", + "meta_rule", self.__manager, self.__user_id) + for meta_rule_id in json_key["meta_rule_id"]: + if meta_rule_id not in model_in_db["meta_rules"]: + model_in_db["meta_rules"].append(meta_rule_id) + + self.__manager.update_model(moon_user_id=self.__user_id, + model_id=model_id, + value=model_in_db) + + def _import_models_without_new_meta_rules(self, json_models): + if not isinstance(json_models, list): + raise exceptions.InvalidJson("models shall be a list!") + imported_model_names = [] + for json_model in json_models: + json_without_new_metarules = dict() + JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "name", str) + + models = self.__manager.get_models(moon_user_id=self.__user_id) + model_in_db = None + model_id = 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 + + JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "description", + str) + if model_in_db is None: + model_does_exist = False + else: + json_without_new_metarules["meta_rules"] = model_in_db["meta_rules"] + model_does_exist = True + model_override = JsonUtils.get_override(json_model) + if not model_does_exist: + LOGGER.debug("Creating model {} ".format(json_without_new_metarules)) + self.__manager.add_model(moon_user_id=self.__user_id, + value=json_without_new_metarules) + elif model_override is True: + LOGGER.debug( + "Updating model with id {} : {} ".format(model_id, json_without_new_metarules)) + self.__manager.update_model(moon_user_id=self.__user_id, + model_id=model_id, + value=json_without_new_metarules) + if "name" in json_without_new_metarules: + imported_model_names.append(json_without_new_metarules["name"]) + return imported_model_names + + def _import_pdps(self, json_pdps): + if not isinstance(json_pdps, list): + raise exceptions.InvalidJson("pdps shall be a list!") + imported_pdp_names = [] + 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, "vim_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 = self.__manager.get_pdp(moon_user_id=self.__user_id) + exists = False + for pdp_key in pdps: + if pdps[pdp_key]["name"] == json_to_use["name"]: + self.__manager.update_pdp(moon_user_id=self.__user_id, pdp_id=pdp_key, + value=json_to_use) + exists = True + if exists is False: + self.__manager.add_pdp(moon_user_id=self.__user_id, value=json_to_use) + imported_pdp_names.append(json_to_use["name"]) + + def import_json(self, **kwargs): + if self.__driver == "db": + if "body" in kwargs: + return self.__import_json_to_db(kwargs.get("body")).keys() + else: + raise Exception("Bad argument given...") + else: + if "body" in kwargs: + return self.__import_json_to_cache(kwargs.get("body")).keys() + else: + raise Exception("Bad argument given...") + + def __import_json_to_db(self, body): + imported_data = {} + + LOGGER.debug("Importing content: {} ...".format(body)) + + # first import the models without the meta rules as they are not yet defined + if "models" in body: + LOGGER.info("Importing models...") + imported_model_names = self._import_models_without_new_meta_rules(body["models"]) + imported_data['models'] = imported_model_names + + + + # import subjects, object, action_categories + list_element = [{"key": "subject"}, {"key": "object"}, {"key": "action"}] + for elt in list_element: + in_key = elt["key"] + key = in_key + "_categories" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_oac = self._import_subject_object_action_categories(body[key], in_key) + imported_data[key] = imported_oac + + # import meta rules + if "meta_rules" in body: + LOGGER.info("Importing meta rules...") + imported_mrules = self._import_meta_rules(body["meta_rules"]) + imported_data["meta_rules"] = imported_mrules + + # add the metarule to model + if "models" in body: + LOGGER.info("Updating models with meta rules...") + self._import_models_with_new_meta_rules(body["models"]) + + # import the policies that depends on the models + mandatory_policy_ids = [] + if "policies" in body: + LOGGER.info("Importing policies...") + mandatory_policy_ids, policy_mandatory_names = self._import_policies(body["policies"]) + imported_data["policies"] = { + 'id': mandatory_policy_ids, + 'name': policy_mandatory_names} + + # import subjects, object, action + for elt in list_element: + in_key = elt["key"] + key = in_key + "s" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_sub = self._import_subject_object_action(body[key], mandatory_policy_ids, in_key) + imported_data[key] = imported_sub + + # import subjects, object, action data + for elt in list_element: + in_key = elt["key"] + key = in_key + "_data" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_sub =self._import_subject_object_action_datas(body[key], mandatory_policy_ids, + in_key) + imported_data[key] = imported_sub + + # import subjects assignments, idem for object and action + for elt in list_element: + in_key = elt["key"] + key = in_key + "_assignments" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_sub = self._import_subject_object_action_assignments(body[key], in_key) + imported_data[key] = imported_sub + + # import rules + if "rules" in body: + LOGGER.info("Importing rules...") + imported_sub = self._import_rules(body["rules"]) + imported_data["rules"] = imported_sub + + # import pdps + if "pdps" in body: + LOGGER.info("Importing pdps...") + imported_sub = self._import_pdps(body["pdps"]) + imported_data["pdps"] = imported_sub + + return imported_data + + def __import_json_to_cache(self, body): + imported_data = {} + + LOGGER.debug("Importing content: {} ...".format(body)) + + # first import the models without the meta rules as they are not yet defined + if "models" in body: + LOGGER.info("Importing models...") + imported_model_names = self._import_models_without_new_meta_rules(body["models"]) + imported_data['models'] = imported_model_names + + + # import subjects, object, action_categories + list_element = [{"key": "subject"}, {"key": "object"}, {"key": "action"}] + for elt in list_element: + in_key = elt["key"] + key = in_key + "_categories" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_oac = self._import_subject_object_action_categories(body[key], in_key) + imported_data[key] = imported_oac + + # import meta rules + if "meta_rules" in body: + LOGGER.info("Importing meta rules...") + imported_mrules = self._import_meta_rules(body["meta_rules"]) + imported_data["meta_rules"] = imported_mrules + + # add the metarule to model + if "models" in body: + LOGGER.info("Updating models with meta rules...") + self._import_models_with_new_meta_rules(body["models"]) + + # import the policies that depends on the models + mandatory_policy_ids = [] + if "policies" in body: + LOGGER.info("Importing policies...") + mandatory_policy_ids, policy_mandatory_names = self._import_policies(body["policies"]) + imported_data["policies"] = { + 'id': mandatory_policy_ids, + 'name': policy_mandatory_names} + + # import subjects, object, action + for elt in list_element: + in_key = elt["key"] + key = in_key + "s" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_sub = self._import_subject_object_action(body[key], mandatory_policy_ids, in_key) + imported_data[key] = imported_sub + + #import subjects, object, action data + for elt in list_element: + in_key = elt["key"] + key = in_key + "_data" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_sub= self._import_subject_object_action_datas(body[key], mandatory_policy_ids, + in_key) + imported_data[key] = imported_sub + + # import subjects assignments, idem for object and action + for elt in list_element: + in_key = elt["key"] + key = in_key + "_assignments" + if key in body: + LOGGER.info("Importing {}...".format(key)) + imported_sub = self._import_subject_object_action_assignments(body[key], in_key) + imported_data[key] = imported_sub + + # import rules + if "rules" in body: + LOGGER.info("Importing rules...") + imported_sub = self._import_rules(body["rules"]) + imported_data["rules"] = imported_sub + + # import pdps + if "pdps" in body: + LOGGER.info("Importing pdps...") + imported_sub = self._import_pdps(body["pdps"]) + imported_data["pdps"] = imported_sub + return imported_data + + +class JsonExport(object): + __user_id = None + __dirver = None + __manager = None + + def __init__(self, driver_name="db", driver=None): + self.__driver = driver_name + if driver_name == "db": + self.__manager = DBManager(driver) + else: + self.__manager = CacheManager(driver) + + def _export_rules(self, json_content): + policies = self.__manager.get_policies(moon_user_id=self.__user_id) + rules_array = [] + + for policy_key in policies: + rules = self.__manager.get_rules(moon_user_id=self.__user_id, policy_id=policy_key) + rules = rules["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", self.__manager, self.__user_id) + JsonUtils.convert_id_to_name(policy_key, rule_dict, "policy", "policy", + self.__manager, self.__user_id) + ids = rule["rule"] + rule_description = dict() + meta_rule = self.__manager.get_meta_rules(moon_user_id=self.__user_id, + meta_rule_id=rule["meta_rule_id"]) + meta_rule = [v for v in meta_rule.values()] + meta_rule = meta_rule[0] + index_subject_data = len(meta_rule["subject_categories"]) - 1 + index_object_data = len(meta_rule["subject_categories"]) + len( + meta_rule["object_categories"]) - 1 + index_action_data = len(meta_rule["subject_categories"]) + len( + meta_rule["object_categories"]) + len(meta_rule["action_categories"]) - 1 + ids_subject_data = [ids[0]] if len(meta_rule["subject_categories"]) == 1 else ids[ + 0:index_subject_data] + ids_object_data = [ids[index_object_data]] if len( + meta_rule["object_categories"]) == 1 else ids[ + index_subject_data + 1:index_object_data] + ids_action_date = [ids[index_action_data]] if len( + meta_rule["action_categories"]) == 1 else ids[ + index_object_data + 1:index_action_data] + JsonUtils.convert_ids_to_names(ids_subject_data, rule_description, "subject_data", + "subject_data", self.__manager, self.__user_id, + policy_key) + JsonUtils.convert_ids_to_names(ids_object_data, rule_description, "object_data", + "object_data", self.__manager, self.__user_id, + policy_key) + JsonUtils.convert_ids_to_names(ids_action_date, rule_description, "action_data", + "action_data", self.__manager, self.__user_id, + policy_key) + rule_dict["rule"] = rule_description + rules_array.append(rule_dict) + + if len(rules_array) > 0: + json_content['rules'] = rules_array + + def _export_meta_rules(self, json_content): + meta_rules = self.__manager.get_meta_rules(moon_user_id=self.__user_id) + meta_rules_array = [] + for meta_rule_key in meta_rules: + 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", + self.__manager, self.__user_id) + JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["object_categories"], + meta_rule_dict, "object_categories", "object_category", + self.__manager, self.__user_id) + JsonUtils.convert_ids_to_names(meta_rules[meta_rule_key]["action_categories"], + meta_rule_dict, "action_categories", "action_category", + self.__manager, self.__user_id) + 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 = None + if type_element == "subject": + export_method_data = self.__manager.get_subject_assignments + elif type_element == "object": + export_method_data = self.__manager.get_object_assignments + if type_element == "action": + export_method_data = self.__manager.get_action_assignments + policies = self.__manager.get_policies(moon_user_id=self.__user_id) + element_assignments_array = [] + for policy_key in policies: + assignments = export_method_data(moon_user_id=self.__user_id, policy_id=policy_key) + 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, + self.__manager, self.__user_id, policy_key) + JsonUtils.convert_id_to_name(assignments[assignment_key]["category_id"], + assignment_dict, "category", + type_element + "_category", self.__manager, + self.__user_id, policy_key) + JsonUtils.convert_ids_to_names(assignments[assignment_key]["assignments"], + assignment_dict, "assignments", + type_element + "_data", self.__manager, + 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 = None + if type_element == "subject": + export_method_data = self.__manager.get_subject_data + elif type_element == "object": + export_method_data = self.__manager.get_object_data + if type_element == "action": + export_method_data = self.__manager.get_action_data + policies = self.__manager.get_policies(moon_user_id=self.__user_id) + element_datas_array = [] + for policy_key in policies: + datas = export_method_data(moon_user_id=self.__user_id, policy_id=policy_key) + for data_group in datas: + policy_id = data_group["policy_id"] + category_id = data_group["category_id"] + for data_key in data_group["data"]: + data_dict = dict() + if type_element == 'subject': + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, + "name", str) + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, + "description", str) + else: + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, + "name", str) + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, + "description", str) + + JsonUtils.convert_id_to_name(policy_id, data_dict, "policy", "policy", + self.__manager, self.__user_id) + JsonUtils.convert_id_to_name(category_id, data_dict, "category", + type_element + "_category", self.__manager, + 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 = None + if type_element == "subject": + export_method = self.__manager.get_subject_categories + elif type_element == "object": + export_method = self.__manager.get_object_categories + if type_element == "action": + export_method = self.__manager.get_action_categories + element_categories = export_method(moon_user_id=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 = None + if type_element == "subject": + export_method = self.__manager.get_subjects + elif type_element == "object": + export_method = self.__manager.get_objects + if type_element == "action": + export_method = self.__manager.get_actions + policies = self.__manager.get_policies(moon_user_id=self.__user_id) + element_dict = dict() + elements_array = [] + for policy_key in policies: + elements = export_method(moon_user_id=self.__user_id, policy_id=policy_key) + for element_key in elements: + 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", self.__manager, 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 = self.__manager.get_policies(moon_user_id = 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", + self.__manager, 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 = self.__manager.get_models(moon_user_id=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) + JsonUtils.convert_ids_to_names(models[model_key]["meta_rules"], model, "meta_rules", + "meta_rule", self.__manager, 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 = self.__manager.get_pdp(moon_user_id=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, **kwargs): + if self.__driver == "db": + if "moon_user_id" in kwargs: + return self.__export_json_from_db(kwargs.get("moon_user_id")) + else: + raise Exception("Bad argument given...") + else: + if "body" in kwargs: + return self.__export_json_from_db(kwargs.get("body")) + else: + raise Exception("Bad argument given...") + + def __export_json_from_db(self, moon_user_id=None): + self.__user_id = moon_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 -- cgit 1.2.3-korg