From 2e35a7e46f0929438c1c206e3116caa829f07dc6 Mon Sep 17 00:00:00 2001 From: Thomas Duval Date: Fri, 5 Oct 2018 16:54:37 +0200 Subject: Update code to 4.6 official version Change-Id: Ibd0da0e476e24b2685f54693efc11f7a58d40a62 --- moon_authz/Changelog | 9 + moon_authz/moon_authz/__init__.py | 2 +- moon_authz/moon_authz/__main__.py | 4 +- moon_authz/moon_authz/api/authorization.py | 151 ++-- moon_authz/moon_authz/api/update.py | 42 + moon_authz/moon_authz/http_server.py | 16 +- moon_authz/moon_authz/server.py | 6 +- moon_authz/tests/unit_python/mock_pods.py | 12 +- moon_dashboard/Dockerfile | 10 +- moon_dashboard/moon/api/__init__.py | 0 moon_dashboard/moon/api/moon_api.py | 0 moon_dashboard/moon/static/moon/js/moon.module.js | 2 +- moon_dashboard/moon/static/moon/js/util.service.js | 8 +- .../moon/static/moon/model/model.controller.js | 150 +++- moon_dashboard/moon/static/moon/model/model.html | 10 +- .../moon/static/moon/model/model.service.js | 5 + .../moon/static/moon/pdp/pdp.controller.js | 12 +- .../moon/static/moon/policy/policy.controller.js | 76 +- moon_dashboard/moon/static/moon/policy/policy.html | 74 +- .../moon/static/moon/policy/policy.service.js | 122 ++- .../moon/static/moon/policy/policy.service.spec.js | 151 ++++ moon_dashboard/moon/static/moon/scss/moon.scss | 4 + moon_dashboard/run.sh | 38 +- moon_dashboard/setup.cfg | 2 +- moon_forming/.gitignore | 105 +++ moon_interface/Changelog | 4 + moon_interface/moon_interface/__init__.py | 2 +- moon_interface/moon_interface/api/update.py | 49 ++ moon_interface/moon_interface/authz_requests.py | 22 +- moon_interface/moon_interface/http_server.py | 10 + moon_manager/.gitignore | 104 +++ moon_manager/Changelog | 35 +- moon_manager/moon_manager/__init__.py | 2 +- moon_manager/moon_manager/api/assignments.py | 96 ++- moon_manager/moon_manager/api/base_exception.py | 3 +- moon_manager/moon_manager/api/data.py | 36 +- moon_manager/moon_manager/api/generic.py | 7 +- moon_manager/moon_manager/api/json_export.py | 109 ++- moon_manager/moon_manager/api/json_import.py | 186 ++-- moon_manager/moon_manager/api/json_utils.py | 87 +- moon_manager/moon_manager/api/meta_data.py | 12 +- moon_manager/moon_manager/api/meta_rules.py | 10 +- moon_manager/moon_manager/api/models.py | 6 +- moon_manager/moon_manager/api/pdp.py | 14 +- moon_manager/moon_manager/api/perimeter.py | 86 +- moon_manager/moon_manager/api/policies.py | 9 +- moon_manager/moon_manager/api/rules.py | 8 +- moon_manager/moon_manager/api/slaves.py | 7 +- moon_manager/moon_manager/http_server.py | 8 +- moon_manager/moon_manager/server.py | 1 - .../unit_python/api/import_export_utilities.py | 36 +- .../tests/unit_python/api/test_assignement.py | 280 ++++++ moon_manager/tests/unit_python/api/test_data.py | 84 +- moon_manager/tests/unit_python/api/test_import.py | 20 +- .../tests/unit_python/api/test_meta_data.py | 116 ++- .../tests/unit_python/api/test_meta_rules.py | 370 ++++++-- moon_manager/tests/unit_python/api/test_pdp.py | 57 +- .../tests/unit_python/api/test_perimeter.py | 935 ++++++++++++++++++--- .../tests/unit_python/api/test_policies.py | 287 ++++++- moon_manager/tests/unit_python/api/test_rules.py | 47 +- .../tests/unit_python/api/test_unit_models.py | 226 ++++- moon_manager/tests/unit_python/conftest.py | 22 + .../tests/unit_python/helpers/data_builder.py | 79 +- .../tests/unit_python/helpers/data_helper.py | 6 +- .../tests/unit_python/helpers/model_helper.py | 7 +- .../tests/unit_python/helpers/policy_helper.py | 4 +- moon_manager/tests/unit_python/requirements.txt | 4 +- moon_orchestrator/Changelog | 7 + moon_orchestrator/Dockerfile | 2 +- moon_orchestrator/moon_orchestrator/__init__.py | 2 +- moon_orchestrator/moon_orchestrator/api/generic.py | 7 +- moon_orchestrator/moon_orchestrator/api/pods.py | 4 +- moon_orchestrator/moon_orchestrator/drivers.py | 2 + moon_orchestrator/moon_orchestrator/http_server.py | 7 +- moon_wrapper/Changelog | 19 + moon_wrapper/moon_wrapper/__init__.py | 2 +- moon_wrapper/moon_wrapper/__main__.py | 4 +- moon_wrapper/moon_wrapper/api/generic.py | 17 +- moon_wrapper/moon_wrapper/api/oslowrapper.py | 41 +- moon_wrapper/moon_wrapper/api/slaveupdate.py | 87 ++ moon_wrapper/moon_wrapper/http_server.py | 16 +- moon_wrapper/moon_wrapper/server.py | 4 +- moon_wrapper/tests/unit_python/conftest.py | 10 +- python_moonclient/.gitignore | 106 +++ python_moonclient/Changelog | 4 + python_moonclient/python_moonclient/__init__.py | 2 +- python_moonclient/python_moonclient/cli/authz.py | 14 +- python_moonclient/python_moonclient/cli/export.py | 4 +- python_moonclient/python_moonclient/cli/import.py | 3 +- python_moonclient/python_moonclient/cli/models.py | 14 +- python_moonclient/python_moonclient/cli/parser.py | 19 +- python_moonclient/python_moonclient/cli/pdps.py | 64 +- .../python_moonclient/cli/policies.py | 90 +- .../python_moonclient/cli/projects.py | 18 +- python_moonclient/python_moonclient/cli/slaves.py | 20 +- python_moonclient/python_moonclient/core/authz.py | 64 +- .../python_moonclient/core/check_tools.py | 127 ++- .../python_moonclient/core/cli_exceptions.py | 3 - python_moonclient/python_moonclient/core/config.py | 24 +- .../python_moonclient/core/json_export.py | 8 +- .../python_moonclient/core/json_import.py | 8 +- python_moonclient/python_moonclient/core/models.py | 17 +- python_moonclient/python_moonclient/core/pdp.py | 41 +- .../python_moonclient/core/policies.py | 107 ++- python_moonclient/python_moonclient/core/slaves.py | 21 +- python_moonclient/python_moonclient/moon.py | 38 +- python_moondb/.gitignore | 106 +++ python_moondb/Changelog | 20 + python_moondb/python_moondb/__init__.py | 2 +- python_moondb/python_moondb/api/keystone.py | 1 - python_moondb/python_moondb/api/managers.py | 1 + python_moondb/python_moondb/api/model.py | 193 ++++- python_moondb/python_moondb/api/policy.py | 551 ++++++++++-- python_moondb/python_moondb/backends/__init__.py | 3 +- python_moondb/python_moondb/backends/sql.py | 496 +++++++---- python_moondb/python_moondb/core.py | 2 +- .../migrate_repo/versions/001_moon.py | 56 +- .../tests/unit_python/helpers/data_helper.py | 6 +- .../tests/unit_python/helpers/meta_rule_helper.py | 4 +- .../tests/unit_python/helpers/mock_data.py | 42 +- .../tests/unit_python/helpers/model_helper.py | 7 +- .../tests/unit_python/helpers/policy_helper.py | 15 +- .../tests/unit_python/models/test_categories.py | 46 +- .../tests/unit_python/models/test_meta_rules.py | 267 +++++- .../tests/unit_python/models/test_models.py | 207 ++++- .../tests/unit_python/policies/test_assignments.py | 35 +- .../tests/unit_python/policies/test_data.py | 151 +++- .../tests/unit_python/policies/test_policies.py | 482 ++++++++++- python_moondb/tests/unit_python/requirements.txt | 2 +- python_moonutilities/.gitignore | 105 +++ python_moonutilities/Changelog | 57 ++ .../python_moonutilities/__init__.py | 4 +- python_moonutilities/python_moonutilities/cache.py | 32 +- .../python_moonutilities/context.py | 81 +- .../python_moonutilities/exceptions.py | 227 +++-- .../python_moonutilities/security_functions.py | 54 +- .../tests/unit_python/requirements.txt | 1 - .../tests/unit_python/test_validated_input.py | 143 ++-- 138 files changed, 7080 insertions(+), 1870 deletions(-) create mode 100644 moon_authz/moon_authz/api/update.py create mode 100644 moon_dashboard/moon/api/__init__.py create mode 100644 moon_dashboard/moon/api/moon_api.py create mode 100644 moon_forming/.gitignore create mode 100644 moon_interface/moon_interface/api/update.py create mode 100644 moon_manager/.gitignore create mode 100644 moon_manager/tests/unit_python/api/test_assignement.py create mode 100644 moon_wrapper/moon_wrapper/api/slaveupdate.py create mode 100644 python_moonclient/.gitignore create mode 100644 python_moondb/.gitignore create mode 100644 python_moonutilities/.gitignore diff --git a/moon_authz/Changelog b/moon_authz/Changelog index 59d7f8e4..ae1ec4d1 100644 --- a/moon_authz/Changelog +++ b/moon_authz/Changelog @@ -28,3 +28,12 @@ CHANGES - use the threading capability of Flask app - set the number of manager to 1 - update to the latest version of the python-moondb library + +4.3.4 +----- +- apply PyLint rules +- fix a bug in instructions management + +4.4.0 +----- +- add the update API diff --git a/moon_authz/moon_authz/__init__.py b/moon_authz/moon_authz/__init__.py index 0fb32055..85c245e0 100644 --- a/moon_authz/moon_authz/__init__.py +++ b/moon_authz/moon_authz/__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.3.3" +__version__ = "4.4.0" diff --git a/moon_authz/moon_authz/__main__.py b/moon_authz/moon_authz/__main__.py index 2693f687..6f1f9807 100644 --- a/moon_authz/moon_authz/__main__.py +++ b/moon_authz/moon_authz/__main__.py @@ -1,4 +1,4 @@ from moon_authz.server import create_server -server = create_server() -server.run() +SERVER = create_server() +SERVER.run() diff --git a/moon_authz/moon_authz/api/authorization.py b/moon_authz/moon_authz/api/authorization.py index 84114466..59af295d 100644 --- a/moon_authz/moon_authz/api/authorization.py +++ b/moon_authz/moon_authz/api/authorization.py @@ -11,7 +11,7 @@ from flask import request from flask_restful import Resource from python_moonutilities import exceptions -logger = logging.getLogger("moon.authz.api." + __name__) +LOGGER = logging.getLogger("moon.authz.api." + __name__) class Authz(Resource): @@ -67,19 +67,23 @@ class Authz(Resource): self.context = pickle.loads(request.data) self.context.set_cache(self.cache) self.context.increment_index() - self.run() + self.context.update_target() + # FIXME (asteroide): force the update but we should not do that + # a better way is to build the bilateral link between Master and Slaves + self.cache.update() + if not self.run(): + raise exceptions.MoonError("Error in the request status={}".format( + self.context.current_state)) self.context.delete_cache() response = flask.make_response(pickle.dumps(self.context)) response.headers['content-type'] = 'application/octet-stream' return response def run(self): - logger.debug("self.context.pdp_set={}".format(self.context.pdp_set)) result, message = self.__check_rules() if result: return self.__exec_instructions(result) - else: - self.context.current_state = "deny" + self.context.current_state = "deny" # self.__exec_next_state(result) return @@ -105,6 +109,9 @@ class Authz(Resource): raise exceptions.PdpContentError for category in category_list: scope = list(current_pdp['target'][category]) + if not scope: + LOGGER.warning("Scope in category {} is empty".format(category)) + raise exceptions.AuthzException scopes_list.append(scope) # policy_id = self.cache.get_policy_from_meta_rules("admin", current_header_id) if self.context.current_policy_id not in self.cache.rules: @@ -114,58 +121,59 @@ class Authz(Resource): for item in itertools.product(*scopes_list): req = list(item) for rule in self.cache.rules[self.context.current_policy_id]["rules"]: - logger.info("rule={}".format(rule)) if req == rule['rule']: return rule['instructions'], "" - logger.warning("No rule match the request...") + LOGGER.warning("No rule match the request...") return False, "No rule match the request..." def __update_subject_category_in_policy(self, operation, target): result = False - try: - policy_name, category_name, data_name = target.split(":") - except ValueError: - logger.error("Cannot understand value in instruction ({})".format(target)) - return False - # pdp_set = self.payload["authz_context"]['pdp_set'] - for meta_rule_id in self.context.pdp_set: - if meta_rule_id == "effect": - continue - if self.context.pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name: - for category_id, category_value in self.cache.subject_categories.items(): - if category_value["name"] == "role": - subject_category_id = category_id - break - else: - logger.error("Cannot understand category in instruction ({})".format(target)) - return False - subject_data_id = None - for data in PolicyManager.get_subject_data("admin", policy_id, category_id=subject_category_id): - for data_id, data_value in data['data'].items(): - if data_value["name"] == data_name: - subject_data_id = data_id - break - if subject_data_id: - break - else: - logger.error("Cannot understand data in instruction ({})".format(target)) - return False - if operation == "add": - self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][subject_category_id].append( - subject_data_id) - elif operation == "delete": - try: - self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][subject_category_id].remove( - subject_data_id) - except ValueError: - logger.warning("Cannot remove role {} from target".format(data_name)) - result = True - break + # try: + # policy_name, category_name, data_name = target.split(":") + # except ValueError: + # LOGGER.error("Cannot understand value in instruction ({})".format(target)) + # return False + # # pdp_set = self.payload["authz_context"]['pdp_set'] + # for meta_rule_id in self.context.pdp_set: + # if meta_rule_id == "effect": + # continue + # if self.context.pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name: + # for category_id, category_value in self.cache.subject_categories.items(): + # if category_value["name"] == "role": + # subject_category_id = category_id + # break + # else: + # LOGGER.error("Cannot understand category in instruction ({})".format(target)) + # return False + # subject_data_id = None + # for data in PolicyManager.get_subject_data("admin", policy_id, + # category_id=subject_category_id): + # for data_id, data_value in data['data'].items(): + # if data_value["name"] == data_name: + # subject_data_id = data_id + # break + # if subject_data_id: + # break + # else: + # LOGGER.error("Cannot understand data in instruction ({})".format(target)) + # return False + # if operation == "add": + # self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][ + # subject_category_id].append(subject_data_id) + # elif operation == "delete": + # try: + # self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][ + # subject_category_id].remove(subject_data_id) + # except ValueError: + # LOGGER.warning("Cannot remove role {} from target".format(data_name)) + # result = True + # break return result def __update_container_chaining(self): for index in range(len(self.payload["authz_context"]['headers'])): - self.payload["container_chaining"][index]["meta_rule_id"] = self.payload["authz_context"]['headers'][index] + self.payload["container_chaining"][index]["meta_rule_id"] = \ + self.payload["authz_context"]['headers'][index] def __get_container_from_meta_rule(self, meta_rule_id): for index in range(len(self.payload["authz_context"]['headers'])): @@ -200,9 +208,10 @@ class Authz(Resource): # if self.payload["authz_context"]['pdp_set'][next_meta_rule]['effect'] == "unset": # return notify( # request_id=self.payload["authz_context"]["request_id"], - # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'], - # payload=self.payload) - # # next will be delegation if current is deny and session is passed or deny and delegation is unset + # container_id=self.__get_container_from_meta_rule(next_meta_rule)[ + # 'container_id'],payload=self.payload) + # # next will be delegation if current is deny and session is passed or deny and + # delegation is unset # else: # LOG.error("Delegation is not developed!") # @@ -215,8 +224,8 @@ class Authz(Resource): # if self.payload["authz_context"]['pdp_set'][current_meta_rule]['effect'] == "passed": # return notify( # request_id=self.payload["authz_context"]["request_id"], - # container_id=self.__get_container_from_meta_rule(next_meta_rule)['container_id'], - # payload=self.payload) + # container_id=self.__get_container_from_meta_rule(next_meta_rule)[ + # 'container_id'],payload=self.payload) # # next will be None if current is grant and the request is sent to router # else: # return self.__return_to_router() @@ -235,16 +244,19 @@ class Authz(Resource): # args=self.payload["authz_context"]) def __exec_instructions(self, instructions): + if type(instructions) is dict: + instructions = [instructions, ] + if type(instructions) not in (list, tuple): + raise exceptions.RuleContentError("Bad instructions format") for instruction in instructions: for key in instruction: if key == "decision": if instruction["decision"] == "grant": self.context.current_state = "grant" - logger.info("__exec_instructions True {}".format( - self.context.current_state)) + LOGGER.info("__exec_instructions True %s" % self.context.current_state) return True - else: - self.context.current_state = instruction["decision"].lower() + + self.context.current_state = instruction["decision"].lower() elif key == "chain": result = self.__update_headers(**instruction["chain"]) if not result: @@ -257,7 +269,7 @@ class Authz(Resource): self.context.current_state = "deny" else: self.context.current_state = "passed" - logger.info("__exec_instructions False {}".format(self.context.current_state)) + LOGGER.info("__exec_instructions False %s" % self.context.current_state) # def __update_current_request(self): # index = self.payload["authz_context"]["index"] @@ -266,7 +278,8 @@ class Authz(Resource): # current_policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id) # previous_policy_id = PolicyManager.get_policy_from_meta_rules("admin", previous_header_id) # # FIXME (asteroide): must change those lines to be ubiquitous against any type of policy - # if self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "session": + # if self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules'][ + # 'name'] == "session": # subject = self.payload["authz_context"]['current_request'].get("subject") # subject_category_id = None # role_names = [] @@ -277,17 +290,20 @@ class Authz(Resource): # for assignment_id, assignment_value in PolicyManager.get_subject_assignments( # "admin", previous_policy_id, subject, subject_category_id).items(): # for data_id in assignment_value["assignments"]: - # data = PolicyManager.get_subject_data("admin", previous_policy_id, data_id, subject_category_id) + # data = PolicyManager.get_subject_data( + # "admin", previous_policy_id, data_id, subject_category_id) # for _data in data: # for key, value in _data["data"].items(): # role_names.append(value["name"]) # new_role_ids = [] - # for perimeter_id, perimeter_value in PolicyManager.get_objects("admin", current_policy_id).items(): + # for perimeter_id, perimeter_value in PolicyManager.get_objects( + # "admin", current_policy_id).items(): # if perimeter_value["name"] in role_names: # new_role_ids.append(perimeter_id) # break # perimeter_id = None - # for perimeter_id, perimeter_value in PolicyManager.get_actions("admin", current_policy_id).items(): + # for perimeter_id, perimeter_value in PolicyManager.get_actions( + # "admin", current_policy_id).items(): # if perimeter_value["name"] == "*": # break # @@ -353,8 +369,9 @@ class Authz(Resource): # else: # self.payload["authz_context"]["index"] += 1 # self.__update_current_request() - result, message = self.__check_rules(self.payload["authz_context"]) - current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']] + result, message = self.__check_rules() + current_header_id = self.payload["authz_context"]['headers'][ + self.payload["authz_context"]['index']] if result: self.__exec_instructions(result) else: @@ -366,15 +383,15 @@ class Authz(Resource): "args": self.payload} except Exception as e: try: - logger.error(self.payload["authz_context"]) + LOGGER.error(self.payload["authz_context"]) except KeyError: - logger.error("Cannot find \"authz_context\" in context") - logger.error(e, exc_info=True) + LOGGER.error("Cannot find \"authz_context\" in context") + LOGGER.error(e, exc_info=True) return {"authz": False, "error": str(e), "pdp_id": self.pdp_id, "args": self.payload} def head(self, uuid=None, subject_name=None, object_name=None, action_name=None): - logger.info("HEAD request") + LOGGER.info("HEAD request") return "", 200 diff --git a/moon_authz/moon_authz/api/update.py b/moon_authz/moon_authz/api/update.py new file mode 100644 index 00000000..68b7f0ce --- /dev/null +++ b/moon_authz/moon_authz/api/update.py @@ -0,0 +1,42 @@ +# 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'. +""" +Authz is the endpoint to get authorization response +""" + +from flask import request +from flask_restful import Resource +import logging + +__version__ = "4.4.0" + +LOGGER = logging.getLogger("moon.authz.api." + __name__) + + +class Update(Resource): + """ + Endpoint for update requests + """ + + __urls__ = ( + "/update", + ) + + def __init__(self, **kwargs): + self.CACHE = kwargs.get("cache") + self.INTERFACE_NAME = kwargs.get("interface_name", "interface") + self.MANAGER_URL = kwargs.get("manager_url", "http://manager:8080") + self.TIMEOUT = 5 + + def put(self): + try: + self.CACHE.update_assignments( + request.form.get("policy_id", None), + request.form.get("perimeter_id", None), + ) + except Exception as e: + LOGGER.exception(e) + return {"result": False, "reason": str(e)} + return {"result": True} diff --git a/moon_authz/moon_authz/http_server.py b/moon_authz/moon_authz/http_server.py index 7d3b1ec3..86d8a914 100644 --- a/moon_authz/moon_authz/http_server.py +++ b/moon_authz/moon_authz/http_server.py @@ -3,15 +3,16 @@ # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. +import logging from flask import Flask from flask_restful import Resource, Api -import logging from moon_authz import __version__ from moon_authz.api.authorization import Authz +from moon_authz.api.update import Update from python_moonutilities.cache import Cache from python_moonutilities import exceptions -logger = logging.getLogger("moon.authz.http_server") +LOGGER = logging.getLogger("moon.authz.http_server") CACHE = Cache() CACHE.update() @@ -62,15 +63,15 @@ class Server: __API__ = ( - Authz, - ) + Authz, Update +) class Root(Resource): """ The root of the web service """ - __urls__ = ("/", ) + __urls__ = ("/",) __methods = ("get", "post", "put", "delete", "options") def get(self): @@ -97,7 +98,7 @@ class HTTPServer(Server): def __init__(self, host="localhost", port=38001, **kwargs): super(HTTPServer, self).__init__(host=host, port=port, **kwargs) self.component_data = kwargs.get("component_data", {}) - logger.info("HTTPServer port={} {}".format(port, kwargs)) + LOGGER.info("HTTPServer port={} {}".format(port, kwargs)) self.app = Flask(__name__) self._port = port self._host = host @@ -106,6 +107,7 @@ class HTTPServer(Server): self.container_chaining = kwargs.get("container_chaining") self.api = Api(self.app) self.__set_route() + # self.__hook_errors() @self.app.errorhandler(exceptions.AuthException) @@ -116,10 +118,12 @@ class HTTPServer(Server): # FIXME (dthom): it doesn't work def get_404_json(e): return {"error": "Error", "code": 404, "description": e} + self.app.register_error_handler(404, get_404_json) def get_400_json(e): return {"error": "Error", "code": 400, "description": e} + self.app.register_error_handler(400, lambda e: get_400_json) self.app.register_error_handler(403, exceptions.AuthException) diff --git a/moon_authz/moon_authz/server.py b/moon_authz/moon_authz/server.py index 0cc5f6fc..d1b5a59b 100644 --- a/moon_authz/moon_authz/server.py +++ b/moon_authz/moon_authz/server.py @@ -8,7 +8,7 @@ import logging from moon_authz.http_server import HTTPServer as Server from python_moonutilities import configuration, exceptions -logger = logging.getLogger("moon.authz.server") +LOGGER = logging.getLogger("moon.authz.server") def create_server(): @@ -20,7 +20,7 @@ def create_server(): pdp_id = os.getenv("PDP_ID") meta_rule_id = os.getenv("META_RULE_ID") keystone_project_id = os.getenv("KEYSTONE_PROJECT_ID") - logger.info("component_type={}".format(component_type)) + LOGGER.info("component_type={}".format(component_type)) conf = configuration.get_plugins() # conf = configuration.get_configuration("plugins/{}".format(component_type)) # conf["plugins/{}".format(component_type)]['id'] = component_id @@ -31,7 +31,7 @@ def create_server(): port = conf[component_type].get('port', tcp_port) bind = conf[component_type].get('bind', "0.0.0.0") - logger.info("Starting server with IP {} on port {} bind to {}".format( + LOGGER.info("Starting server with IP {} on port {} bind to {}".format( hostname, port, bind)) server = Server( host=bind, diff --git a/moon_authz/tests/unit_python/mock_pods.py b/moon_authz/tests/unit_python/mock_pods.py index 9e05e335..39223a57 100644 --- a/moon_authz/tests/unit_python/mock_pods.py +++ b/moon_authz/tests/unit_python/mock_pods.py @@ -338,16 +338,16 @@ def register_pods(m): register_policy_action(m, "f8f49a779ceb47b3ac810f01ef71b4e0") # register_policy_action(m, "policy_id_2") register_policy_subject_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "89ba91c18dd54abfbfde7a66936c51a6") - # register_policy_subject_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") - # register_policy_subject_assignment(m, "policy_id_2", "subject_id") + register_policy_subject_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_policy_subject_assignment(m, "policy_id_2", "subject_id") # register_policy_subject_assignment_list(m1, "policy_id_2") register_policy_object_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "9089b3d2ce5b4e929ffc7e35b55eba1a") - # register_policy_object_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") - # register_policy_object_assignment(m, "policy_id_2", "object_id") + register_policy_object_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_policy_object_assignment(m, "policy_id_2", "object_id") # register_policy_object_assignment_list(m1, "policy_id_2") register_policy_action_assignment(m, "f8f49a779ceb47b3ac810f01ef71b4e0", "cdb3df220dc05a6ea3334b994827b068") - # register_policy_action_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") - # register_policy_action_assignment(m, "policy_id_2", "action_id") + register_policy_action_assignment_list(m, "f8f49a779ceb47b3ac810f01ef71b4e0") + register_policy_action_assignment(m, "policy_id_2", "action_id") # register_policy_action_assignment_list(m1, "policy_id_2") register_rules(m, "f8f49a779ceb47b3ac810f01ef71b4e0") register_rules(m, "policy_id_1") diff --git a/moon_dashboard/Dockerfile b/moon_dashboard/Dockerfile index 8f997fe1..790a2b21 100644 --- a/moon_dashboard/Dockerfile +++ b/moon_dashboard/Dockerfile @@ -8,19 +8,21 @@ LABEL Url="https://wiki.opnfv.org/display/moon/Moon+Project+Proposal" ENV MANAGER_HOST="127.0.0.1" ENV MANAGER_PORT=30001 ENV KEYSTONE_HOST="127.0.0.1" -ENV KEYSTONE_PORT=30005 +ENV KEYSTONE_PORT=5000 ENV OPENSTACK_HOST="127.0.0.1" -ENV OPENSTACK_KEYSTONE_URL="http://${KEYSTONE_HOST}:${KEYSTONE_PORT}/v2.0" +ENV OPENSTACK_KEYSTONE_URL="http://${KEYSTONE_HOST}:${KEYSTONE_PORT}/identity/v3" +ENV SERVER_IP_ADDR="0.0.0.0" USER root WORKDIR /root/ ADD . /root -RUN git clone https://git.openstack.org/openstack/horizon +RUN [ -d horizon ] || git clone https://git.openstack.org/openstack/horizon WORKDIR /root/horizon +# RUN pip install --no-cache-dir pip RUN pip install --no-cache-dir -c http://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt . RUN cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py @@ -31,4 +33,6 @@ WORKDIR /root/ RUN cp -v moon/enabled/_32000_moon.py horizon/openstack_dashboard/local/enabled/_32000_moon.py RUN cp -rv moon/ horizon/openstack_dashboard/dashboards/ +EXPOSE 8000 + CMD ["/bin/sh", "/root/run.sh"] \ No newline at end of file diff --git a/moon_dashboard/moon/api/__init__.py b/moon_dashboard/moon/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moon_dashboard/moon/api/moon_api.py b/moon_dashboard/moon/api/moon_api.py new file mode 100644 index 00000000..e69de29b diff --git a/moon_dashboard/moon/static/moon/js/moon.module.js b/moon_dashboard/moon/static/moon/js/moon.module.js index ed56ec2a..c8b86439 100755 --- a/moon_dashboard/moon/static/moon/js/moon.module.js +++ b/moon_dashboard/moon/static/moon/js/moon.module.js @@ -23,7 +23,7 @@ .module('moon', [ 'ngResource', ]).constant('moon.URI', { - API: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}', + API: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}', }) })(); diff --git a/moon_dashboard/moon/static/moon/js/util.service.js b/moon_dashboard/moon/static/moon/js/util.service.js index 18ae901d..29680a43 100755 --- a/moon_dashboard/moon/static/moon/js/util.service.js +++ b/moon_dashboard/moon/static/moon/js/util.service.js @@ -117,8 +117,12 @@ }, displayErrorFunction: function displayErrorFunction(message) { - return function() { - toast.add('error', gettext(message)); + return function(response) { + var text = gettext(message); + if (response && response.data && response.data.message) { + text += ' (' + response.data.message + ')' + } + toast.add('error', text); } }, diff --git a/moon_dashboard/moon/static/moon/model/model.controller.js b/moon_dashboard/moon/static/moon/model/model.controller.js index d6a7503b..99a7c7ed 100644 --- a/moon_dashboard/moon/static/moon/model/model.controller.js +++ b/moon_dashboard/moon/static/moon/model/model.controller.js @@ -17,13 +17,13 @@ link: function (scope, element, attrs) { element.bind('change', function (e) { - var onFileReadFn = $parse(attrs.onReadFile); + var onFileRead = $parse(attrs.onReadFile); var reader = new FileReader(); reader.onload = function () { var fileContents = reader.result; scope.$apply(function () { - onFileReadFn(scope, { + onFileRead(scope, { 'contents': fileContents }); }); @@ -65,8 +65,10 @@ modelService.initialize(); self.importData = function importData(text) { + horizon.modals.modal_spinner(gettext("Loading")) importService.importData(JSON.parse(text)).then(function () { modelService.initialize(); + horizon.modals.spinner.modal('hide'); }) } @@ -76,7 +78,8 @@ properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") } - } + }, + required: ['name', 'description'] }; var model = { name: '', description: '' }; var config = { @@ -98,7 +101,8 @@ properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") } - } + }, + required: ['name', 'description'] }; var config = { title: gettext('Update Model'), @@ -118,37 +122,73 @@ modelService.removeModel(model); } + self.createMetaRuleFunction = function createMetaRuleFunction(model, titleMap) { + return function () { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + }, + required: ['name', 'description'] + }; + var metaRule = { name: '', description: '' }; + var config = { + title: gettext('Create Meta Rule'), + schema: schema, + form: [ + 'name', + { key: 'description', type: 'textarea' } + ], + model: metaRule + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.createMetaRule(form.model).then(function (metaRule) { + titleMap.push({ value: metaRule.id, name: metaRule.name }) + model.id = metaRule.id + }) + } + } + } + self.addMetaRule = function addMetaRule(model) { var schema = { type: "object", properties: { - name: { type: "string", minLength: 2, title: gettext("Name") }, - description: { type: "string", minLength: 2, title: gettext("Description") }, id: { type: "string", title: gettext("Select a Meta Rule:") } - } + }, + required: ['id'] }; - var metaRule = { name: '', description: '' }; var titleMap = util.arrayToTitleMap(modelService.metaRules) + var formModel = { id: null } var config = { title: gettext('Add Meta Rule'), schema: schema, - form: [{ key: 'id', type: 'select', titleMap: titleMap }, { type: 'help', helpvalue: gettext("Or create a new one:") }, 'name', { key: 'description', type: 'textarea' }], - model: metaRule + form: [ + { key: 'id', type: 'select', titleMap: titleMap }, + { + key: 'createButton', + type: 'button', + title: gettext('Create Meta Rule'), + icon: 'fa fa-plus', + onClick: self.createMetaRuleFunction(formModel, titleMap) + } + ], + model: formModel }; + if (modelService.metaRules.length == 1) { + formModel.id = modelService.metaRules[0].id + } + ModalFormService.open(config).then(submit); function submit(form) { - function addMetaRuleToModel(metaRule) { - var modelCopy = angular.copy(model); - modelCopy.meta_rules.push(metaRule); - modelService.updateModel(modelCopy); - } - - if (form.model.name) { - modelService.createMetaRule(form.model).then(addMetaRuleToModel) - } else if (form.model.id) { - addMetaRuleToModel(modelService.getMetaRule(form.model.id)); - } + var metaRule = modelService.getMetaRule(form.model.id); + var modelCopy = angular.copy(model); + modelCopy.meta_rules.push(metaRule); + modelService.updateModel(modelCopy); } } @@ -158,7 +198,8 @@ properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") } - } + }, + required: ['name', 'description'] }; var metaRuleCopy = angular.copy(metaRule); var config = { @@ -188,38 +229,69 @@ } } + self.createCategoryFunction = function createCategoryFunction(type, formModel, titleMap) { + return function () { + var schema = { + type: "object", + properties: { + name: { type: "string", minLength: 2, title: gettext("Name") }, + description: { type: "string", minLength: 2, title: gettext("Description") }, + }, + required: ['name', 'description'] + }; + var metaRule = { name: '', description: '' }; + var config = { + title: gettext('Create Category'), + schema: schema, + form: [ + 'name', + { key: 'description', type: 'textarea' } + ], + model: metaRule + }; + ModalFormService.open(config).then(submit); + + function submit(form) { + modelService.createCategory(type, form.model).then(function (category) { + titleMap.push({ value: category.id, name: category.name }) + formModel.id = category.id + }) + } + } + } + self.addCategory = function addCategory(type, metaRule) { var typeValue = categoryMap[type]; var schema = { type: "object", properties: { - name: { type: "string", minLength: 2, title: gettext("Name") }, - description: { type: "string", minLength: 2, title: gettext("Description") }, id: { type: "string", title: gettext("Select a Category:") } - } + }, + required: ['id'] }; - var category = { name: '', description: '' }; var titleMap = util.arrayToTitleMap(modelService[typeValue.serviceListName]) + var formModel = { id: null } var config = { title: gettext(typeValue.addTitle), schema: schema, - form: [{ key: 'id', type: 'select', titleMap: titleMap }, { type: 'help', helpvalue: gettext("Or create a new one:") }, 'name', { key: 'description', type: 'textarea' }], - model: category + form: [ + { key: 'id', type: 'select', titleMap: titleMap }, + { + key: 'createButton', + type: 'button', + title: gettext('Create Category'), + icon: 'fa fa-plus', + onClick: self.createCategoryFunction(type, formModel, titleMap) + }], + model: formModel }; ModalFormService.open(config).then(submit); function submit(form) { - function addCategoryToMetaRule(category) { - var metaRuleCopy = angular.copy(metaRule); - metaRuleCopy[typeValue.listName].push(category); - modelService.updateMetaRule(metaRuleCopy) - } - - if (form.model.name) { - modelService.createCategory(type, form.model).then(addCategoryToMetaRule) - } else if (form.model.id) { - addCategoryToMetaRule(modelService.getCategory(type, form.model.id)); - } + var category = modelService.getCategory(type, form.model.id); + var metaRuleCopy = angular.copy(metaRule); + metaRuleCopy[typeValue.listName].push(category); + modelService.updateMetaRule(metaRuleCopy) } } diff --git a/moon_dashboard/moon/static/moon/model/model.html b/moon_dashboard/moon/static/moon/model/model.html index 98d64c75..97f08910 100644 --- a/moon_dashboard/moon/static/moon/model/model.html +++ b/moon_dashboard/moon/static/moon/model/model.html @@ -62,10 +62,6 @@ Import - @@ -115,19 +111,19 @@

- {$ category.name $} + {$ category.name $}

- {$ category.name $} + {$ category.name $}

- {$ category.name $} + {$ category.name $}

diff --git a/moon_dashboard/moon/static/moon/model/model.service.js b/moon_dashboard/moon/static/moon/model/model.service.js index 76c3da01..986eb6b1 100755 --- a/moon_dashboard/moon/static/moon/model/model.service.js +++ b/moon_dashboard/moon/static/moon/model/model.service.js @@ -205,6 +205,7 @@ return modelsMap[id]; }, createModel: function createModel(model) { + model.meta_rules = []; modelResource.create(null, model, success, util.displayErrorFunction('Unable to create model')); function success(data) { @@ -235,6 +236,10 @@ return metaRulesMap[id]; }, createMetaRule: function createMetaRule(metaRule) { + metaRule.subject_categories = []; + metaRule.object_categories = []; + metaRule.action_categories = []; + return metaRuleResource.create(null, metaRule).$promise.then(function (data) { util.displaySuccess('Meta Rule created'); return createMetaRuleInternal(data.meta_rules)[0]; diff --git a/moon_dashboard/moon/static/moon/pdp/pdp.controller.js b/moon_dashboard/moon/static/moon/pdp/pdp.controller.js index c57f3b28..1859b1f8 100644 --- a/moon_dashboard/moon/static/moon/pdp/pdp.controller.js +++ b/moon_dashboard/moon/static/moon/pdp/pdp.controller.js @@ -19,7 +19,8 @@ properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") } - } + }, + required: ['name', 'description'] }; var pdp = { name: '', description: '' }; var config = { @@ -41,7 +42,8 @@ properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") } - } + }, + required: ['name', 'description'] }; var config = { title: gettext('Update PDP'), @@ -66,7 +68,8 @@ type: "object", properties: { id: { type: "string", title: gettext("Select a Policy:") } - } + }, + required: ['id'] }; var titleMap = util.arrayToTitleMap(pdpService.policies) var config = { @@ -97,7 +100,8 @@ type: "object", properties: { id: { type: "string", title: gettext("Select a Project:") } - } + }, + required: ['id'] }; var model = {id : pdp.keystone_project_id}; diff --git a/moon_dashboard/moon/static/moon/policy/policy.controller.js b/moon_dashboard/moon/static/moon/policy/policy.controller.js index 6c6631cf..a3cc18f1 100644 --- a/moon_dashboard/moon/static/moon/policy/policy.controller.js +++ b/moon_dashboard/moon/static/moon/policy/policy.controller.js @@ -32,21 +32,23 @@ function createAddDataButton(type, index, category, config, policy) { config.form.push({ - "key": type + index + "Button", - "type": "button", - "title": "Add", - onClick: createDataFunction(type, category, policy) + key: type + index + "Button", + type: "button", + title: gettext("Create Data"), + icon: 'fa fa-plus', + onClick: createDataFunction(type, category, policy, config.model, type+index) }) } - function createDataFunction(type, category, policy) { + function createDataFunction(type, category, policy, formModel, key) { return function () { var schema = { type: "object", properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") }, - } + }, + required: ['name', 'description'] }; var data = { name: '', description: '' }; var config = { @@ -61,6 +63,7 @@ policyService.createData(type, policy, category, form.model).then( function (data) { util.pushAll(dataTitleMaps[category.id], util.arrayToTitleMap(data)); + formModel[key] = data[0].id } ); } @@ -82,6 +85,7 @@ var titleMap = getOrCreateDataTitleMap(category, data, policy); config.schema.properties[type + i] = { type: "string", title: gettext('Select ' + type + ' data of ' + category.name + ' category') }; config.form.push({ key: type + i, type: 'select', titleMap: titleMap }); + config.schema.required.push(type + i); createAddDataButton(type, i, category, config, policy); } } @@ -102,7 +106,8 @@ description: { type: "string", minLength: 2, title: gettext("Description") }, genre: { type: "string", title: gettext("genre") }, model_id: { type: "string", title: gettext("Select a Model:") } - } + }, + required: ['name', 'description', 'genre', 'model_id'] }; var policy = { name: '', description: '', model_id: null, genre: '' }; var titleMap = util.arrayToTitleMap(modelService.models) @@ -126,7 +131,8 @@ name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") }, genre: { type: "string", title: gettext("Genre") }, - } + }, + required: ['name', 'description', 'genre'] }; var config = { title: gettext('Update Policy'), @@ -146,7 +152,8 @@ type: "object", properties: { instructions: { type: "string", title: gettext("Instructions") } - } + }, + required: ['instructions'] }; var config = { @@ -179,11 +186,16 @@ } self.addRule = function addRule(policy) { + if (policy.model.meta_rules.length == 1) { + self.addRuleWithMetaRule(policy, policy.model.meta_rules[0]); + return; + } var schema = { type: "object", properties: { metaRuleId: { type: "string", title: gettext("Select a Metarule:") } - } + }, + required: ['metaRuleId'] }; var rule = { metaRuleId: null }; var titleMap = util.arrayToTitleMap(policy.model.meta_rules); @@ -201,7 +213,7 @@ } self.removePolicy = function removePolicy(policy) { - if (confirm(gettext('Are you sure to delete this Policy?'))) + if (confirm(gettext('Are you sure to delete this Policy? (Associated perimeter, data an PDP will be deleted too)'))) policyService.removePolicy(policy); } @@ -216,6 +228,7 @@ self.showRule = function showRule(rule) { self.selectedRule = rule; + self.currentData = null; } self.hideRule = function hideRule() { @@ -229,14 +242,22 @@ type: type, loading: true, perimeters: [], - assignments: [] + allPerimeters: [], + assignments: [], } policyService.loadPerimetersAndAssignments(type, policy).then(function (values) { var category = categoryMap[type]; self.currentData.loading = false; self.currentData.perimeters = values.perimeters; - for (var index = 0; index < values.assignments.length; index++) { + var index; + for (index = 0; index < values.allPerimeters.length; index++) { + var perimeter = values.allPerimeters[index]; + if (perimeter.policy_list.indexOf(policy.id) < 0) { + self.currentData.allPerimeters.push(perimeter); + } + } + for (index = 0; index < values.assignments.length; index++) { var assignment = values.assignments[index]; if (assignment.assignments.indexOf(data.id) >= 0) { var perimeter = values.perimetersMap[assignment[category.perimeterId]]; @@ -253,10 +274,12 @@ properties: { name: { type: "string", minLength: 2, title: gettext("Name") }, description: { type: "string", minLength: 2, title: gettext("Description") }, - } + }, + required: ['name', 'description'] }; if (type == 'subject') { schema.properties.email = { type: "email", "type": "string", "pattern": "^\\S+@\\S+$", title: gettext("Email") } + schema.required.push('email'); } var perimeter = { name: '', description: '' }; var config = { @@ -268,7 +291,7 @@ if (type == 'subject') { config.form.push('email'); } - + ModalFormService.open(config).then(submit); function submit(form) { @@ -278,6 +301,13 @@ } } + self.addPerimeter = function addPerimeter(type, policy, perimeter) { + policyService.addPerimeterToPolicy(type, policy, perimeter).then(function () { + self.currentData.allPerimeters.splice(self.currentData.allPerimeters.indexOf(perimeter), 1); + self.currentData.perimeters.push(perimeter); + }) + } + self.assign = function assign(type, policy, perimeter, data) { policyService.createAssignment(type, policy, perimeter, data).then(function () { self.currentData.assignments.push(perimeter); @@ -291,5 +321,21 @@ self.currentData.assignments.splice(self.currentData.assignments.indexOf(perimeter), 1); }) } + + self.removePerimeterFromPolicy = function removePerimeterFromPolicy(type, policy, perimeter) { + if (confirm(gettext('Are you sure to delete this Perimeter? (Associated assignments will be deleted too)'))) + policyService.removePerimeterFromPolicy(type, policy, perimeter).then(function () { + self.currentData.perimeters.splice(self.currentData.perimeters.indexOf(perimeter), 1); + perimeter.policy_list.splice(perimeter.policy_list.indexOf(policy.id), 1); + if (perimeter.policy_list.length > 0) { + self.currentData.allPerimeters.push(perimeter); + } + }) + } + + self.removeData = function removeData(type, policy, data) { + if (confirm(gettext('Are you sure to delete this Data? (Associated assignments and rules will be deleted too)'))) + policyService.removeData(type, policy, data) + } } })(); \ No newline at end of file diff --git a/moon_dashboard/moon/static/moon/policy/policy.html b/moon_dashboard/moon/static/moon/policy/policy.html index 70789fbb..ba13bec2 100644 --- a/moon_dashboard/moon/static/moon/policy/policy.html +++ b/moon_dashboard/moon/static/moon/policy/policy.html @@ -10,7 +10,7 @@
-
+

{$ policy.name $}

@@ -24,6 +24,46 @@ Genre: {$ policy.genre ? policy.genre : 'none' $} +
+ +

Warning!

+

+ Some data are unused, please check them and delete them if necessary. + Show unused data + Hide unused data +

+
+ +
+
+

Unused Subject data

+
+

{$ subject.name $}

+ +
+
+ +
+

Unused Object data

+
+

{$ object.name $}

+ +
+
+ +
+

Unused Action data

+
+

{$ action.name $}

+ +
+
+ +
+ +

Rules

@@ -85,7 +125,7 @@

- {$ data.name $} + {$ data.name $} + +

+

Click to add

+
+ +
+

Policy perimeters

- +
+ + {$ perimeter.name $} + + +
+

Click to assign

Assigned perimeters

- +

Click to unassign

diff --git a/moon_dashboard/moon/static/moon/policy/policy.service.js b/moon_dashboard/moon/static/moon/policy/policy.service.js index 87250b2e..3781156d 100755 --- a/moon_dashboard/moon/static/moon/policy/policy.service.js +++ b/moon_dashboard/moon/static/moon/policy/policy.service.js @@ -26,34 +26,55 @@ remove: { method: 'DELETE' } }); - var policySubjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/subject_data/' + ':category_id', {}, { + var policySubjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/subject_data/' + ':category_id' + '/' + ':data_id', {}, { query: {method: 'GET'}, create: { method: 'POST' }, + remove: { method: 'DELETE' } }) - var policyObjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/object_data/' + ':category_id', {}, { + var policyObjectDataResource = $resource(host + '/policies/' + ':policy_id' + '/object_data/' + ':category_id' + '/' + ':data_id', {}, { query: {method: 'GET'}, create: { method: 'POST' }, + remove: { method: 'DELETE' } }) - var policyActionDataResource = $resource(host + '/policies/' + ':policy_id' + '/action_data/' + ':category_id', {}, { + var policyActionDataResource = $resource(host + '/policies/' + ':policy_id' + '/action_data/' + ':category_id' + '/' + ':data_id', {}, { query: {method: 'GET'}, create: { method: 'POST' }, + remove: { method: 'DELETE' } }) - var policySubjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/subjects', {}, { + var policySubjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/subjects/' + ':perimeter_id', {}, { query: {method: 'GET'}, create: { method: 'POST' }, + remove: { method: 'DELETE' } }) - var policyObjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/objects', {}, { + var policyObjectPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/objects/' + ':perimeter_id', {}, { query: {method: 'GET'}, create: { method: 'POST' }, + remove: { method: 'DELETE' } }) - var policyActionPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/actions', {}, { + var policyActionPerimetersResource = $resource(host + '/policies/' + ':policy_id' + '/actions/' + ':perimeter_id', {}, { query: {method: 'GET'}, create: { method: 'POST' }, + remove: { method: 'DELETE' } + }) + + var subjectPerimetersResource = $resource(host + '/subjects/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + update: { method: 'PATCH' } + }) + + var objectPerimetersResource = $resource(host + '/objects/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + update: { method: 'PATCH' } + }) + + var actionPerimetersResource = $resource(host + '/actions/' + ':perimeter_id', {}, { + query: {method: 'GET'}, + update: { method: 'PATCH' } }) var policySubjectAssignmentsResource = $resource(host + '/policies/' + ':policy_id' + '/subject_assignments/' + ':perimeter_id' + '/' + ':category_id' + '/' + ':data_id', {}, { @@ -81,30 +102,36 @@ arrayName: "subjectData", mapName: "subjectDataMap", responseName: "subject_data", - perimeterResource: policySubjectPerimetersResource, + policyPerimeterResource: policySubjectPerimetersResource, + perimeterResource: subjectPerimetersResource, assignmentResource: policySubjectAssignmentsResource, perimeterResponseName: "subjects", assignmentResponseName: "subject_assignments", + unusedArrayName: "unusedSubjectData", }, 'object': { resource: policyObjectDataResource, arrayName: "objectData", mapName: "objectDataMap", responseName: "object_data", - perimeterResource: policyObjectPerimetersResource, + policyPerimeterResource: policyObjectPerimetersResource, + perimeterResource: objectPerimetersResource, assignmentResource: policyObjectAssignmentsResource, perimeterResponseName: "objects", assignmentResponseName: "object_assignments", + unusedArrayName: "unusedObjectData", }, 'action': { resource: policyActionDataResource, arrayName: "actionData", mapName: "actionDataMap", responseName: "action_data", - perimeterResource: policyActionPerimetersResource, + policyPerimeterResource: policyActionPerimetersResource, + perimeterResource: actionPerimetersResource, assignmentResource: policyActionAssignmentsResource, perimeterResponseName: "actions", assignmentResponseName: "action_assignments", + unusedArrayName: "unusedActionData", } } @@ -149,6 +176,7 @@ function removeRuleInternal(policy, rule) { policy.rules.splice(policy.rules.indexOf(rule), 1); + updateUnusedData(policy); } function loadPolicyRule(policy) { @@ -161,11 +189,40 @@ } $q.all(queries).then(function (result) { - createRules(policy, result.rules, result.subjectData, result.objectData, result.actionData) + createRules(policy, result.rules, result.subjectData, result.objectData, result.actionData); + updateUnusedData(policy); }, util.displayErrorFunction('Unable to load rules')) } } + function updateUnusedData(policy) { + policy.unusedSubjectData.splice(0, policy.unusedSubjectData.length); + util.pushAll(policy.unusedSubjectData, policy.subjectData); + + policy.unusedObjectData.splice(0, policy.unusedObjectData.length); + util.pushAll(policy.unusedObjectData, policy.objectData); + + policy.unusedActionData.splice(0, policy.unusedActionData.length); + util.pushAll(policy.unusedActionData, policy.actionData); + + for (var i = 0; i < policy.rules.length; i++) { + var rule = policy.rules[i]; + removeUsedData(rule.subjectData, policy.unusedSubjectData); + removeUsedData(rule.objectData, policy.unusedObjectData); + removeUsedData(rule.actionData, policy.unusedActionData); + } + } + + function removeUsedData(list, orphanList) { + for (var j = 0; j < list.length; j++) { + var data = list[j]; + var notOrphanIndex = util.indexOf(orphanList, "id", data.id); + if (notOrphanIndex >= 0) { + orphanList.splice(notOrphanIndex, 1); + } + } + } + function createRules(policy, rulesData, subjectsData, objectsData, actionsData) { policy.rules = rulesData ? rulesData.rules.rules : []; policy.subjectDataMap = subjectsData.subject_data.length > 0 ? subjectsData.subject_data[0].data : []; @@ -174,6 +231,9 @@ policy.objectData = util.mapToArray(policy.objectDataMap); policy.actionDataMap = actionsData.action_data.length > 0 ? actionsData.action_data[0].data : []; policy.actionData = util.mapToArray(policy.actionDataMap); + policy.unusedSubjectData = []; + policy.unusedObjectData = []; + policy.unusedActionData = []; for (var i = 0; i < policy.rules.length; i++) { var rule = policy.rules[i]; populateRule(policy, rule); @@ -251,6 +311,7 @@ policy.rules.push(populateRule(policy, rule)) } util.displaySuccess('Rule created'); + updateUnusedData(policy); } }, removeRuleFromPolicy: function removeRuleFromPolicy(policy, rule) { @@ -267,14 +328,27 @@ function (data) { var result = util.createInternal(data[categoryValue.responseName].data, policy[categoryValue.arrayName], policy[categoryValue.mapName]); util.displaySuccess('Data created'); + util.pushAll(policy[categoryValue.unusedArrayName], result); return result; }, util.displayErrorFunction('Unable to create Data') ); }, + removeData: function removeData(type, policy, data) { + var categoryValue = categoryMap[type]; + return categoryValue.resource.remove({ policy_id: policy.id, category_id: data.category_id, data_id: data.id }).$promise.then( + function (data) { + policy[categoryValue.arrayName].splice(policy.subjectData.indexOf(data), 1); + policy[categoryValue.unusedArrayName].splice(policy.unusedSubjectData.indexOf(data), 1); + delete policy[categoryValue.mapName][data.id]; + util.displaySuccess('Data removed'); + }, + util.displayErrorFunction('Unable to remove Data') + ); + }, createPerimeter: function createPerimeter(type, policy, perimeter) { var categoryValue = categoryMap[type]; - return categoryValue.perimeterResource.create({ policy_id: policy.id }, perimeter).$promise.then( + return categoryValue.policyPerimeterResource.create({ policy_id: policy.id }, perimeter).$promise.then( function (data) { util.displaySuccess('Perimeter created'); return util.mapToArray(data[categoryValue.perimeterResponseName]); @@ -282,10 +356,33 @@ util.displayErrorFunction('Unable to create Perimeter') ); }, + removePerimeterFromPolicy: function removePerimeterFromPolicy(type, policy, perimeter) { + var categoryValue = categoryMap[type]; + + return categoryValue.policyPerimeterResource.remove({ policy_id: policy.id, perimeter_id: perimeter.id }, null).$promise.then( + function (data) { + util.displaySuccess('Perimeter removed'); + return perimeter; + }, + util.displayErrorFunction('Unable to remove Perimeter') + ) + }, + addPerimeterToPolicy: function addPerimeterToPolicy(type, policy, perimeter) { + var categoryValue = categoryMap[type]; + perimeter.policy_list.push(policy.id); + + return categoryValue.perimeterResource.update({ perimeter_id: perimeter.id }, perimeter).$promise.then( + function (data) { + util.displaySuccess('Perimeter added'); + }, + util.displayErrorFunction('Unable to add Perimeter') + ) + }, loadPerimetersAndAssignments: function loadPerimetersAndAssignments(type, policy) { var categoryValue = categoryMap[type]; var queries = { - perimeters: categoryValue.perimeterResource.query({ policy_id: policy.id }).$promise, + allPerimeters: categoryValue.perimeterResource.query().$promise, + perimeters: categoryValue.policyPerimeterResource.query({ policy_id: policy.id }).$promise, assignments: categoryValue.assignmentResource.query({ policy_id: policy.id }).$promise, } @@ -294,6 +391,7 @@ result.assignments = util.mapToArray(data.assignments[categoryValue.assignmentResponseName]); result.perimetersMap = data.perimeters[categoryValue.perimeterResponseName]; result.perimeters = util.mapToArray(result.perimetersMap); + result.allPerimeters = util.mapToArray(data.allPerimeters[categoryValue.perimeterResponseName]); return result; }, util.displayErrorFunction('Unable to load Perimeters')) diff --git a/moon_dashboard/moon/static/moon/policy/policy.service.spec.js b/moon_dashboard/moon/static/moon/policy/policy.service.spec.js index 045bf9b3..8d0ca8bf 100755 --- a/moon_dashboard/moon/static/moon/policy/policy.service.spec.js +++ b/moon_dashboard/moon/static/moon/policy/policy.service.spec.js @@ -329,6 +329,157 @@ }); + it('should create perimeter', function () { + var perimeterCreatedData = { + subjects: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + } + }; + + $httpBackend.expectPOST(URI.API + '/policies/policyId1/subjects').respond(200, perimeterCreatedData); + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { name: 'subject1', description: 'sDescription1' }; + + var promise = service.createPerimeter(type, policy, perimeter); + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.length).toBe(1); + var perimeter = result[0]; + expect(perimeter.id).toBe('subjectId1'); + expect(perimeter.name).toBe('subject1'); + expect(perimeter.description).toBe('sDescription1'); + }) + }); + + it('should remove perimeter', function () { + $httpBackend.expectDELETE(URI.API + '/policies/policyId1/subjects/subjectId1').respond(200); + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { id: 'subjectId1' }; + + var promise = service.removePerimeterFromPolicy(type, policy, perimeter); + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.id).toBe('subjectId1'); + }) + }); + + it('should load perimeters and assignments', function () { + var assignmentsData = { + subject_assignments: { + 'subjectAssignmentId1': { + id: 'subjectAssignmentId1', + policy_id: 'policyId1', + subject_id: 'subjectId1', + category_id: 'subjectCategoryId1', + assignments: ['subjectDataId1'] + }, + } + }; + + var perimetersData = { + subjects: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + } + }; + + var allPerimetersData = { + subjects: { + 'subjectId1': { name: 'subject1', description: 'sDescription1' }, + 'subjectId2': { name: 'subject2', description: 'sDescription2' }, + } + }; + + var type = 'subject'; + var policy = { id: 'policyId1' }; + $httpBackend.expectGET(URI.API + '/subjects').respond(200, allPerimetersData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/subjects').respond(200, perimetersData); + $httpBackend.expectGET(URI.API + '/policies/policyId1/subject_assignments').respond(200, assignmentsData); + + var promise = service.loadPerimetersAndAssignments(type, policy); + + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.perimeters.length).toBe(1); + var perimeter = result.perimeters[0]; + expect(perimeter.id).toBe('subjectId1'); + expect(perimeter.name).toBe('subject1'); + expect(perimeter.description).toBe('sDescription1'); + + expect(result.allPerimeters.length).toBe(2); + perimeter = result.allPerimeters[0]; + expect(perimeter.id).toBe('subjectId1'); + expect(perimeter.name).toBe('subject1'); + expect(perimeter.description).toBe('sDescription1'); + + perimeter = result.allPerimeters[1]; + expect(perimeter.id).toBe('subjectId2'); + expect(perimeter.name).toBe('subject2'); + expect(perimeter.description).toBe('sDescription2'); + + + expect(result.assignments.length).toBe(1); + var assignment = result.assignments[0]; + expect(assignment.id).toBe('subjectAssignmentId1'); + expect(assignment.policy_id).toBe('policyId1'); + expect(assignment.subject_id).toBe('subjectId1'); + expect(assignment.category_id).toBe('subjectCategoryId1'); + expect(assignment.assignments.length).toBe(1); + expect(assignment.assignments[0]).toBe('subjectDataId1'); + }) + + }); + + it('should create assignment', function () { + var assignmentCreatedData = { + subject_assignments: { + 'subjectAssignmentId1': { + id: 'subjectAssignmentId1', + policy_id: 'policyId1', + subject_id: 'subjectId1', + category_id: 'subjectCategoryId1', + assignments: ['subjectDataId1'] + }, + } + }; + + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { id: 'subjectId1' }; + var data = { id: 'subjectDataId1', category_id: 'subjectCategoryId1'}; + + $httpBackend.expectPOST(URI.API + '/policies/policyId1/subject_assignments').respond(200, assignmentCreatedData); + var promise = service.createAssignment(type, policy, perimeter, data); + + $httpBackend.flush(); + + promise.then(function (result) { + expect(result.length).toBe(1); + var assignment = result[0]; + expect(assignment.id).toBe('subjectAssignmentId1'); + expect(assignment.policy_id).toBe('policyId1'); + expect(assignment.subject_id).toBe('subjectId1'); + expect(assignment.category_id).toBe('subjectCategoryId1'); + expect(assignment.assignments.length).toBe(1); + expect(assignment.assignments[0]).toBe('subjectDataId1'); + }) + }); + + it('should remove assignment', function () { + var type = 'subject'; + var policy = { id: 'policyId1' }; + var perimeter = { id: 'subjectId1' }; + var data = { id: 'subjectDataId1', category_id: 'subjectCategoryId1'}; + + $httpBackend.expectDELETE(URI.API + '/policies/policyId1/subject_assignments/subjectId1/subjectCategoryId1/subjectDataId1').respond(200); + service.removeAssignment(type, policy, perimeter, data); + $httpBackend.flush(); + }); + }); diff --git a/moon_dashboard/moon/static/moon/scss/moon.scss b/moon_dashboard/moon/static/moon/scss/moon.scss index 20bf6c41..3cdbb6e3 100644 --- a/moon_dashboard/moon/static/moon/scss/moon.scss +++ b/moon_dashboard/moon/static/moon/scss/moon.scss @@ -51,4 +51,8 @@ details { .input-file { display: none !important; +} + +.overflow-hidden { + overflow: hidden; } \ No newline at end of file diff --git a/moon_dashboard/run.sh b/moon_dashboard/run.sh index bf18faa2..9a68ca6e 100644 --- a/moon_dashboard/run.sh +++ b/moon_dashboard/run.sh @@ -1,26 +1,42 @@ #!/bin/sh # sudo docker run -ti --rm -p 8000:8000 -e MANAGER_HOST=localhost -e MANAGER_PORT=30001 -e KEYSTONE_HOST=localhost -e KEYSTONE_PORT=30005 moonplatform/dashboard:dev +echo ----------------------------------- +export OPENSTACK_KEYSTONE_URL="http://${KEYSTONE_HOST}:${KEYSTONE_PORT}/identity/v3" +echo MANAGER_HOST=${MANAGER_HOST} +echo MANAGER_PORT=${MANAGER_PORT} +echo KEYSTONE_HOST=${KEYSTONE_HOST} +echo KEYSTONE_PORT=${KEYSTONE_PORT} +echo OPENSTACK_HOST=${OPENSTACK_HOST} +echo OPENSTACK_KEYSTONE_URL=${OPENSTACK_KEYSTONE_URL} +echo SERVER_IP_ADDR=${SERVER_IP_ADDR} +echo ----------------------------------- + CONSTANT_FILE=/root/horizon/openstack_dashboard/dashboards/moon/static/moon/js/moon.module.js -sed "s/{{MANAGER_HOST}}/$MANAGER_HOST/g" -i $CONSTANT_FILE -sed "s/{{MANAGER_PORT}}/$MANAGER_PORT/g" -i $CONSTANT_FILE -sed "s/{{KEYSTONE_HOST}}/$KEYSTONE_HOST/g" -i $CONSTANT_FILE -sed "s/{{KEYSTONE_PORT}}/$KEYSTONE_PORT/g" -i $CONSTANT_FILE +sed "s/{{MANAGER_HOST}}/${MANAGER_HOST}/g" -i ${CONSTANT_FILE} +sed "s/{{MANAGER_PORT}}/${MANAGER_PORT}/g" -i ${CONSTANT_FILE} +sed "s/{{KEYSTONE_HOST}}/${KEYSTONE_HOST}/g" -i ${CONSTANT_FILE} +sed "s/{{KEYSTONE_PORT}}/${KEYSTONE_PORT}/g" -i ${CONSTANT_FILE} cd /root/horizon LOCAL_SETTINGS=/root/horizon/openstack_dashboard/local/local_settings.py -sed "s/OPENSTACK_HOST = \"127.0.0.1\"/OPENSTACK_HOST = \"${OPENSTACK_HOST}\"/" -i $LOCAL_SETTINGS -sed "s#OPENSTACK_KEYSTONE_URL = \"http:\/\/%s:5000\/v2.0\" % OPENSTACK_HOST#OPENSTACK_KEYSTONE_URL = \"${OPENSTACK_KEYSTONE_URL}\"#" -i $LOCAL_SETTINGS + +sed "s/OPENSTACK_HOST = \"127.0.0.1\"/OPENSTACK_HOST = \"${OPENSTACK_HOST}\"/" -i ${LOCAL_SETTINGS} +sed "s#OPENSTACK_KEYSTONE_URL = \"http://%s:5000/v3\" % OPENSTACK_HOST#OPENSTACK_KEYSTONE_URL = \"${OPENSTACK_KEYSTONE_URL}\"#" -i ${LOCAL_SETTINGS} +sed "s/#ALLOWED_HOSTS = \['horizon.example.com', \]/ALLOWED_HOSTS = \['${SERVER_IP_ADDR}'\]/" -i ${LOCAL_SETTINGS} echo ----------------- -grep OPENSTACK_HOST $LOCAL_SETTINGS -grep OPENSTACK_KEYSTONE_URL LOCAL_SETTINGS +grep OPENSTACK_HOST ${LOCAL_SETTINGS} +grep ALLOWED_HOSTS ${LOCAL_SETTINGS} echo ----------------- +export NO_PROXY=127.0.0.1,10.0.2.15,10.96.0.0/12,192.168.0.0/16,10.192.118.95,10.192.118.96,keystone,manager,devstack + +echo "${KEYSTONE_HOST} devstack, keystone" | tee -a /etc/hosts -echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $CONSTANT_FILE" -cat $CONSTANT_FILE +echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ${CONSTANT_FILE}" +cat ${CONSTANT_FILE} echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" -tox -e runserver -- 0.0.0.0:8000 \ No newline at end of file +tox -e runserver -- 0.0.0.0:8000 diff --git a/moon_dashboard/setup.cfg b/moon_dashboard/setup.cfg index f68765dd..9cf3f779 100644 --- a/moon_dashboard/setup.cfg +++ b/moon_dashboard/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = moon -version=1.2.0 +version=1.5.0 summary = A dashboard plugin for Moon description-file = README.rst diff --git a/moon_forming/.gitignore b/moon_forming/.gitignore new file mode 100644 index 00000000..7bff7318 --- /dev/null +++ b/moon_forming/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + diff --git a/moon_interface/Changelog b/moon_interface/Changelog index cea475f2..361d7840 100644 --- a/moon_interface/Changelog +++ b/moon_interface/Changelog @@ -30,3 +30,7 @@ CHANGES 4.3.3-1 ----- - Fix a bug in authz_requests + +4.4.0 +----- +- Add the update API diff --git a/moon_interface/moon_interface/__init__.py b/moon_interface/moon_interface/__init__.py index a8cd9455..85c245e0 100644 --- a/moon_interface/moon_interface/__init__.py +++ b/moon_interface/moon_interface/__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.3.3-1" +__version__ = "4.4.0" diff --git a/moon_interface/moon_interface/api/update.py b/moon_interface/moon_interface/api/update.py new file mode 100644 index 00000000..e798059c --- /dev/null +++ b/moon_interface/moon_interface/api/update.py @@ -0,0 +1,49 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. +""" +Authz is the endpoint to get authorization response +""" + +from flask import request +from flask_restful import Resource +import requests +import logging + +__version__ = "4.3.1" + +logger = logging.getLogger("moon.interface.api." + __name__) + + +class Update(Resource): + """ + Endpoint for update requests + """ + + __urls__ = ( + "/update", + ) + + def __init__(self, **kwargs): + self.CACHE = kwargs.get("cache") + self.INTERFACE_NAME = kwargs.get("interface_name", "interface") + self.MANAGER_URL = kwargs.get("manager_url", "http://manager:8080") + self.TIMEOUT = 5 + + def put(self): + try: + self.CACHE.update_assignments( + request.form.get("policy_id", None), + request.form.get("perimeter_id", None), + ) + for project_id in self.CACHE.container_chaining: + hostname = self.CACHE.container_chaining[project_id][0]["hostip"] + port = self.CACHE.container_chaining[project_id][0]["port"] + req = requests.put("http://{}:{}/update".format(hostname, port), request.form) + if req.status_code != 200: + logger.error("Cannot connect to {} on port {}".format(hostname, port)) + except Exception as e: + logger.exception(e) + return {"result": False, "reason": str(e)} + return {"result": True} diff --git a/moon_interface/moon_interface/authz_requests.py b/moon_interface/moon_interface/authz_requests.py index c809053b..cf50dfe5 100644 --- a/moon_interface/moon_interface/authz_requests.py +++ b/moon_interface/moon_interface/authz_requests.py @@ -53,7 +53,9 @@ class AuthzRequest: raise exceptions.AuthzException( "error in address no hostname or hostip" ) + tried_hostnames = [] while tries < 2: + tried_hostnames.append(hostname) try: req = requests.post("http://{}:{}/authz".format( hostname, @@ -62,18 +64,20 @@ class AuthzRequest: if req.status_code != 200: raise exceptions.AuthzException( "Receive bad response from Authz function " - "(with address - {})".format(req.status_code) + "(with {} -> {})".format(hostname, req.status_code) ) success = True - break except requests.exceptions.ConnectionError: - logger.error("Cannot connect to {}".format( - "http://{}:{}/authz".format( - hostname, - self.container_chaining[0]["port"] - ))) - except: - logger.error("Unexpected error:", sys.exc_info()[0]) + if tries > 1: + logger.error("Cannot connect to {}".format( + "http://[{}]:{}/authz".format( + ", ".join(tried_hostnames), + self.container_chaining[0]["port"] + ))) + except Exception as e: + logger.exception(e) + else: + break hostname = self.container_chaining[0]["hostname"], tries += 1 diff --git a/moon_interface/moon_interface/http_server.py b/moon_interface/moon_interface/http_server.py index 1e0858c0..50bf2a62 100644 --- a/moon_interface/moon_interface/http_server.py +++ b/moon_interface/moon_interface/http_server.py @@ -9,6 +9,7 @@ import logging from moon_interface import __version__ from moon_interface.api.generic import Status, API from moon_interface.api.authz import Authz +from moon_interface.api.update import Update from moon_interface.authz_requests import CACHE from python_moonutilities import configuration, exceptions @@ -131,6 +132,15 @@ class HTTPServer(Server): self.manager_port), } ) + self.api.add_resource(Update, *Update.__urls__, + resource_class_kwargs={ + "cache": CACHE, + "interface_name": self.host, + "manager_url": "http://{}:{}".format( + self.manager_hostname, + self.manager_port), + } + ) def run(self): self.app.run(host=self._host, port=self._port, threaded=True) # nosec diff --git a/moon_manager/.gitignore b/moon_manager/.gitignore new file mode 100644 index 00000000..894a44cc --- /dev/null +++ b/moon_manager/.gitignore @@ -0,0 +1,104 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/moon_manager/Changelog b/moon_manager/Changelog index 56521a0e..1fb9ac08 100644 --- a/moon_manager/Changelog +++ b/moon_manager/Changelog @@ -31,7 +31,7 @@ CHANGES 4.5.2-1 ----- -integrating validtion to send mandatory key names +- integrating validation to send mandatory key names 4.5.3 ----- @@ -39,4 +39,35 @@ integrating validtion to send mandatory key names - fixing test cases to assert on the expected exception after removing try-catch - allow 404 to be catched from our side instead of flask itself - revert the params in the get/post/patch/delete to be by default = None, so that we could catch the param if it was None -instead of having not found url if the param is mandatory \ No newline at end of file +instead of having not found url if the param is mandatory + +4.5.4 +----- +- fixing test cases after validation dependencies added in moondb + +4.5.5 +----- +- removing validation on meta_rule categories +- Update to python_moonutilities 1.4.17 and fix tests +- adding extra test cases for update requests +- adding None to requests ( to avoid request not found) +- removing validation on categories, meta_rules so that can be added empty + +4.5.5-1 +------- +- Update to python_moonutilities 1.4.18 + +4.5.5-2 +------- +- Update to python_moonutilities 1.4.19 + +4.5.6 +---- +apply pyLint +adding extra test cases for policy update +- separate perimeter add/update with validation + +4.6.0 +----- +- Add a connection to the Update endpoint in Wrapper +>>>>>>> Stashed changes diff --git a/moon_manager/moon_manager/__init__.py b/moon_manager/moon_manager/__init__.py index 205f6d8c..f0887748 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.5.3" +__version__ = "4.6.0" diff --git a/moon_manager/moon_manager/api/assignments.py b/moon_manager/moon_manager/api/assignments.py index 426789e6..9bc54b2d 100644 --- a/moon_manager/moon_manager/api/assignments.py +++ b/moon_manager/moon_manager/api/assignments.py @@ -6,10 +6,11 @@ Assignments allow to connect data with elements of perimeter """ - +import flask from flask import request from flask_restful import Resource import logging +import requests from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager from python_moonutilities.security_functions import validate_input @@ -19,6 +20,35 @@ __version__ = "4.3.2" logger = logging.getLogger("moon.manager.api." + __name__) +def invalidate_data_in_slaves( + policy_id, + perimeter_id, + category_id, + data_id): + slaves = requests.get("http://{}/slaves".format(request.host)).json().get("slaves") + for slave in slaves: + if not slave.get("configured", False): + continue + try: + update = requests.put("http://{}:{}/update".format( + slave.get("wrapper_name"), slave.get("internal_port")), + data={ + "policy_id": policy_id, + "perimeter_id": perimeter_id, + "category_id": category_id, + "data_id": data_id + }, + timeout=1 + ) + logger.info("result {} {}:{} = {}".format( + update.status_code, + slave.get("wrapper_name"), + slave.get("internal_port"), + update.text)) + except requests.exceptions.ConnectionError: + logger.warning("Cannot reach {}:{}".format(slave.get("wrapper_name"), slave.get("port"))) + + class SubjectAssignments(Resource): """ Endpoint for subject assignment requests @@ -32,9 +62,9 @@ class SubjectAssignments(Resource): "/policies//subject_assignments///", ) - @validate_input("get", kwargs_state=[True, False, False,False,False]) + @validate_input("get", kwargs_state=[True, False, False, False, False]) @check_auth - def get(self, uuid, perimeter_id=None, category_id=None, + def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Retrieve all subject assignments or a specific one for a given policy @@ -60,9 +90,10 @@ class SubjectAssignments(Resource): return {"subject_assignments": data} - @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True}) + @validate_input("post", kwargs_state=[True, False, False, False, False], + body_state={"id": True, "category_id": True, "data_id": True}) @check_auth - def post(self, uuid, perimeter_id=None, category_id=None, + def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Create a subject assignment. @@ -93,11 +124,17 @@ class SubjectAssignments(Resource): user_id=user_id, policy_id=uuid, subject_id=perimeter_id, category_id=category_id, data_id=data_id) + invalidate_data_in_slaves( + policy_id=uuid, + perimeter_id=perimeter_id, + category_id=category_id, + data_id=data_id) + return {"subject_assignments": data} @validate_input("delete", kwargs_state=[True, True, True, True, False]) @check_auth - def delete(self, uuid, perimeter_id=None, category_id=None, + def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Delete a subject assignment for a given policy @@ -117,6 +154,11 @@ class SubjectAssignments(Resource): user_id=user_id, policy_id=uuid, subject_id=perimeter_id, category_id=category_id, data_id=data_id) + invalidate_data_in_slaves( + policy_id=uuid, + perimeter_id=perimeter_id, + category_id=category_id, + data_id=data_id) return {"result": True} @@ -134,9 +176,9 @@ class ObjectAssignments(Resource): "/policies//object_assignments///", ) - @validate_input("get", kwargs_state=[True, False, False,False,False]) + @validate_input("get", kwargs_state=[True, False, False, False, False]) @check_auth - def get(self, uuid, perimeter_id=None, category_id=None, + def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Retrieve all object assignment or a specific one for a given policy @@ -162,9 +204,10 @@ class ObjectAssignments(Resource): return {"object_assignments": data} - @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True}) + @validate_input("post", kwargs_state=[True, False, False, False, False], + body_state={"id": True, "category_id": True, "data_id": True}) @check_auth - def post(self, uuid, perimeter_id=None, category_id=None, + def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Create an object assignment. @@ -196,12 +239,17 @@ class ObjectAssignments(Resource): user_id=user_id, policy_id=uuid, object_id=perimeter_id, category_id=category_id, data_id=data_id) + invalidate_data_in_slaves( + policy_id=uuid, + perimeter_id=perimeter_id, + category_id=category_id, + data_id=data_id) return {"object_assignments": data} @validate_input("delete", kwargs_state=[True, True, True, True, False]) @check_auth - def delete(self, uuid, perimeter_id=None, category_id=None, + def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Delete a object assignment for a given policy @@ -220,6 +268,11 @@ class ObjectAssignments(Resource): user_id=user_id, policy_id=uuid, object_id=perimeter_id, category_id=category_id, data_id=data_id) + invalidate_data_in_slaves( + policy_id=uuid, + perimeter_id=perimeter_id, + category_id=category_id, + data_id=data_id) return {"result": True} @@ -237,9 +290,9 @@ class ActionAssignments(Resource): "/policies//action_assignments///", ) - @validate_input("get", kwargs_state=[True, False, False,False,False]) + @validate_input("get", kwargs_state=[True, False, False, False, False]) @check_auth - def get(self, uuid, perimeter_id=None, category_id=None, + def get(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Retrieve all action assignment or a specific one for a given policy @@ -264,9 +317,10 @@ class ActionAssignments(Resource): return {"action_assignments": data} - @validate_input("post", kwargs_state=[True, False, False, False, False], body_state={"id":True, "category_id":True, "data_id":True}) + @validate_input("post", kwargs_state=[True, False, False, False, False], + body_state={"id": True, "category_id": True, "data_id": True}) @check_auth - def post(self, uuid, perimeter_id=None, category_id=None, + def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Create an action assignment. @@ -298,12 +352,17 @@ class ActionAssignments(Resource): user_id=user_id, policy_id=uuid, action_id=perimeter_id, category_id=category_id, data_id=data_id) + invalidate_data_in_slaves( + policy_id=uuid, + perimeter_id=perimeter_id, + category_id=category_id, + data_id=data_id) return {"action_assignments": data} @validate_input("delete", kwargs_state=[True, True, True, True, False]) @check_auth - def delete(self, uuid, perimeter_id=None, category_id=None, + def delete(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): """Delete a action assignment for a given policy @@ -323,5 +382,10 @@ class ActionAssignments(Resource): user_id=user_id, policy_id=uuid, action_id=perimeter_id, category_id=category_id, data_id=data_id) + invalidate_data_in_slaves( + policy_id=uuid, + perimeter_id=perimeter_id, + category_id=category_id, + data_id=data_id) return {"result": True} diff --git a/moon_manager/moon_manager/api/base_exception.py b/moon_manager/moon_manager/api/base_exception.py index 0af3b6d0..0a414a59 100644 --- a/moon_manager/moon_manager/api/base_exception.py +++ b/moon_manager/moon_manager/api/base_exception.py @@ -1,4 +1,3 @@ - class BaseException(Exception): def __init__(self, message): self._code = 500 @@ -15,4 +14,4 @@ class BaseException(Exception): return self._message def __str__(self): - return "Error " + str(self._code) + " " + self.__class__.__name__ + ': ' + self.message \ No newline at end of file + return "Error " + str(self._code) + " " + self.__class__.__name__ + ': ' + self.message diff --git a/moon_manager/moon_manager/api/data.py b/moon_manager/moon_manager/api/data.py index d887ac2b..92d7b2c6 100644 --- a/moon_manager/moon_manager/api/data.py +++ b/moon_manager/moon_manager/api/data.py @@ -28,13 +28,12 @@ class SubjectData(Resource): "/policies//subject_data", "/policies//subject_data/", "/policies//subject_data/", - "/policies//subject_data//" - "", + "/policies//subject_data//", ) @validate_input("get", kwargs_state=[True, False, False, False]) @check_auth - def get(self, uuid, category_id=None, data_id=None, user_id=None): + def get(self, uuid=None, category_id=None, data_id=None, user_id=None): """Retrieve all subject categories or a specific one if data_id is given for a given policy @@ -63,9 +62,9 @@ class SubjectData(Resource): return {"subject_data": data} - @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True}) + @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name": True}) @check_auth - def post(self, uuid, category_id=None, data_id=None, user_id=None): + def post(self, uuid=None, category_id=None, data_id=None, user_id=None): """Create or update a subject. :param uuid: uuid of the policy @@ -90,14 +89,14 @@ class SubjectData(Resource): """ data = PolicyManager.set_subject_data(user_id=user_id, policy_id=uuid, - category_id=category_id, - value=request.json) + category_id=category_id, + value=request.json) return {"subject_data": data} @validate_input("delete", kwargs_state=[True, False, False, False]) @check_auth - def delete(self, uuid, category_id=None, data_id=None, user_id=None): + def delete(self, uuid=None, category_id=None, data_id=None, user_id=None): """Delete a subject for a given policy :param uuid: uuid of the policy @@ -113,6 +112,7 @@ class SubjectData(Resource): logger.info("api.delete {} {}".format(uuid, data_id)) data = PolicyManager.delete_subject_data(user_id=user_id, policy_id=uuid, + category_id=category_id, data_id=data_id) return {"result": True} @@ -133,7 +133,7 @@ class ObjectData(Resource): @validate_input("get", kwargs_state=[True, False, False, False]) @check_auth - def get(self, uuid, category_id=None, data_id=None, user_id=None): + def get(self, uuid=None, category_id=None, data_id=None, user_id=None): """Retrieve all object categories or a specific one if sid is given for a given policy @@ -160,9 +160,9 @@ class ObjectData(Resource): return {"object_data": data} - @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True}) + @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name": True}) @check_auth - def post(self, uuid, category_id=None, data_id=None, user_id=None): + def post(self, uuid=None, category_id=None, data_id=None, user_id=None): """Create or update a object. :param uuid: uuid of the policy @@ -194,7 +194,7 @@ class ObjectData(Resource): @validate_input("delete", kwargs_state=[True, False, False, False]) @check_auth - def delete(self, uuid, category_id=None, data_id=None, user_id=None): + def delete(self, uuid=None, category_id=None, data_id=None, user_id=None): """Delete a object for a given policy :param uuid: uuid of the policy @@ -209,6 +209,7 @@ class ObjectData(Resource): """ data = PolicyManager.delete_object_data(user_id=user_id, policy_id=uuid, + category_id=category_id, data_id=data_id) return {"result": True} @@ -229,7 +230,7 @@ class ActionData(Resource): @validate_input("get", kwargs_state=[True, False, False, False]) @check_auth - def get(self, uuid, category_id=None, data_id=None, user_id=None): + def get(self, uuid=None, category_id=None, data_id=None, user_id=None): """Retrieve all action categories or a specific one if sid is given for a given policy @@ -256,9 +257,9 @@ class ActionData(Resource): return {"action_data": data} - @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name":True}) + @validate_input("post", kwargs_state=[True, True, False, False], body_state={"name": True}) @check_auth - def post(self, uuid, category_id=None, data_id=None, user_id=None): + def post(self, uuid=None, category_id=None, data_id=None, user_id=None): """Create or update a action. :param uuid: uuid of the policy @@ -289,7 +290,7 @@ class ActionData(Resource): @validate_input("delete", kwargs_state=[True, False, False, False]) @check_auth - def delete(self, uuid, category_id=None, data_id=None, user_id=None): + def delete(self, uuid=None, category_id=None, data_id=None, user_id=None): """Delete a action for a given policy :param uuid: uuid of the policy @@ -304,8 +305,7 @@ class ActionData(Resource): """ data = PolicyManager.delete_action_data(user_id=user_id, policy_id=uuid, + category_id=category_id, data_id=data_id) return {"result": True} - - diff --git a/moon_manager/moon_manager/api/generic.py b/moon_manager/moon_manager/api/generic.py index c79520f7..721f6213 100644 --- a/moon_manager/moon_manager/api/generic.py +++ b/moon_manager/moon_manager/api/generic.py @@ -122,13 +122,16 @@ class API(Resource): api_desc[api_name]["version"] = group_api_obj.__version__ object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj))) - for obj in map(lambda x: eval("moon_manager.api.{}.{}".format(api_name, x)), object_list): + for obj in map(lambda x: eval("moon_manager.api.{}.{}".format(api_name, x)), + object_list): if "__urls__" in dir(obj): api_desc[api_name][obj.__name__] = dict() api_desc[api_name][obj.__name__]["urls"] = obj.__urls__ api_desc[api_name][obj.__name__]["methods"] = dict() for _method in filter(lambda x: x in __methods, dir(obj)): - docstring = eval("moon_manager.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method)) + docstring = eval( + "moon_manager.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, + _method)) api_desc[api_name][obj.__name__]["methods"][_method] = docstring api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__) if group_id in api_desc: diff --git a/moon_manager/moon_manager/api/json_export.py b/moon_manager/moon_manager/api/json_export.py index 1d3643e7..069e5884 100644 --- a/moon_manager/moon_manager/api/json_export.py +++ b/moon_manager/moon_manager/api/json_export.py @@ -17,7 +17,6 @@ logger = logging.getLogger("moon.manager.api." + __name__) class JsonExport(Resource): - __urls__ = ( "/export", "/export/", @@ -35,22 +34,37 @@ class JsonExport(Resource): 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) + JsonUtils.convert_id_to_name(rule["meta_rule_id"], rule_dict, "meta_rule", + "meta_rule", ModelManager, self._user_id) + JsonUtils.convert_id_to_name(policy_key, rule_dict, "policy", "policy", + PolicyManager, self._user_id) ids = rule["rule"] rule_description = dict() meta_rule = ModelManager.get_meta_rules(self._user_id, rule["meta_rule_id"]) meta_rule = [v for v in meta_rule.values()] meta_rule = meta_rule[0] - index_subject_data = len(meta_rule["subject_categories"])-1 - index_object_data = len(meta_rule["subject_categories"]) + len(meta_rule["object_categories"])-1 - index_action_data = len(meta_rule["subject_categories"]) + len(meta_rule["object_categories"]) + len(meta_rule["action_categories"])-1 - ids_subject_data = [ids[0]] if len(meta_rule["subject_categories"]) == 1 else ids[0:index_subject_data] - ids_object_data = [ids[index_object_data]] if len(meta_rule["object_categories"]) == 1 else ids[index_subject_data+1:index_object_data] - ids_action_date = [ids[index_action_data]] if len(meta_rule["action_categories"]) == 1 else ids[index_object_data+1:index_action_data] - JsonUtils.convert_ids_to_names(ids_subject_data, rule_description, "subject_data", "subject_data", PolicyManager, self._user_id, policy_key) - JsonUtils.convert_ids_to_names(ids_object_data, rule_description, "object_data", "object_data", PolicyManager, self._user_id, policy_key) - JsonUtils.convert_ids_to_names(ids_action_date, rule_description, "action_data", "action_data", PolicyManager, self._user_id, policy_key) + index_subject_data = len(meta_rule["subject_categories"]) - 1 + index_object_data = len(meta_rule["subject_categories"]) + len( + meta_rule["object_categories"]) - 1 + index_action_data = len(meta_rule["subject_categories"]) + len( + meta_rule["object_categories"]) + len(meta_rule["action_categories"]) - 1 + ids_subject_data = [ids[0]] if len(meta_rule["subject_categories"]) == 1 else ids[ + 0:index_subject_data] + ids_object_data = [ids[index_object_data]] if len( + meta_rule["object_categories"]) == 1 else ids[ + index_subject_data + 1:index_object_data] + ids_action_date = [ids[index_action_data]] if len( + meta_rule["action_categories"]) == 1 else ids[ + index_object_data + 1:index_action_data] + JsonUtils.convert_ids_to_names(ids_subject_data, rule_description, "subject_data", + "subject_data", PolicyManager, self._user_id, + policy_key) + JsonUtils.convert_ids_to_names(ids_object_data, rule_description, "object_data", + "object_data", PolicyManager, self._user_id, + policy_key) + JsonUtils.convert_ids_to_names(ids_action_date, rule_description, "action_data", + "action_data", PolicyManager, self._user_id, + policy_key) rule_dict["rule"] = rule_description rules_array.append(rule_dict) @@ -62,13 +76,20 @@ class JsonExport(Resource): meta_rules_array = [] # logger.info(meta_rules) for meta_rule_key in meta_rules: - #logger.info(meta_rules[meta_rule_key]) + # 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) + 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: @@ -80,12 +101,20 @@ class JsonExport(Resource): element_assignments_array = [] for policy_key in policies: assignments = export_method_data(self._user_id, policy_key) - #logger.info(assignments) + # 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) + 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: @@ -97,7 +126,7 @@ class JsonExport(Resource): element_datas_array = [] for policy_key in policies: datas = export_method_data(self._user_id, policy_key) - #logger.info("data found : {}".format(datas)) + # logger.info("data found : {}".format(datas)) for data_group in datas: policy_id = data_group["policy_id"] category_id = data_group["category_id"] @@ -105,14 +134,21 @@ class JsonExport(Resource): 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) + 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.copy_field_if_exists(data_group["data"][data_key], data_dict, + "name", str) + JsonUtils.copy_field_if_exists(data_group["data"][data_key], data_dict, + "description", str) - JsonUtils.convert_id_to_name(policy_id, data_dict, "policy", "policy", PolicyManager, self._user_id) - JsonUtils.convert_id_to_name(category_id, data_dict, "category", type_element + "_category", ModelManager, self._user_id, policy_key) + 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) @@ -125,8 +161,10 @@ class JsonExport(Resource): 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) + 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: @@ -140,7 +178,7 @@ class JsonExport(Resource): 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])) + # 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) @@ -149,7 +187,8 @@ class JsonExport(Resource): 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)}) + 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])) @@ -166,7 +205,8 @@ class JsonExport(Resource): 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) + 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: @@ -180,7 +220,8 @@ class JsonExport(Resource): 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) + 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: diff --git a/moon_manager/moon_manager/api/json_import.py b/moon_manager/moon_manager/api/json_import.py index e57a27c1..05f4a0c0 100644 --- a/moon_manager/moon_manager/api/json_import.py +++ b/moon_manager/moon_manager/api/json_import.py @@ -19,7 +19,6 @@ 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__) @@ -32,64 +31,61 @@ CATEGORIES_CALLBACK = 3 class ForbiddenOverride(BaseException): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(ForbiddenOverride, self).__init__(message) class UnknownPolicy(BaseException): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(UnknownPolicy, self).__init__(message) class UnknownModel(BaseException): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(UnknownModel, self).__init__(message) class UnknownData(BaseException): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(UnknownData, self).__init__(message) class MissingPolicy(BaseException): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(MissingPolicy, self).__init__(message) class InvalidJson(BaseException): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(InvalidJson, self).__init__(message) class JsonImport(Resource): - __urls__ = ( "/import", "/import/", ) - def _reorder_rules_ids(self, rule, ordered_perimeter_categories_ids, json_data_ids, policy_id, get_function): - ordered_json_ids = [None]*len(ordered_perimeter_categories_ids) + def _reorder_rules_ids(self, rule, ordered_perimeter_categories_ids, json_data_ids, policy_id, + get_function): + ordered_json_ids = [None] * len(ordered_perimeter_categories_ids) for json_id in json_data_ids: data = get_function(self._user_id, policy_id, data_id=json_id) data = data[0] if data["category_id"] not in ordered_perimeter_categories_ids: - raise InvalidJson("The category id {} of the rule {} does not match the meta rule".format( - data["category_id"], rule)) - if ordered_json_ids[ordered_perimeter_categories_ids.index(data["category_id"])] is not None: - raise InvalidJson("The category id {} of the rule {} shall not be used twice in the same rule".format( - data["category_id"], rule)) + raise InvalidJson( + "The category id {} of the rule {} does not match the meta rule".format( + data["category_id"], rule)) + if ordered_json_ids[ + ordered_perimeter_categories_ids.index(data["category_id"])] is not None: + raise InvalidJson( + "The category id {} of the rule {} shall not be used twice in the same rule".format( + data["category_id"], rule)) ordered_json_ids[ordered_perimeter_categories_ids.index(data["category_id"])] = json_id logger.info(ordered_json_ids) return ordered_json_ids @@ -101,30 +97,46 @@ class JsonImport(Resource): 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) + 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) + JsonUtils.convert_name_to_id(json_rule, json_to_use, "meta_rule", "meta_rule_id", + "meta_rule", ModelManager, self._user_id) json_subject_ids = dict() json_object_ids = dict() json_action_ids = dict() - JsonUtils.convert_names_to_ids(json_rule["rule"], json_subject_ids, "subject_data", "subject", "subject_data", PolicyManager, self._user_id, json_ids["policy_id"]) - JsonUtils.convert_names_to_ids(json_rule["rule"], json_object_ids, "object_data", "object", "object_data", PolicyManager, self._user_id, json_ids["policy_id"]) - JsonUtils.convert_names_to_ids(json_rule["rule"], json_action_ids, "action_data", "action", "action_data", PolicyManager, self._user_id, json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_subject_ids, "subject_data", + "subject", "subject_data", PolicyManager, self._user_id, + json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_object_ids, "object_data", + "object", "object_data", PolicyManager, self._user_id, + json_ids["policy_id"]) + JsonUtils.convert_names_to_ids(json_rule["rule"], json_action_ids, "action_data", + "action", "action_data", PolicyManager, self._user_id, + json_ids["policy_id"]) meta_rule = ModelManager.get_meta_rules(self._user_id, json_to_use["meta_rule_id"]) meta_rule = [v for v in meta_rule.values()] meta_rule = meta_rule[0] - json_to_use_rule = self._reorder_rules_ids(json_rule, meta_rule["subject_categories"], json_subject_ids["subject"], json_ids["policy_id"], PolicyManager.get_subject_data) - json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule["object_categories"], json_object_ids["object"], json_ids["policy_id"], PolicyManager.get_object_data) - json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule["action_categories"], json_action_ids["action"], json_ids["policy_id"], PolicyManager.get_action_data) + json_to_use_rule = self._reorder_rules_ids(json_rule, meta_rule["subject_categories"], + json_subject_ids["subject"], + json_ids["policy_id"], + PolicyManager.get_subject_data) + json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule[ + "object_categories"], json_object_ids["object"], json_ids["policy_id"], + PolicyManager.get_object_data) + json_to_use_rule = json_to_use_rule + self._reorder_rules_ids(json_rule, meta_rule[ + "action_categories"], json_action_ids["action"], json_ids["policy_id"], + PolicyManager.get_action_data) json_to_use["rule"] = json_to_use_rule try: logger.debug("Adding / updating a rule from json {}".format(json_to_use)) - PolicyManager.add_rule(self._user_id, json_ids["policy_id"], json_to_use["meta_rule_id"], json_to_use) + 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: @@ -136,11 +148,18 @@ class JsonImport(Resource): json_to_use = dict() JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "name", str) JsonUtils.copy_field_if_exists(json_meta_rule, json_to_use, "description", str) - JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "subject_categories", "subject_categories", "subject_category", ModelManager, self._user_id) - JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "object_categories", "object_categories", "object_category", ModelManager, self._user_id) - JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "action_categories", "action_categories", "action_category", ModelManager, self._user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "subject_categories", + "subject_categories", "subject_category", ModelManager, + self._user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "object_categories", + "object_categories", "object_category", ModelManager, + self._user_id) + JsonUtils.convert_names_to_ids(json_meta_rule, json_to_use, "action_categories", + "action_categories", "action_category", ModelManager, + self._user_id) logger.debug("Adding / updating a metarule from json {}".format(json_meta_rule)) - meta_rule = ModelManager.add_meta_rule(self._user_id, meta_rule_id=None, value=json_to_use) + meta_rule = ModelManager.add_meta_rule(self._user_id, meta_rule_id=None, + value=json_to_use) logger.debug("Added / updated meta rule : {}".format(meta_rule)) def _import_subject_object_action_assignments(self, json_item_assignments, type_element): @@ -156,29 +175,40 @@ class JsonImport(Resource): 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)) + 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) + 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"]) + 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"]) + data = get_method(self._user_id, policy_id, data_id, + json_assignment["category_id"]) if data is not None and len(data) == 1: - logger.debug("Adding / updating a {} assignment from json {}".format(type_element, - json_assignment)) - import_method(self._user_id, policy_id, json_assignment["id"], json_assignment["category_id"], + logger.debug( + "Adding / updating a {} assignment from json {}".format(type_element, + json_assignment)) + import_method(self._user_id, policy_id, json_assignment["id"], + json_assignment["category_id"], data_id) else: raise UnknownData("Unknown data with id {}".format(data_id)) @@ -189,7 +219,8 @@ class JsonImport(Resource): type_element, json_item_assignment)) - def _import_subject_object_action_datas(self, json_items_data, mandatory_policy_ids, type_element): + 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: @@ -202,16 +233,20 @@ class JsonImport(Resource): 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)) + raise ForbiddenOverride( + "{} datas do not support override flag !".format(type_element)) json_to_use = dict() JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "name", str) JsonUtils.copy_field_if_exists(json_item_data, json_to_use, "description", str) json_policy = dict() # field_mandatory : not mandatory if there is some mandatory policies - JsonUtils.convert_names_to_ids(json_item_data, json_policy, "policies", "policy_id", "policy", - PolicyManager, self._user_id, field_mandatory=len(mandatory_policy_ids) == 0) + JsonUtils.convert_names_to_ids(json_item_data, json_policy, "policies", "policy_id", + "policy", + PolicyManager, self._user_id, + field_mandatory=len(mandatory_policy_ids) == 0) json_category = dict() - JsonUtils.convert_name_to_id(json_item_data, json_category, "category", "category_id", type_element+"_category", + JsonUtils.convert_name_to_id(json_item_data, json_category, "category", "category_id", + type_element + "_category", ModelManager, self._user_id) policy_ids = [] if "policy_id" in json_policy: @@ -222,16 +257,20 @@ class JsonImport(Resource): 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)) + 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)) + raise InvalidJson( + "Invalid data, the category shall be set when importing {}".format( + json_item_data)) for policy_id in mandatory_policy_ids: try: - data = import_method(self._user_id, policy_id, category_id=category_id, value=json_to_use) + data = import_method(self._user_id, policy_id, category_id=category_id, + value=json_to_use) except exceptions.PolicyUnknown: raise UnknownPolicy("Unknown policy with id {}".format(policy_id)) except Exception as e: @@ -260,13 +299,16 @@ class JsonImport(Resource): 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)) + raise ForbiddenOverride( + "{} categories do not support override flag !".format(type_element)) try: category = import_method(self._user_id, existing_id, json_to_use) - except (exceptions.SubjectCategoryExisting, exceptions.ObjectCategoryExisting, exceptions.ActionCategoryExisting): + 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"])) + 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)) @@ -284,7 +326,9 @@ class JsonImport(Resource): 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) + 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: @@ -297,7 +341,9 @@ class JsonImport(Resource): 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))) + 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: @@ -307,7 +353,8 @@ class JsonImport(Resource): if items_in_db[key_in_db]["name"] == json_without_policy_name["name"]: key = key_in_db break - element = import_method(self._user_id, policy_id, perimeter_id=key, value=json_without_policy_name) + element = import_method(self._user_id, policy_id, perimeter_id=key, + value=json_without_policy_name) logger.debug("Added / updated {} : {}".format(type_element, element)) except exceptions.PolicyUnknown: @@ -344,24 +391,29 @@ class JsonImport(Resource): if policy_override is False and policy_does_exist: if policy_id: policy_mandatory_ids.append(policy_id) - logger.warning("Existing policy not updated because of the override option is not set !") + 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) + JsonUtils.convert_name_to_id(json_policy, json_without_model_name, "model", "model_id", + "model", ModelManager, self._user_id, + field_mandatory=False) if not policy_does_exist: logger.debug("Creating policy {} ".format(json_without_model_name)) - added_policy = PolicyManager.add_policy(self._user_id, None, json_without_model_name) + added_policy = PolicyManager.add_policy(self._user_id, None, + json_without_model_name) if policy_mandatory is True: keys = list(added_policy.keys()) policy_mandatory_ids.append(keys[0]) elif policy_override is True: logger.debug("Updating policy {} ".format(json_without_model_name)) - updated_policy = PolicyManager.update_policy(self._user_id, policy_id, json_without_model_name) + updated_policy = PolicyManager.update_policy(self._user_id, policy_id, + json_without_model_name) if policy_mandatory is True: policy_mandatory_ids.append(policy_id) return policy_mandatory_ids @@ -376,7 +428,8 @@ class JsonImport(Resource): 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"]): + 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 @@ -385,7 +438,8 @@ class JsonImport(Resource): raise UnknownModel("Unknown model ") json_key = dict() - JsonUtils.convert_names_to_ids(json_model, json_key, "meta_rules", "meta_rule_id", "meta_rule", ModelManager, self._user_id) + JsonUtils.convert_names_to_ids(json_model, json_key, "meta_rules", "meta_rule_id", + "meta_rule", ModelManager, self._user_id) for meta_rule_id in json_key["meta_rule_id"]: if meta_rule_id not in model_in_db["meta_rules"]: model_in_db["meta_rules"].append(meta_rule_id) @@ -410,18 +464,20 @@ class JsonImport(Resource): model_id = model_key # end TODO - JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "description", str) + JsonUtils.copy_field_if_exists(json_model, json_without_new_metarules, "description", + str) if model_in_db is None: model_does_exist = False else: - json_without_new_metarules["meta_rule_id"] = model_in_db["meta_rules"] + 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)) ModelManager.add_model(self._user_id, None, json_without_new_metarules) elif model_override is True: - logger.debug("Updating model with id {} : {} ".format(model_id, json_without_new_metarules)) + logger.debug( + "Updating model with id {} : {} ".format(model_id, json_without_new_metarules)) ModelManager.update_model(self._user_id, model_id, json_without_new_metarules) def _import_pdps(self, json_pdps): @@ -477,10 +533,6 @@ class JsonImport(Resource): 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: @@ -492,6 +544,14 @@ class JsonImport(Resource): logger.info("Updating models with meta rules...") self._import_models_with_new_meta_rules(json_content["models"]) + for elt in list_element: + in_key = elt["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 subjects assignments, idem for object and action for elt in list_element: in_key = elt["key"] diff --git a/moon_manager/moon_manager/api/json_utils.py b/moon_manager/moon_manager/api/json_utils.py index cc4c8b0f..6a5830f1 100644 --- a/moon_manager/moon_manager/api/json_utils.py +++ b/moon_manager/moon_manager/api/json_utils.py @@ -6,28 +6,24 @@ 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) @@ -64,7 +60,8 @@ class JsonUtils: 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): + 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) @@ -85,11 +82,14 @@ class JsonUtils: 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) + 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) + 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) + 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: @@ -101,15 +101,16 @@ class JsonUtils: 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: + # 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): + 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: + # if len(data_db["data"].values()) != 1: # raise Exception("Several {} with the same id : {}".format(element_type, data_db)) - #data_db = data_db["data"] + # 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] @@ -117,7 +118,8 @@ class JsonUtils: 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): + 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": @@ -156,7 +158,8 @@ class JsonUtils: 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... + 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] @@ -167,20 +170,31 @@ class JsonUtils: 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): + 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) + 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"])) + 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) + 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"])) + 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)) @@ -188,7 +202,9 @@ class JsonUtils: @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)} + 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): @@ -203,9 +219,10 @@ class JsonUtils: @staticmethod def convert_id_to_name_string(id_, element_type, manager, user_id, - policy_id=None, category_id=None, meta_rule_id=None): + 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) + 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_)) @@ -218,31 +235,42 @@ class JsonUtils: 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): + 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) + 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"])) + 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) + 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"])) + 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): + 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) + 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) @@ -252,4 +280,3 @@ class JsonUtils: if "value" in res and "name" in res["value"]: res_array.append({"name": res["value"]["name"]}) json_out[field_name_out] = res_array - diff --git a/moon_manager/moon_manager/api/meta_data.py b/moon_manager/moon_manager/api/meta_data.py index 62ca050f..b0b86d10 100644 --- a/moon_manager/moon_manager/api/meta_data.py +++ b/moon_manager/moon_manager/api/meta_data.py @@ -30,7 +30,7 @@ class SubjectCategories(Resource): "/subject_categories/", ) - @validate_input("get",kwargs_state=[False,False]) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, category_id=None, user_id=None): """Retrieve all subject categories or a specific one @@ -50,7 +50,7 @@ class SubjectCategories(Resource): return {"subject_categories": data} - @validate_input("post",body_state={"name":True}) + @validate_input("post", body_state={"name": True}) @check_auth def post(self, category_id=None, user_id=None): """Create or update a subject category. @@ -74,7 +74,7 @@ class SubjectCategories(Resource): return {"subject_categories": data} - @validate_input("delete",kwargs_state=[True,False]) + @validate_input("delete", kwargs_state=[True, False]) @check_auth def delete(self, category_id=None, user_id=None): """Delete a subject category @@ -105,7 +105,7 @@ class ObjectCategories(Resource): "/object_categories/", ) - @validate_input("get",kwargs_state=[False,False]) + @validate_input("get", kwargs_state=[False, False]) @check_auth def get(self, category_id=None, user_id=None): """Retrieve all object categories or a specific one @@ -125,7 +125,7 @@ class ObjectCategories(Resource): return {"object_categories": data} - @validate_input("post", body_state={"name":True}) + @validate_input("post", body_state={"name": True}) @check_auth def post(self, category_id=None, user_id=None): """Create or update a object category. @@ -202,7 +202,7 @@ class ActionCategories(Resource): return {"action_categories": data} - @validate_input("post", body_state={"name":True}) + @validate_input("post", body_state={"name": True}) @check_auth def post(self, category_id=None, user_id=None): """Create or update an action category. diff --git a/moon_manager/moon_manager/api/meta_rules.py b/moon_manager/moon_manager/api/meta_rules.py index 3dc9996b..738aad71 100644 --- a/moon_manager/moon_manager/api/meta_rules.py +++ b/moon_manager/moon_manager/api/meta_rules.py @@ -57,7 +57,8 @@ class MetaRules(Resource): return {"meta_rules": data} - @validate_input("post", body_state={"name":True, "subject_categories":True, "object_categories":True, "action_categories":True}) + @validate_input("post", body_state={"name": True, "subject_categories": False, + "object_categories": False, "action_categories": False}) @check_auth def post(self, meta_rule_id=None, user_id=None): """Add a meta rule @@ -90,7 +91,9 @@ class MetaRules(Resource): return {"meta_rules": data} - @validate_input("patch", kwargs_state=[True, False], body_state={"name":True, "subject_categories":True, "object_categories":True, "action_categories":True}) + @validate_input("patch", kwargs_state=[True, False], + body_state={"name": True, "subject_categories": False, + "object_categories": False, "action_categories": False}) @check_auth def patch(self, meta_rule_id=None, user_id=None): """Update a meta rule @@ -117,7 +120,7 @@ class MetaRules(Resource): } :internal_api: set_meta_rules """ - data = ModelManager.set_meta_rule( + data = ModelManager.update_meta_rule( user_id=user_id, meta_rule_id=meta_rule_id, value=request.json) return {"meta_rules": data} @@ -147,4 +150,3 @@ class MetaRules(Resource): user_id=user_id, meta_rule_id=meta_rule_id) return {"result": True} - diff --git a/moon_manager/moon_manager/api/models.py b/moon_manager/moon_manager/api/models.py index c3068367..c72396cf 100644 --- a/moon_manager/moon_manager/api/models.py +++ b/moon_manager/moon_manager/api/models.py @@ -50,7 +50,7 @@ class Models(Resource): return {"models": data} - @validate_input("post", body_state={"name":True, "meta_rules":True}) + @validate_input("post", body_state={"name": True, "meta_rules": False}) @check_auth def post(self, uuid=None, user_id=None): """Create model. @@ -94,7 +94,8 @@ class Models(Resource): return {"result": True} - @validate_input("patch", kwargs_state=[True, False], body_state={"name":True, "meta_rules":True}) + @validate_input("patch", kwargs_state=[True, False], + body_state={"name": True, "meta_rules": False}) @check_auth def patch(self, uuid=None, user_id=None): """Update a model @@ -114,4 +115,3 @@ class Models(Resource): user_id=user_id, model_id=uuid, value=request.json) return {"models": data} - diff --git a/moon_manager/moon_manager/api/pdp.py b/moon_manager/moon_manager/api/pdp.py index a5d7c007..65a6a5f1 100644 --- a/moon_manager/moon_manager/api/pdp.py +++ b/moon_manager/moon_manager/api/pdp.py @@ -42,9 +42,11 @@ def delete_pod(uuid): for pod_value in pod_list: if "pdp_id" in pod_value: if pod_value["pdp_id"] == uuid: - req = requests.delete("{}://{}:{}/pods/{}".format(proto, hostname, port, pod_key)) + req = requests.delete( + "{}://{}:{}/pods/{}".format(proto, hostname, port, pod_key)) if req.status_code != 200: - logger.warning("Cannot delete pod {} - {}".format(pod_key, pod_value['name'])) + logger.warning( + "Cannot delete pod {} - {}".format(pod_key, pod_value['name'])) logger.debug(req.content) # Note (Asteroide): no need to go further if one match break @@ -119,7 +121,8 @@ class PDP(Resource): return {"pdps": data} - @validate_input("post", body_state={"name": True, "security_pipeline": True, "keystone_project_id": True}) + @validate_input("post", body_state={"name": True, "security_pipeline": True, + "keystone_project_id": True}) @check_auth def post(self, uuid=None, user_id=None): """Create pdp. @@ -176,7 +179,9 @@ class PDP(Resource): return {"result": True} - @validate_input("patch", kwargs_state=[True, False], body_state={"name": True, "security_pipeline": True, "keystone_project_id": True}) + @validate_input("patch", kwargs_state=[True, False], + body_state={"name": True, "security_pipeline": True, + "keystone_project_id": True}) @check_auth def patch(self, uuid, user_id=None): """Update a pdp @@ -207,4 +212,3 @@ class PDP(Resource): add_pod(uuid=uuid, data=data[uuid]) return {"pdps": data} - diff --git a/moon_manager/moon_manager/api/perimeter.py b/moon_manager/moon_manager/api/perimeter.py index 6c39c43d..a0fda4ad 100644 --- a/moon_manager/moon_manager/api/perimeter.py +++ b/moon_manager/moon_manager/api/perimeter.py @@ -17,7 +17,6 @@ from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager from python_moonutilities.security_functions import validate_input - __version__ = "4.3.2" logger = logging.getLogger("moon.manager.api." + __name__) @@ -64,9 +63,9 @@ class Subjects(Resource): return {"subjects": data} - @validate_input("post", body_state={"name":True}) + @validate_input("post", body_state={"name": True}) @check_auth - def post(self, uuid, perimeter_id=None, user_id=None): + def post(self, uuid=None, perimeter_id=None, user_id=None): """Create or update a subject. :param uuid: uuid of the policy @@ -90,23 +89,15 @@ class Subjects(Resource): :internal_api: set_subject """ - if not perimeter_id: - data = PolicyManager.get_subjects(user_id=user_id, - policy_id=uuid) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break data = PolicyManager.add_subject( user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id, value=request.json) return {"subjects": data} - @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True}) + @validate_input("patch", kwargs_state=[False, True, False]) @check_auth - def patch(self, uuid, perimeter_id=None, user_id=None): + def patch(self, uuid=None, perimeter_id=None, user_id=None): """Create or update a subject. :param uuid: uuid of the policy @@ -129,19 +120,8 @@ class Subjects(Resource): } :internal_api: set_subject """ - - if not perimeter_id: - data = PolicyManager.get_subjects(user_id=user_id, - policy_id=None) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_subject( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) - + data = PolicyManager.update_subject(user_id=user_id, perimeter_id=perimeter_id, + value=request.json) return {"subjects": data} @validate_input("delete", kwargs_state=[False, True, False]) @@ -210,9 +190,9 @@ class Objects(Resource): return {"objects": data} - @validate_input("post", body_state={"name":True}) + @validate_input("post", body_state={"name": True}) @check_auth - def post(self, uuid, perimeter_id=None, user_id=None): + def post(self, uuid=None, perimeter_id=None, user_id=None): """Create or update a object. :param uuid: uuid of the policy @@ -230,22 +210,15 @@ class Objects(Resource): } :internal_api: set_object """ - - data = PolicyManager.get_objects(user_id=user_id, policy_id=uuid) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break data = PolicyManager.add_object( user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id, value=request.json) return {"objects": data} - @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True}) + @validate_input("patch", kwargs_state=[False, True, False]) @check_auth - def patch(self, uuid, perimeter_id=None, user_id=None): + def patch(self, uuid=None, perimeter_id=None, user_id=None): """Create or update a object. :param uuid: uuid of the policy @@ -263,16 +236,8 @@ class Objects(Resource): } :internal_api: set_object """ - - data = PolicyManager.get_objects(user_id=user_id, policy_id=uuid) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_object( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) + data = PolicyManager.update_object(user_id=user_id, perimeter_id=perimeter_id, + value=request.json) return {"objects": data} @@ -336,9 +301,9 @@ class Actions(Resource): return {"actions": data} - @validate_input("post", body_state={"name":True}) + @validate_input("post", body_state={"name": True}) @check_auth - def post(self, uuid, perimeter_id=None, user_id=None): + def post(self, uuid=None, perimeter_id=None, user_id=None): """Create or update a action. :param uuid: uuid of the policy @@ -356,22 +321,15 @@ class Actions(Resource): } :internal_api: set_action """ - - data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break data = PolicyManager.add_action( user_id=user_id, policy_id=uuid, perimeter_id=perimeter_id, value=request.json) return {"actions": data} - @validate_input("patch", kwargs_state=[False, True, False], body_state={"name":True}) + @validate_input("patch", kwargs_state=[False, True, False]) @check_auth - def patch(self, uuid, perimeter_id=None, user_id=None): + def patch(self, uuid=None, perimeter_id=None, user_id=None): """Create or update a action. :param uuid: uuid of the policy @@ -389,16 +347,8 @@ class Actions(Resource): } :internal_api: set_action """ - - data = PolicyManager.get_actions(user_id=user_id, policy_id=uuid) - if 'name' in request.json: - for data_id, data_value in data.items(): - if data_value['name'] == request.json['name']: - perimeter_id = data_id - break - data = PolicyManager.add_action( - user_id=user_id, policy_id=uuid, - perimeter_id=perimeter_id, value=request.json) + data = PolicyManager.update_action(user_id=user_id, perimeter_id=perimeter_id, + value=request.json) return {"actions": data} diff --git a/moon_manager/moon_manager/api/policies.py b/moon_manager/moon_manager/api/policies.py index 9fe237b2..3264e8e0 100644 --- a/moon_manager/moon_manager/api/policies.py +++ b/moon_manager/moon_manager/api/policies.py @@ -14,7 +14,6 @@ from python_moonutilities.security_functions import check_auth from python_moondb.core import PolicyManager from python_moonutilities.security_functions import validate_input - __version__ = "4.3.2" logger = logging.getLogger("moon.manager.api." + __name__) @@ -54,7 +53,7 @@ class Policies(Resource): return {"policies": data} - @validate_input("post", body_state={"name": True, "model_id":True}) + @validate_input("post", body_state={"name": True, "model_id": False}) @check_auth def post(self, uuid=None, user_id=None): """Create policy. @@ -83,7 +82,7 @@ class Policies(Resource): return {"policies": data} - @validate_input("delete", kwargs_state=[ True, False]) + @validate_input("delete", kwargs_state=[True, False]) @check_auth def delete(self, uuid=None, user_id=None): """Delete a policy @@ -101,7 +100,8 @@ class Policies(Resource): return {"result": True} - @validate_input("patch", kwargs_state=[True, False], body_state={"name": True, "model_id":True}) + @validate_input("patch", kwargs_state=[True, False], + body_state={"name": True, "model_id": False}) @check_auth def patch(self, uuid=None, user_id=None): """Update a policy @@ -123,4 +123,3 @@ class Policies(Resource): user_id=user_id, policy_id=uuid, value=request.json) return {"policies": data} - diff --git a/moon_manager/moon_manager/api/rules.py b/moon_manager/moon_manager/api/rules.py index a0248097..cbd39969 100644 --- a/moon_manager/moon_manager/api/rules.py +++ b/moon_manager/moon_manager/api/rules.py @@ -51,12 +51,13 @@ class Rules(Resource): """ data = PolicyManager.get_rules(user_id=user_id, - policy_id=uuid, - rule_id=rule_id) + policy_id=uuid, + rule_id=rule_id) return {"rules": data} - @validate_input("post", kwargs_state=[True, False, False], body_state={"meta_rule_id": True, "rule": True, "instructions": True}) + @validate_input("post", kwargs_state=[True, False, False], + body_state={"meta_rule_id": True, "rule": True, "instructions": True}) @check_auth def post(self, uuid=None, rule_id=None, user_id=None): """Add a rule to a meta rule @@ -132,4 +133,3 @@ class Rules(Resource): user_id=user_id, policy_id=uuid, rule_id=rule_id) return {"result": True} - diff --git a/moon_manager/moon_manager/api/slaves.py b/moon_manager/moon_manager/api/slaves.py index 769b681f..e2928de0 100644 --- a/moon_manager/moon_manager/api/slaves.py +++ b/moon_manager/moon_manager/api/slaves.py @@ -16,7 +16,6 @@ from python_moonutilities.security_functions import check_auth from python_moonutilities import configuration from python_moonutilities.security_functions import validate_input - __version__ = "4.3.0" logger = logging.getLogger("moon.manager.api." + __name__) @@ -84,11 +83,11 @@ class Slaves(Resource): """ logger.info("Will made a request for {}".format(uuid)) if request.json.get("op") == "replace" \ - and request.json.get("variable") == "configured" \ + and request.json.get("variable") == "configured" \ and request.json.get("value"): req = requests.post("http://{}:{}/pods".format( self.orchestrator_hostname, self.orchestrator_port, - ), + ), json={"slave_name": uuid} ) if req.status_code != 200: @@ -97,7 +96,7 @@ class Slaves(Resource): )) return "Orchestrator: " + str(req.reason), req.status_code elif request.json.get("op") == "replace" \ - and request.json.get("variable") == "configured" \ + and request.json.get("variable") == "configured" \ and not request.json.get("value"): req = requests.delete("http://{}:{}/pods/{}".format( self.orchestrator_hostname, self.orchestrator_port, uuid diff --git a/moon_manager/moon_manager/http_server.py b/moon_manager/moon_manager/http_server.py index 204e7e04..53879529 100644 --- a/moon_manager/moon_manager/http_server.py +++ b/moon_manager/moon_manager/http_server.py @@ -26,7 +26,6 @@ from moon_manager.api.json_export import JsonExport from python_moonutilities import configuration from python_moondb.core import PDPManager - logger = logging.getLogger("moon.manager.http_server") __API__ = ( @@ -36,7 +35,7 @@ __API__ = ( SubjectAssignments, ObjectAssignments, ActionAssignments, SubjectData, ObjectData, ActionData, Models, Policies, PDP, Slaves, JsonImport, JsonExport - ) +) class Server: @@ -87,7 +86,7 @@ class Root(Resource): """ The root of the web service """ - __urls__ = ("/", ) + __urls__ = ("/",) __methods = ("get", "post", "put", "delete", "options") def get(self): @@ -112,7 +111,8 @@ class CustomApi(Api): @staticmethod def handle_error(e): try: - error_message = dumps({"result": False, 'message': str(e), "code": getattr(e, "code", 500)}) + error_message = dumps( + {"result": False, 'message': str(e), "code": getattr(e, "code", 500)}) logger.error(e, exc_info=True) logger.error(error_message) return make_response(error_message, getattr(e, "code", 500)) diff --git a/moon_manager/moon_manager/server.py b/moon_manager/moon_manager/server.py index a8db8fd5..70ddaee0 100644 --- a/moon_manager/moon_manager/server.py +++ b/moon_manager/moon_manager/server.py @@ -7,7 +7,6 @@ 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/unit_python/api/import_export_utilities.py b/moon_manager/tests/unit_python/api/import_export_utilities.py index 12cb208e..2ee2627d 100644 --- a/moon_manager/tests/unit_python/api/import_export_utilities.py +++ b/moon_manager/tests/unit_python/api/import_export_utilities.py @@ -9,7 +9,7 @@ import api.test_perimeter as test_perimeter import api.test_meta_data as test_categories import api.test_data as test_data import api.test_meta_rules as test_meta_rules -import api.test_assignemnt as test_assignments +import api.test_assignement as test_assignments import api.test_rules as test_rules import logging @@ -38,7 +38,6 @@ def clean_subjects(client): logger.info("subjects policy_keys {}".format(policy_keys)) for policy_key in policy_keys: client.delete("/policies/{}/subjects/{}".format(policy_key, key)) - client.delete("/subjects/{}".format(key)) def clean_objects(client): @@ -50,10 +49,10 @@ def clean_objects(client): logger.info("objects policy_keys {}".format(policy_keys)) for policy_key in policy_keys: client.delete("/policies/{}/objects/{}".format(policy_key, key)) - client.delete("/objects/{}".format(key)) def clean_actions(client): + actions = test_perimeter.get_actions(client) actions = test_perimeter.get_actions(client) logger.info("actions {}".format(actions)) for key in actions[1]["actions"]: @@ -62,7 +61,6 @@ def clean_actions(client): logger.info("action policy_keys {}".format(policy_keys)) for policy_key in policy_keys: client.delete("/policies/{}/actions/{}".format(policy_key, key)) - client.delete("/actions/{}".format(key)) def clean_subject_categories(client): @@ -92,25 +90,33 @@ def clean_subject_data(client): for policy_key in policies["policies"]: req, data = test_data.get_subject_data(client, policy_id=policy_key) logger.info("============= data {}".format(data)) - for key in data["subject_data"]: - logger.info("============= Deleting {}/{}".format(policy_key, key)) - client.delete("/policies/{}/subject_data/{}".format(policy_key, key)) + for data_item in data["subject_data"]: + if data_item["data"]: + for data_id in data_item["data"]: + logger.info("============= Deleting {}/{}".format(policy_key, data_id)) + client.delete("/policies/{}/subject_data/{}/{}".format(policy_key, data_item['category_id'], data_id)) def clean_object_data(client): req, policies = test_policies.get_policies(client) for policy_key in policies["policies"]: req, data = test_data.get_object_data(client, policy_id=policy_key) - for key in data["object_data"]: - client.delete("/policies/{}/object_data/{}".format(policy_key, key)) + for data_item in data["object_data"]: + if data_item["data"]: + for data_id in data_item["data"]: + logger.info("============= object_data {}/{}".format(policy_key, data_id)) + client.delete("/policies/{}/object_data/{}/{}".format(policy_key, data_item['category_id'], data_id)) 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)) + for data_item in data["action_data"]: + if data_item["data"]: + for data_id in data_item["data"]: + logger.info("============= action_data {}/{}".format(policy_key, data_id)) + client.delete("/policies/{}/action_data/{}/{}".format(policy_key, data_item['category_id'], data_id)) def clean_meta_rule(client): @@ -165,10 +171,9 @@ def clean_rules(client): req, policies = test_policies.get_policies(client) for policy_key in policies["policies"]: req, rules = test_rules.get_rules(client, policy_key) - rules = rules["rules"] - rules = rules["rules"] + rules = rules["rules"]["rules"] for rule_key in rules: - client.delete("/policies/{}/rules/{}".format(policy_key, rule_key)) + req = client.delete("/policies/{}/rules/{}".format(policy_key, rule_key["id"])) def clean_all(client): @@ -178,7 +183,6 @@ def clean_all(client): clean_object_assignments(client) clean_action_assignments(client) - clean_meta_rule(client) clean_subject_data(client) clean_object_data(client) @@ -192,5 +196,7 @@ def clean_all(client): clean_object_categories(client) clean_action_categories(client) + clean_policies(client) clean_models(client) + clean_meta_rule(client) \ No newline at end of file diff --git a/moon_manager/tests/unit_python/api/test_assignement.py b/moon_manager/tests/unit_python/api/test_assignement.py new file mode 100644 index 00000000..b56fb420 --- /dev/null +++ b/moon_manager/tests/unit_python/api/test_assignement.py @@ -0,0 +1,280 @@ +import api.utilities as utilities +import json +from helpers import data_builder as builder +from uuid import uuid4 + + +# subject_categories_test + + +def get_subject_assignment(client, policy_id): + req = client.get("/policies/{}/subject_assignments".format(policy_id)) + subject_assignment = utilities.get_json(req.data) + return req, subject_assignment + + +def add_subject_assignment(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + subject_id = builder.create_subject(policy_id) + data_id = builder.create_subject_data(policy_id=policy_id, category_id=subject_category_id) + + data = { + "id": subject_id, + "category_id": subject_category_id, + "data_id": data_id + } + req = client.post("/policies/{}/subject_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subject_assignment = utilities.get_json(req.data) + return req, subject_assignment + + +def add_subject_assignment_without_cat_id(client): + + data = { + "id": "subject_id", + "category_id": "", + "data_id": "data_id" + } + req = client.post("/policies/{}/subject_assignments".format("1111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subject_assignment = utilities.get_json(req.data) + return req, subject_assignment + + +def delete_subject_assignment(client, policy_id, sub_id, cat_id,data_id): + req = client.delete("/policies/{}/subject_assignments/{}/{}/{}".format(policy_id, sub_id, cat_id,data_id)) + return req + + +def test_add_subject_assignment(): + client = utilities.register_client() + req, subject_assignment = add_subject_assignment(client) + assert req.status_code == 200 + assert isinstance(subject_assignment, dict) + assert "subject_assignments" in subject_assignment + + +# def test_add_subject_assignment_without_cat_id(): +# client = utilities.register_client() +# req, subject_assignment = add_subject_assignment_without_cat_id(client) +# assert req.status_code == 400 +# assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]" + + +def test_get_subject_assignment(): + client = utilities.register_client() + policy_id = builder.get_policy_id_with_subject_assignment() + req, subject_assignment = get_subject_assignment(client, policy_id) + assert req.status_code == 200 + assert isinstance(subject_assignment, dict) + assert "subject_assignments" in subject_assignment + + +def test_delete_subject_assignment(): + client = utilities.register_client() + policy_id = builder.get_policy_id_with_subject_assignment() + req, subject_assignment = get_subject_assignment(client, policy_id) + value = subject_assignment["subject_assignments"] + _id = list(value.keys())[0] + success_req = delete_subject_assignment(client, + policy_id, + value[_id]['subject_id'], + value[_id]['category_id'], + value[_id]['assignments'][0]) + assert success_req.status_code == 200 + + +def test_delete_subject_assignment_without_policy_id(): + client = utilities.register_client() + success_req = delete_subject_assignment(client, "", "id1", "111", "data_id1") + assert success_req.status_code == 404 + + +# --------------------------------------------------------------------------- +# object_categories_test + + +def get_object_assignment(client, policy_id): + req = client.get("/policies/{}/object_assignments".format(policy_id)) + object_assignment = utilities.get_json(req.data) + return req, object_assignment + + +def add_object_assignment(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + object_id = builder.create_object(policy_id) + data_id = builder.create_object_data(policy_id=policy_id, category_id=object_category_id) + + data = { + "id": object_id, + "category_id": object_category_id, + "data_id": data_id + } + + req = client.post("/policies/{}/object_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + object_assignment = utilities.get_json(req.data) + return req, object_assignment + + +def add_object_assignment_without_cat_id(client): + + data = { + "id": "object_id", + "category_id": "", + "data_id": "data_id" + } + req = client.post("/policies/{}/object_assignments".format("1111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + object_assignment = utilities.get_json(req.data) + return req, object_assignment + + +def delete_object_assignment(client, policy_id, obj_id, cat_id, data_id): + req = client.delete("/policies/{}/object_assignments/{}/{}/{}".format(policy_id, obj_id, cat_id, data_id)) + return req + + +def test_get_object_assignment(): + policy_id = builder.get_policy_id_with_object_assignment() + client = utilities.register_client() + req, object_assignment = get_object_assignment(client, policy_id) + assert req.status_code == 200 + assert isinstance(object_assignment, dict) + assert "object_assignments" in object_assignment + + +def test_add_object_assignment(): + client = utilities.register_client() + req, object_assignment = add_object_assignment(client) + assert req.status_code == 200 + assert "object_assignments" in object_assignment + + +# def test_add_object_assignment_without_cat_id(): +# client = utilities.register_client() +# req, object_assignment = add_object_assignment_without_cat_id(client) +# assert req.status_code == 400 +# assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]" + + +def test_delete_object_assignment(): + client = utilities.register_client() + policy_id = builder.get_policy_id_with_object_assignment() + req, object_assignment = get_object_assignment(client, policy_id) + value = object_assignment["object_assignments"] + _id = list(value.keys())[0] + success_req = delete_object_assignment(client, + policy_id, + value[_id]['object_id'], + value[_id]['category_id'], + value[_id]['assignments'][0]) + assert success_req.status_code == 200 + + +def test_delete_object_assignment_without_policy_id(): + client = utilities.register_client() + success_req = delete_object_assignment(client, "", "id1", "111", "data_id1") + assert success_req.status_code == 404 + + +# --------------------------------------------------------------------------- +# action_categories_test + + +def get_action_assignment(client, policy_id): + req = client.get("/policies/{}/action_assignments".format(policy_id)) + action_assignment = utilities.get_json(req.data) + return req, action_assignment + + +def add_action_assignment(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex) + action_id = builder.create_action(policy_id) + data_id = builder.create_action_data(policy_id=policy_id, category_id=action_category_id) + + data = { + "id": action_id, + "category_id": action_category_id, + "data_id": data_id + } + req = client.post("/policies/{}/action_assignments".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + action_assignment = utilities.get_json(req.data) + return req, action_assignment + + +def add_action_assignment_without_cat_id(client): + + data = { + "id": "action_id", + "category_id": "", + "data_id": "data_id" + } + req = client.post("/policies/{}/action_assignments".format("1111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + action_assignment = utilities.get_json(req.data) + return req, action_assignment + + +def delete_action_assignment(client, policy_id, action_id, cat_id, data_id): + req = client.delete("/policies/{}/action_assignments/{}/{}/{}".format(policy_id, action_id, cat_id, data_id)) + return req + + +def test_get_action_assignment(): + policy_id = builder.get_policy_id_with_action_assignment() + client = utilities.register_client() + req, action_assignment = get_action_assignment(client, policy_id) + assert req.status_code == 200 + assert isinstance(action_assignment, dict) + assert "action_assignments" in action_assignment + + +def test_add_action_assignment(): + client = utilities.register_client() + req, action_assignment = add_action_assignment(client) + assert req.status_code == 200 + assert "action_assignments" in action_assignment + + +# def test_add_action_assignment_without_cat_id(): +# client = utilities.register_client() +# req, action_assignment = add_action_assignment_without_cat_id(client) +# assert req.status_code == 400 +# assert json.loads(req.data)["message"] == "Key: 'category_id', [Empty String]" + + +def test_delete_action_assignment(): + client = utilities.register_client() + policy_id = builder.get_policy_id_with_action_assignment() + req, action_assignment = get_action_assignment(client, policy_id) + value = action_assignment["action_assignments"] + id = list(value.keys())[0] + success_req = delete_action_assignment(client, + policy_id, + value[id]['action_id'], + value[id]['category_id'], + value[id]['assignments'][0]) + assert success_req.status_code == 200 + + +def test_delete_action_assignment_without_policy_id(): + client = utilities.register_client() + success_req = delete_action_assignment(client, "", "id1", "111", "data_id1") + assert success_req.status_code == 404 + +# --------------------------------------------------------------------------- diff --git a/moon_manager/tests/unit_python/api/test_data.py b/moon_manager/tests/unit_python/api/test_data.py index ff0856af..433f69e6 100644 --- a/moon_manager/tests/unit_python/api/test_data.py +++ b/moon_manager/tests/unit_python/api/test_data.py @@ -36,8 +36,8 @@ def add_subject_data(client, name): return req, subject_data -def delete_subject_data(client, policy_id): - req = client.delete("/policies/{}/subject_data".format(policy_id)) +def delete_subject_data(client, policy_id, category_id, data_id): + req = client.delete("/policies/{}/subject_data/{}/{}".format(policy_id,category_id,data_id)) return req @@ -65,31 +65,24 @@ def test_add_subject_data(): def test_delete_subject_data(): client = utilities.register_client() subject_category_id, object_category_id, action_category_id, meta_rule_id,policy_id = builder.create_new_policy() - success_req = delete_subject_data(client, policy_id) + data_id = builder.create_subject_data(policy_id,subject_category_id) + success_req = delete_subject_data(client, policy_id, subject_category_id, data_id ) assert success_req.status_code == 200 -def test_add_subject_data_with_empty_user(): +def test_add_subject_data_with_forbidden_char_in_user(): client = utilities.register_client() - req, subject_data = add_subject_data(client, "") + req, subject_data = add_subject_data(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" - - -def test_add_subject_data_with_user_contain_space(): - client = utilities.register_client() - req, subject_data = add_subject_data(client, "test user") - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_delete_subject_data_without_policy_id(): client = utilities.register_client() - success_req = delete_subject_data(client, "") + success_req = delete_subject_data(client, "", "", "") assert success_req.status_code == 404 # --------------------------------------------------------------------------- - # object_categories_test @@ -118,8 +111,8 @@ def add_object_data(client, name): return req, object_data -def delete_object_data(client, policy_id): - req = client.delete("/policies/{}/object_data".format(policy_id)) +def delete_object_data(client, policy_id, category_id, data_id): + req = client.delete("/policies/{}/object_data/{}/{}".format(policy_id, category_id, data_id)) return req @@ -139,42 +132,34 @@ def test_add_object_data(): assert isinstance(object_data, dict) value = object_data["object_data"]['data'] assert "object_data" in object_data - id = list(value.keys())[0] - print("-----------------------") - print(id) - print(value[id]) - print("-----------------------") - assert value[id]['name'] == "testuser" - assert value[id]['description'] == "description of {}".format("testuser") + _id = list(value.keys())[0] + assert value[_id]['name'] == "testuser" + assert value[_id]['description'] == "description of {}".format("testuser") def test_delete_object_data(): client = utilities.register_client() - policy_id = utilities.get_policy_id() - success_req = delete_object_data(client, policy_id) - assert success_req.status_code == 200 + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy() + data_id = builder.create_object_data(policy_id, object_category_id) -def test_add_object_data_with_empty_user(): - client = utilities.register_client() - req, subject_data = add_object_data(client, "") - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + success_req = delete_object_data(client, policy_id, data_id, object_category_id) + assert success_req.status_code == 200 -def test_add_object_data_with_user_contain_space(): +def test_add_object_data_with_forbidden_char_in_user(): client = utilities.register_client() - req, object_data = add_object_data(client, "test user") + req, subject_data = add_object_data(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_delete_object_data_without_policy_id(): client = utilities.register_client() - success_req = delete_object_data(client, "") + success_req = delete_object_data(client, "", "", "") assert success_req.status_code == 404 -# --------------------------------------------------------------------------- +# --------------------------------------------------------------------------- # action_categories_test @@ -203,8 +188,8 @@ def add_action_data(client, name): return req, action_data -def delete_action_data(client, policy_id): - req = client.delete("/policies/{}/action_data".format(policy_id)) +def delete_action_data(client, policy_id, categorgy_id, data_id): + req = client.delete("/policies/{}/action_data/{}/{}".format(policy_id, categorgy_id, data_id)) return req @@ -231,27 +216,24 @@ def test_add_action_data(): def test_delete_action_data(): client = utilities.register_client() - policy_id = utilities.get_policy_id() - success_req = delete_action_data(client, policy_id) - assert success_req.status_code == 200 + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy() + data_id = builder.create_action_data(policy_id, action_category_id) -def test_add_action_data_with_empty_user(): - client = utilities.register_client() - req, action_data = add_action_data(client, "") - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + success_req = delete_action_data(client, policy_id, data_id, action_category_id) + + assert success_req.status_code == 200 -def test_add_action_data_with_user_contain_space(): +def test_add_action_data_with_forbidden_char_in_user(): client = utilities.register_client() - req, action_data = add_action_data(client, "test user") + req, action_data = add_action_data(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_delete_action_data_without_policy_id(): client = utilities.register_client() - success_req = delete_action_data(client, "") + success_req = delete_action_data(client, "", "", "") assert success_req.status_code == 404 # --------------------------------------------------------------------------- diff --git a/moon_manager/tests/unit_python/api/test_import.py b/moon_manager/tests/unit_python/api/test_import.py index f1ab8251..af5f753a 100644 --- a/moon_manager/tests/unit_python/api/test_import.py +++ b/moon_manager/tests/unit_python/api/test_import.py @@ -9,7 +9,7 @@ import api.test_policies as test_policies import api.test_meta_data as test_categories import api.test_data as test_data import api.test_meta_rules as test_meta_rules -import api.test_assignemnt as test_assignments +import api.test_assignement as test_assignments import api.test_rules as test_rules import api.import_export_utilities as import_export_utilities @@ -42,7 +42,8 @@ OBJECTS = [ "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"}, + {"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"}]}]}, @@ -225,7 +226,14 @@ def test_import_subject_object_action(): if counter == 2 or counter == 4: clean_method(client) - req = client.post("/import", content_type='application/json', data=json.dumps(element)) + + if counter == 3: + req = client.patch("/{}s/{}".format(type_element,perimeter_id), content_type='application/json', + data=json.dumps( + element["{}s".format(type_element)][0])) + else : + req = client.post("/import", content_type='application/json', + data=json.dumps(element)) if counter < 2: assert req.status_code == 500 continue @@ -237,10 +245,13 @@ def test_import_subject_object_action(): #assert counter < 2 #  this is an expected failure #continue - assert data == "Import ok !" + if counter != 3: + assert data == "Import ok !" get_elements = utilities.get_json(client.get("/"+type_element + "s").data) get_elements = get_elements[type_element + "s"] + perimeter_id = list(get_elements.keys())[0] + assert len(list(get_elements.keys())) == 1 values = list(get_elements.values()) assert values[0]["name"] == name @@ -338,6 +349,7 @@ def test_import_meta_rules(): 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 !" diff --git a/moon_manager/tests/unit_python/api/test_meta_data.py b/moon_manager/tests/unit_python/api/test_meta_data.py index 4cb86913..e6cb0833 100644 --- a/moon_manager/tests/unit_python/api/test_meta_data.py +++ b/moon_manager/tests/unit_python/api/test_meta_data.py @@ -1,7 +1,10 @@ import json import api.utilities as utilities +from helpers import data_builder +from uuid import uuid4 -#subject_categories_test + +# subject_categories_test def get_subject_categories(client): @@ -52,18 +55,35 @@ def test_add_subject_categories(): assert value['description'] == "description of {}".format("testuser") -def test_add_subject_categories_with_empty_user(): +def test_add_subject_categories_with_existed_name(): + client = utilities.register_client() + name = uuid4().hex + req, subject_categories = add_subject_categories(client, name) + assert req.status_code == 200 + req, subject_categories = add_subject_categories(client, name) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Subject Category Existing' + + +def test_add_subject_categories_name_contain_space(): + client = utilities.register_client() + req, subject_categories = add_subject_categories(client, " ") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Category Name Invalid' + + +def test_add_subject_categories_with_empty_name(): client = utilities.register_client() - req, subject_categories = add_subject_categories(client, "") + req, subject_categories = add_subject_categories(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" -def test_add_subject_categories_with_user_contain_space(): +def test_add_subject_categories_with_name_contain_space(): client = utilities.register_client() - req, subject_categories = add_subject_categories(client, "test user") + req, subject_categories = add_subject_categories(client, "testuser") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_delete_subject_categories(): @@ -79,8 +99,8 @@ def test_delete_subject_categories_without_id(): assert json.loads(req.data)["message"] == "400: Subject Category Unknown" -#--------------------------------------------------------------------------- -#object_categories_test +# --------------------------------------------------------------------------- +# object_categories_test def get_object_categories(client): req = client.get("/object_categories") @@ -130,18 +150,35 @@ def test_add_object_categories(): assert value['description'] == "description of {}".format("testuser") -def test_add_object_categories_with_empty_user(): +def test_add_object_categories_with_existed_name(): + client = utilities.register_client() + name = uuid4().hex + req, object_categories = add_object_categories(client, name) + assert req.status_code == 200 + req, object_categories = add_object_categories(client, name) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Object Category Existing' + + +def test_add_object_categories_name_contain_space(): + client = utilities.register_client() + req, subject_categories = add_object_categories(client, " ") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Category Name Invalid' + + +def test_add_object_categories_with_empty_name(): client = utilities.register_client() - req, object_categories = add_object_categories(client, "") + req, object_categories = add_object_categories(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" -def test_add_object_categories_with_user_contain_space(): +def test_add_object_categories_with_name_contain_space(): client = utilities.register_client() - req, object_categories = add_object_categories(client, "test user") + req, object_categories = add_object_categories(client, "testuser") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_delete_object_categories(): @@ -157,8 +194,8 @@ def test_delete_object_categories_without_id(): assert json.loads(req.data)["message"] == "400: Object Category Unknown" -#--------------------------------------------------------------------------- -#action_categories_test +# --------------------------------------------------------------------------- +# action_categories_test def get_action_categories(client): req = client.get("/action_categories") @@ -208,18 +245,35 @@ def test_add_action_categories(): assert value['description'] == "description of {}".format("testuser") -def test_add_action_categories_with_empty_user(): +def test_add_action_categories_with_existed_name(): client = utilities.register_client() - req, action_categories = add_action_categories(client, "") + name = uuid4().hex + req, action_categories = add_action_categories(client, name) + assert req.status_code == 200 + req, action_categories = add_action_categories(client, name) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Action Category Existing' + + +def test_add_action_categories_name_contain_space(): + client = utilities.register_client() + req, subject_categories = add_action_categories(client, " ") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Category Name Invalid' + + +def test_add_action_categories_with_empty_name(): + client = utilities.register_client() + req, action_categories = add_action_categories(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" -def test_add_action_categories_with_user_contain_space(): +def test_add_action_categories_with_name_contain_space(): client = utilities.register_client() - req, action_categories = add_action_categories(client, "test user") + req, action_categories = add_action_categories(client, "testuser") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_delete_action_categories(): @@ -233,3 +287,19 @@ def test_delete_action_categories_without_id(): req = delete_action_categories_without_id(client) assert req.status_code == 400 assert json.loads(req.data)["message"] == "400: Action Category Unknown" + + +def test_delete_data_categories_connected_to_meta_rule(): + subject_category_id, object_category_id, action_category_id, meta_rule_id = data_builder.create_new_meta_rule() + client = utilities.register_client() + req = client.delete("/subject_categories/{}".format(subject_category_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Subject Category With Meta Rule Error' + + req = client.delete("/object_categories/{}".format(object_category_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Object Category With Meta Rule Error' + + req = client.delete("/action_categories/{}".format(action_category_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Action Category With Meta Rule Error' diff --git a/moon_manager/tests/unit_python/api/test_meta_rules.py b/moon_manager/tests/unit_python/api/test_meta_rules.py index 80d648b4..634f19da 100644 --- a/moon_manager/tests/unit_python/api/test_meta_rules.py +++ b/moon_manager/tests/unit_python/api/test_meta_rules.py @@ -1,6 +1,7 @@ import json import api.utilities as utilities from helpers import category_helper +from helpers import data_builder from uuid import uuid4 @@ -10,32 +11,36 @@ def get_meta_rules(client): return req, meta_rules -def add_meta_rules(client, name): - subject_category = category_helper.add_subject_category(value={"name": "subject category name"+uuid4().hex, "description": "description 1"}) - subject_category_id = list(subject_category.keys())[0] - object_category = category_helper.add_object_category(value={"name": "object category name"+ uuid4().hex, "description": "description 1"}) - object_category_id = list(object_category.keys())[0] - action_category = category_helper.add_action_category(value={"name": "action category name"+uuid4().hex, "description": "description 1"}) - action_category_id = list(action_category.keys())[0] - - data = { - "name": name, - "subject_categories": [subject_category_id], - "object_categories": [object_category_id], - "action_categories": [action_category_id] - } +def add_meta_rules(client, name, data=None): + if not data: + subject_category = category_helper.add_subject_category( + value={"name": "subject category name" + uuid4().hex, "description": "description 1"}) + subject_category_id = list(subject_category.keys())[0] + object_category = category_helper.add_object_category( + value={"name": "object category name" + uuid4().hex, "description": "description 1"}) + object_category_id = list(object_category.keys())[0] + action_category = category_helper.add_action_category( + value={"name": "action category name" + uuid4().hex, "description": "description 1"}) + action_category_id = list(action_category.keys())[0] + + data = { + "name": name, + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } req = client.post("/meta_rules", data=json.dumps(data), headers={'Content-Type': 'application/json'}) meta_rules = utilities.get_json(req.data) return req, meta_rules -def add_meta_rules_without_subject_category_ids(client, name): +def add_meta_rules_without_category_ids(client, name): data = { - "name": name, + "name": name + uuid4().hex, "subject_categories": [], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] + "object_categories": [], + "action_categories": [] } req = client.post("/meta_rules", data=json.dumps(data), headers={'Content-Type': 'application/json'}) @@ -43,37 +48,45 @@ def add_meta_rules_without_subject_category_ids(client, name): return req, meta_rules -def update_meta_rules(client, name, metaRuleId): - subject_category = category_helper.add_subject_category( - value={"name": "subject category name update" + uuid4().hex, "description": "description 1"}) - subject_category_id = list(subject_category.keys())[0] - object_category = category_helper.add_object_category( - value={"name": "object category name update" + uuid4().hex, "description": "description 1"}) - object_category_id = list(object_category.keys())[0] - action_category = category_helper.add_action_category( - value={"name": "action category name update" + uuid4().hex, "description": "description 1"}) - action_category_id = list(action_category.keys())[0] - data = { - "name": name, - "subject_categories": [subject_category_id], - "object_categories": [object_category_id], - "action_categories": [action_category_id] - } +def update_meta_rules(client, name, metaRuleId, data=None): + if not data: + subject_category = category_helper.add_subject_category( + value={"name": "subject category name update" + uuid4().hex, + "description": "description 1"}) + subject_category_id = list(subject_category.keys())[0] + object_category = category_helper.add_object_category( + value={"name": "object category name update" + uuid4().hex, + "description": "description 1"}) + object_category_id = list(object_category.keys())[0] + action_category = category_helper.add_action_category( + value={"name": "action category name update" + uuid4().hex, + "description": "description 1"}) + action_category_id = list(action_category.keys())[0] + data = { + "name": name, + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + req = client.patch("/meta_rules/{}".format(metaRuleId), data=json.dumps(data), - headers={'Content-Type': 'application/json'}) + headers={'Content-Type': 'application/json'}) meta_rules = utilities.get_json(req.data) return req, meta_rules -def update_meta_rules_without_subject_category_ids(client, name): - data = { - "name": name, - "subject_categories": [], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - } - req = client.post("/meta_rules", data=json.dumps(data), - headers={'Content-Type': 'application/json'}) +def update_meta_rules_with_categories(client, name, data=None, meta_rule_id=None): + if not meta_rule_id: + subject_category_id, object_category_id, action_category_id, meta_rule_id = data_builder.create_new_meta_rule() + data = { + "name": name, + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + + req = client.patch("/meta_rules/{}".format(meta_rule_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) meta_rules = utilities.get_json(req.data) return req, meta_rules @@ -82,9 +95,7 @@ def delete_meta_rules(client, name): request, meta_rules = get_meta_rules(client) for key, value in meta_rules['meta_rules'].items(): if value['name'] == name: - req = client.delete("/meta_rules/{}".format(key)) - break - return req + return client.delete("/meta_rules/{}".format(key)) def delete_meta_rules_without_id(client): @@ -102,38 +113,143 @@ def test_get_meta_rules(): def test_add_meta_rules(): client = utilities.register_client() - req, meta_rules = add_meta_rules(client, "testuser") + meta_rule_name = uuid4().hex + req, meta_rules = add_meta_rules(client, meta_rule_name) assert req.status_code == 200 assert isinstance(meta_rules, dict) value = list(meta_rules["meta_rules"].values())[0] assert "meta_rules" in meta_rules - assert value['name'] == "testuser" + assert value['name'] == meta_rule_name -def test_add_meta_rules_with_empty_user(): +def test_add_two_meta_rules_with_same_categories_combination(): client = utilities.register_client() - req, meta_rules = add_meta_rules(client, "") + meta_rule_name = uuid4().hex + req, meta_rules = add_meta_rules(client, meta_rule_name) + assert req.status_code == 200 + for meta_rule_id in meta_rules['meta_rules']: + if meta_rules['meta_rules'][meta_rule_id]['name'] == meta_rule_name: + data = meta_rules['meta_rules'][meta_rule_id] + + data['name'] = uuid4().hex + req, meta_rules = add_meta_rules(client, name=data['name'], data=data) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Meta Rule Existing' + + +def test_add_three_meta_rules_with_different_combination_but_similar_items(): + client = utilities.register_client() + meta_rule_name1 = uuid4().hex + req, meta_rules = add_meta_rules(client, meta_rule_name1) + assert req.status_code == 200 + for meta_rule_id in meta_rules['meta_rules']: + if meta_rules['meta_rules'][meta_rule_id]['name'] == meta_rule_name1: + data = meta_rules['meta_rules'][meta_rule_id] + break + + meta_rule_name2 = uuid4().hex + + req, meta_rules = add_meta_rules(client, meta_rule_name2) + + for meta_rule_id in meta_rules['meta_rules']: + if meta_rules['meta_rules'][meta_rule_id]['name'] == meta_rule_name2: + data['subject_categories'] += meta_rules['meta_rules'][meta_rule_id][ + 'subject_categories'] + data['object_categories'] += meta_rules['meta_rules'][meta_rule_id]['object_categories'] + data['action_categories'] += meta_rules['meta_rules'][meta_rule_id]['action_categories'] + break + + data['name'] = uuid4().hex + + req, meta_rules = add_meta_rules(client, name=data['name'], data=data) + assert req.status_code == 200 + + +def test_add_two_meta_rules_with_different_combination_but_similar_items(): + client = utilities.register_client() + meta_rule_name1 = uuid4().hex + meta_rule_name2 = uuid4().hex + + subject_category = category_helper.add_subject_category( + value={"name": "subject category name" + uuid4().hex, "description": "description 1"}) + subject_category_id1 = list(subject_category.keys())[0] + + object_category = category_helper.add_object_category( + value={"name": "object category name" + uuid4().hex, "description": "description 1"}) + object_category_id1 = list(object_category.keys())[0] + + action_category = category_helper.add_action_category( + value={"name": "action category name" + uuid4().hex, "description": "description 1"}) + action_category_id1 = list(action_category.keys())[0] + + subject_category = category_helper.add_subject_category( + value={"name": "subject category name" + uuid4().hex, "description": "description 1"}) + subject_category_id2 = list(subject_category.keys())[0] + + object_category = category_helper.add_object_category( + value={"name": "object category name" + uuid4().hex, "description": "description 1"}) + object_category_id2 = list(object_category.keys())[0] + + action_category = category_helper.add_action_category( + value={"name": "action category name" + uuid4().hex, "description": "description 1"}) + action_category_id2 = list(action_category.keys())[0] + + data = { + "name": meta_rule_name1, + "subject_categories": [subject_category_id1, subject_category_id2], + "object_categories": [object_category_id1, object_category_id2], + "action_categories": [action_category_id1, action_category_id2] + } + req, meta_rules = add_meta_rules(client, meta_rule_name1, data=data) + assert req.status_code == 200 + data = { + "name": meta_rule_name2, + "subject_categories": [subject_category_id2], + "object_categories": [object_category_id1], + "action_categories": [action_category_id2] + } + + req, meta_rules = add_meta_rules(client, meta_rule_name1, data=data) + assert req.status_code == 200 + + +def test_add_meta_rule_with_existing_name_error(): + client = utilities.register_client() + name = uuid4().hex + req, meta_rules = add_meta_rules(client, name) + assert req.status_code == 200 + req, meta_rules = add_meta_rules(client, name) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Meta Rule Existing' + + +def test_add_meta_rules_with_forbidden_char_in_name(): + client = utilities.register_client() + req, meta_rules = add_meta_rules(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" -def test_add_meta_rules_with_user_contain_space(): +def test_add_meta_rules_with_blank_name(): client = utilities.register_client() - req, meta_rules = add_meta_rules(client, "test user") + req, meta_rules = add_meta_rules(client, "") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == '400: Meta Rule Error' def test_add_meta_rules_without_subject_categories(): client = utilities.register_client() - req, meta_rules = add_meta_rules_without_subject_category_ids(client, "testuser") - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'subject_categories', [Empty Container]" + name_meta_rule = uuid4().hex + req, meta_rules = add_meta_rules_without_category_ids(client, name_meta_rule) + assert req.status_code == 200 def test_delete_meta_rules(): client = utilities.register_client() - req = delete_meta_rules(client, "testuser") + name_meta_rule = uuid4().hex + req, meta_rules = add_meta_rules_without_category_ids(client, name_meta_rule) + meta_rule_id = next(iter(meta_rules['meta_rules'])) + req = delete_meta_rules(client, meta_rules['meta_rules'][meta_rule_id]['name']) assert req.status_code == 200 @@ -154,6 +270,70 @@ def test_update_meta_rules(): get_meta_rules(client) +def test_update_meta_rule_with_combination_existed(): + client = utilities.register_client() + meta_rule_name1 = uuid4().hex + req, meta_rules = add_meta_rules(client, meta_rule_name1) + meta_rule_id1 = next(iter(meta_rules['meta_rules'])) + data1 = meta_rules['meta_rules'][meta_rule_id1] + + meta_rule_name2 = uuid4().hex + req, meta_rules = add_meta_rules(client, meta_rule_name2) + meta_rule_id2 = next(iter(meta_rules['meta_rules'])) + data2 = meta_rules['meta_rules'][meta_rule_id2] + data1['name'] = data2['name'] + req_update = update_meta_rules(client, name=meta_rule_name2, metaRuleId=meta_rule_id2, + data=data1) + assert req_update[0].status_code == 409 + assert req_update[1]['message']== '409: Meta Rule Existing' + + +def test_update_meta_rule_with_different_combination_but_same_data(): + client = utilities.register_client() + meta_rule_name1 = uuid4().hex + subject_category = category_helper.add_subject_category( + value={"name": "subject category name" + uuid4().hex, "description": "description 1"}) + subject_category_id1 = list(subject_category.keys())[0] + object_category = category_helper.add_object_category( + value={"name": "object category name" + uuid4().hex, "description": "description 1"}) + object_category_id1 = list(object_category.keys())[0] + action_category = category_helper.add_action_category( + value={"name": "action category name" + uuid4().hex, "description": "description 1"}) + action_category_id1 = list(action_category.keys())[0] + subject_category = category_helper.add_subject_category( + value={"name": "subject category name" + uuid4().hex, "description": "description 1"}) + subject_category_id2 = list(subject_category.keys())[0] + object_category = category_helper.add_object_category( + value={"name": "object category name" + uuid4().hex, "description": "description 1"}) + object_category_id2 = list(object_category.keys())[0] + action_category = category_helper.add_action_category( + value={"name": "action category name" + uuid4().hex, "description": "description 1"}) + action_category_id2 = list(action_category.keys())[0] + + data = { + "name": meta_rule_name1, + "subject_categories": [subject_category_id1, subject_category_id2], + "object_categories": [object_category_id1, object_category_id2], + "action_categories": [action_category_id1, action_category_id2] + } + req, meta_rules = add_meta_rules(client, meta_rule_name1, data=data) + assert req.status_code == 200 + + meta_rule_name2 = uuid4().hex + req, meta_rules = add_meta_rules(client, meta_rule_name2) + meta_rule_id2 = next(iter(meta_rules['meta_rules'])) + data2 = { + "name": meta_rule_name2, + "subject_categories": [subject_category_id1, subject_category_id2], + "object_categories": [object_category_id1], + "action_categories": [action_category_id1,action_category_id2] + } + + req_update = update_meta_rules(client, name=meta_rule_name2, metaRuleId=meta_rule_id2, + data=data2) + assert req_update[0].status_code == 200 + + def test_update_meta_rules_without_id(): client = utilities.register_client() req_update = update_meta_rules(client, "testuser", "") @@ -161,15 +341,75 @@ def test_update_meta_rules_without_id(): assert json.loads(req_update[0].data)["message"] == "400: Meta Rule Unknown" -def test_update_meta_rules_without_user(): +def test_update_meta_rules_without_name(): client = utilities.register_client() - req_update = update_meta_rules(client, "", "") + req_update = update_meta_rules(client, "
", "1234567") assert req_update[0].status_code == 400 - assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req_update[0].data)[ + "message"] == "Key: 'name', [Forbidden characters in string]" + + +def test_update_meta_rules_without_categories(): + client = utilities.register_client() + req_update = update_meta_rules_with_categories(client, "testuser") + assert req_update[0].status_code == 200 -def test_update_meta_rules_without_subject_categories(): +def test_update_meta_rules_with_empty_categories(): client = utilities.register_client() - req_update = update_meta_rules_without_subject_category_ids(client, "testuser") + subject_category_id, object_category_id, action_category_id, meta_rule_id = data_builder.create_new_meta_rule() + data = { + "name": "testuser", + "subject_categories": [""], + "object_categories": [""], + "action_categories": [""] + } + req_update = update_meta_rules_with_categories(client, "testuser", data=data, + meta_rule_id=meta_rule_id) + assert req_update[0].status_code == 400 + assert req_update[1]['message'] == '400: Subject Category Unknown' + + +def test_update_meta_rules_with_empty_action_category(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id = data_builder.create_new_meta_rule() + data = { + "name": "testuser", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [""] + } + req_update = update_meta_rules_with_categories(client, "testuser", data=data, + meta_rule_id=meta_rule_id) + assert req_update[0].status_code == 400 + assert req_update[1]['message'] == '400: Action Category Unknown' + + +def test_update_meta_rules_with_empty_object_category(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id = data_builder.create_new_meta_rule() + data = { + "name": "testuser", + "subject_categories": [subject_category_id], + "object_categories": [""], + "action_categories": [action_category_id] + } + req_update = update_meta_rules_with_categories(client, "testuser", data=data, + meta_rule_id=meta_rule_id) + assert req_update[0].status_code == 400 + assert req_update[1]['message'] == '400: Object Category Unknown' + + +def test_update_meta_rules_with_categories_and_one_empty(): + client = utilities.register_client() + subject_category_id, object_category_id, action_category_id, meta_rule_id = data_builder.create_new_meta_rule() + data = { + "name": "testuser", + "subject_categories": [subject_category_id, ""], + "object_categories": [object_category_id, ""], + "action_categories": [action_category_id, ""] + } + req_update = update_meta_rules_with_categories(client, "testuser", data=data, + meta_rule_id=meta_rule_id) assert req_update[0].status_code == 400 - assert json.loads(req_update[0].data)["message"] == "Key: 'subject_categories', [Empty Container]" + assert req_update[1]['message'] == '400: Subject Category Unknown' diff --git a/moon_manager/tests/unit_python/api/test_pdp.py b/moon_manager/tests/unit_python/api/test_pdp.py index 1ac9b84f..53a87b21 100644 --- a/moon_manager/tests/unit_python/api/test_pdp.py +++ b/moon_manager/tests/unit_python/api/test_pdp.py @@ -69,16 +69,18 @@ def test_add_pdp(): def test_delete_pdp(): client = utilities.register_client() request, pdp = get_pdp(client) + success_req = None for key, value in pdp['pdps'].items(): if value['name'] == "testuser": success_req = delete_pdp(client, key) break + assert success_req assert success_req.status_code == 200 -def test_add_pdp_with_empty_user(): +def test_add_pdp_with_forbidden_char_in_user(): data = { - "name": "", + "name": "
", "security_pipeline": ["policy_id_1", "policy_id_2"], "keystone_project_id": "keystone_project_id", "description": "description of testuser" @@ -86,46 +88,20 @@ def test_add_pdp_with_empty_user(): client = utilities.register_client() req, models = add_pdp(client, data) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" - - -def test_add_pdp_with_user_contain_space(): - data = { - "name": "test user", - "security_pipeline": ["policy_id_1", "policy_id_2"], - "keystone_project_id": "keystone_project_id", - "description": "description of testuser" - } - client = utilities.register_client() - req, models = add_pdp(client, data) - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" - - -def test_add_pdp_without_security_pipeline(): - data = { - "name": "testuser", - "security_pipeline": [], - "keystone_project_id": "keystone_project_id", - "description": "description of testuser" - } - client = utilities.register_client() - req, meta_rules = add_pdp(client, data) - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'security_pipeline', [Empty Container]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" -def test_add_pdp_without_keystone(): +def test_add_pdp_with_forbidden_char_in_keystone(): data = { "name": "testuser", "security_pipeline": ["policy_id_1", "policy_id_2"], - "keystone_project_id": "", + "keystone_project_id": "", "description": "description of testuser" } client = utilities.register_client() req, meta_rules = add_pdp(client, data) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'keystone_project_id', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'keystone_project_id', [Forbidden characters in string]" def test_update_pdp(): @@ -183,19 +159,6 @@ def test_update_pdp_without_user(): "description": "description of testuser" } client = utilities.register_client() - req_update = update_pdp(client, data, "") - assert req_update[0].status_code == 400 - assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]" - - -def test_update_pdp_without_security_pipeline(): - data = { - "name": "testuser", - "security_pipeline": [], - "keystone_project_id": "keystone_project_id", - "description": "description of testuser" - } - client = utilities.register_client() - req_update = update_pdp(client, data, "") + req_update = update_pdp(client, data, "") assert req_update[0].status_code == 400 - assert json.loads(req_update[0].data)["message"] == "Key: 'security_pipeline', [Empty Container]" \ No newline at end of file + assert json.loads(req_update[0].data)["message"] == "Forbidden characters in string" diff --git a/moon_manager/tests/unit_python/api/test_perimeter.py b/moon_manager/tests/unit_python/api/test_perimeter.py index 322d90c6..ff7b09d7 100644 --- a/moon_manager/tests/unit_python/api/test_perimeter.py +++ b/moon_manager/tests/unit_python/api/test_perimeter.py @@ -3,6 +3,7 @@ import json import api.utilities as utilities from helpers import data_builder as builder +import helpers.policy_helper as policy_helper from uuid import uuid4 @@ -12,33 +13,27 @@ def get_subjects(client): return req, subjects -def add_subjects(client, name): - subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( - subject_category_name="subject_category1" + uuid4().hex, - object_category_name="object_category1" + uuid4().hex, - action_category_name="action_category1" + uuid4().hex, - meta_rule_name="meta_rule_1" + uuid4().hex, - model_name="model1" + uuid4().hex) - data = { - "name": name + uuid4().hex, - "description": "description of {}".format(name), - "password": "password for {}".format(name), - "email": "{}@moon".format(name) - } - req = client.post("/policies/{}/subjects".format(policy_id), data=json.dumps(data), - headers={'Content-Type': 'application/json'}) +def add_subjects(client, policy_id, name, perimeter_id=None, data=None): + if not data: + name = name + uuid4().hex + data = { + "name": name, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + if not perimeter_id: + req = client.post("/policies/{}/subjects".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + else: + req = client.post("/policies/{}/subjects/{}".format(policy_id, perimeter_id), + data=json.dumps( + data), + headers={'Content-Type': 'application/json'}) subjects = utilities.get_json(req.data) return req, subjects -def delete_subject(client): - subjects = get_subjects(client) - value = subjects[1]['subjects'] - id = list(value.keys())[0] - policy_id = builder.get_policy_id_with_subject_assignment() - return client.delete("/policies/{}/subjects/{}".format(policy_id, id)) - - def delete_subjects_without_perimeter_id(client): req = client.delete("/subjects/{}".format("")) return req @@ -54,18 +49,166 @@ def test_perimeter_get_subject(): def test_perimeter_add_subject(): client = utilities.register_client() - req, subjects = add_subjects(client, "testuser") + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + + req, subjects = add_subjects(client, policy_id, "testuser") value = list(subjects["subjects"].values())[0] assert req.status_code == 200 - assert "subjects" in subjects - assert value["name"] is not None - assert value["email"] is not None + assert value["name"] + assert value["email"] + + +def test_perimeter_add_same_subject_perimeter_id_with_new_policy_id(): + client = utilities.register_client() + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + name = "testuser" + perimeter_id = uuid4().hex + data = { + "name": name + uuid4().hex, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + add_subjects(client, policy_id1, data['name'], perimeter_id=perimeter_id, data=data) + policies2 = policy_helper.add_policies() + policy_id2 = list(policies2.keys())[0] + req, subjects = add_subjects(client, policy_id2, data['name'], + perimeter_id=perimeter_id, data=data) + value = list(subjects["subjects"].values())[0] + assert req.status_code == 200 + assert value["name"] + assert value["email"] + assert len(value['policy_list']) == 2 + assert policy_id1 in value['policy_list'] + assert policy_id2 in value['policy_list'] + + +def test_perimeter_add_same_subject_perimeter_id_with_different_name(): + client = utilities.register_client() + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + perimeter_id = uuid4().hex + add_subjects(client, policy_id1, "testuser", perimeter_id=perimeter_id) + policies2 = policy_helper.add_policies() + policy_id2 = list(policies2.keys())[0] + req, subjects = add_subjects(client, policy_id2, "testuser", perimeter_id=perimeter_id) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Perimeter content is invalid.' + + +def test_perimeter_add_same_subject_name_with_new_policy_id(): + client = utilities.register_client() + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + perimeter_id = uuid4().hex + name = "testuser" + uuid4().hex + data = { + "name": name, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + req, subjects = add_subjects(client, policy_id1, None, perimeter_id=perimeter_id, + data=data) + policies2 = policy_helper.add_policies() + policy_id2 = list(policies2.keys())[0] + value = list(subjects["subjects"].values())[0] + data = { + "name": value['name'], + "description": "description of {}".format(value['name']), + "password": "password for {}".format(value['name']), + "email": "{}@moon".format(value['name']) + } + req, subjects = add_subjects(client, policy_id2, None, data=data) + value = list(subjects["subjects"].values())[0] + assert req.status_code == 200 + assert value["name"] + assert value["email"] + assert len(value['policy_list']) == 2 + assert policy_id1 in value['policy_list'] + assert policy_id2 in value['policy_list'] + + +def test_perimeter_add_same_subject_name_with_same_policy_id(): + client = utilities.register_client() + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + perimeter_id = uuid4().hex + name = "testuser" + uuid4().hex + data = { + "name": name, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + req, subjects = add_subjects(client, policy_id1, None, perimeter_id=perimeter_id, + data=data) + value = list(subjects["subjects"].values())[0] + data = { + "name": value['name'], + "description": "description of {}".format(value['name']), + "password": "password for {}".format(value['name']), + "email": "{}@moon".format(value['name']) + } + req, subjects = add_subjects(client, policy_id1, None, data=data) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_perimeter_add_same_subject_perimeter_id_with_existed_policy_id_in_list(): + client = utilities.register_client() + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + name = "testuser" + uuid4().hex + data = { + "name": name, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + req, subjects = add_subjects(client, policy_id, name, data=data) + perimeter_id = list(subjects["subjects"].values())[0]['id'] + req, subjects = add_subjects(client, policy_id, name, perimeter_id=perimeter_id, data=data) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_perimeter_add_subject_invalid_policy_id(): + client = utilities.register_client() + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + name = "testuser" + data = { + "name": name + uuid4().hex, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + req, subjects = add_subjects(client, policy_id + "0", "testuser", data) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' + + +def test_perimeter_add_subject_policy_id_none(): + client = utilities.register_client() + name = "testuser" + data = { + "name": name + uuid4().hex, + "description": "description of {}".format(name), + "password": "password for {}".format(name), + "email": "{}@moon".format(name) + } + req, subjects = add_subjects(client, None, "testuser", data) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' -def test_perimeter_add_subject_without_name(): +def test_perimeter_add_subject_with_forbidden_char_in_name(): client = utilities.register_client() data = { - "name": "", + "name": "", "description": "description of {}".format(""), "password": "password for {}".format(""), "email": "{}@moon".format("") @@ -73,26 +216,121 @@ def test_perimeter_add_subject_without_name(): req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" -def test_perimeter_add_subject_with_name_contain_spaces(): +def test_perimeter_update_subject_name(): client = utilities.register_client() + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + req, subjects = add_subjects(client, policy_id, "testuser") + value1 = list(subjects["subjects"].values())[0] + perimeter_id = value1['id'] data = { - "name": "test user", - "description": "description of {}".format("test user"), - "password": "password for {}".format("test user"), - "email": "{}@moon".format("test user") + 'name': value1['name'] + "update" } - req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data), - headers={'Content-Type': 'application/json'}) + req = client.patch("/subjects/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subjects = utilities.get_json(req.data) + value2 = list(subjects["subjects"].values())[0] + assert req.status_code == 200 + assert value1['name'] + 'update' == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] == value2['description'] + + +def test_perimeter_update_subject_description(): + client = utilities.register_client() + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + req, subjects = add_subjects(client, policy_id, "testuser") + value1 = list(subjects["subjects"].values())[0] + perimeter_id = value1['id'] + data = { + 'description': value1['description'] + "update", + } + req = client.patch("/subjects/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subjects = utilities.get_json(req.data) + value2 = list(subjects["subjects"].values())[0] + assert req.status_code == 200 + assert value1['name'] == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] + 'update' == value2['description'] + + +def test_perimeter_update_subject_description_and_name(): + client = utilities.register_client() + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + + req, subjects = add_subjects(client, policy_id, "testuser") + value1 = list(subjects["subjects"].values())[0] + perimeter_id = value1['id'] + data = { + 'description': value1['description'] + "update", + 'name': value1['name'] + "update" + } + req = client.patch("/subjects/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subjects = utilities.get_json(req.data) + value2 = list(subjects["subjects"].values())[0] + assert req.status_code == 200 + assert value1['name'] + 'update' == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] + 'update' == value2['description'] + + +def test_perimeter_update_subject_wrong_id(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, subjects = add_subjects(client, policy_id=policy_id1, name='testuser', data=data) + value1 = list(subjects["subjects"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update", + 'description': value1['description'] + "update" + } + req = client.patch("/subjects/{}".format(perimeter_id + "wrong"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == '400: Perimeter content is invalid.' + + +def test_perimeter_update_subject_name_with_existed_one(): + client = utilities.register_client() + name1 = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + perimeter_id1 = uuid4().hex + req, subjects = add_subjects(client, policy_id=policy_id1, name=name1, + perimeter_id=perimeter_id1) + value1 = list(subjects["subjects"].values())[0] + perimeter_id2 = uuid4().hex + name2 = 'testuser' + uuid4().hex + req, subjects = add_subjects(client, policy_id=policy_id1, name=name2, + perimeter_id=perimeter_id2) + data = { + 'name': value1['name'], + } + req = client.patch("/subjects/{}".format(perimeter_id2), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 409 def test_perimeter_delete_subject(): client = utilities.register_client() - req = delete_subject(client) + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + req, subjects = add_subjects(client, policy_id, "testuser") + subject_id = list(subjects["subjects"].values())[0]["id"] + req = client.delete("/policies/{}/subjects/{}".format(policy_id, subject_id)) assert req.status_code == 200 @@ -109,31 +347,30 @@ def get_objects(client): return req, objects -def add_objects(client, name): - subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy( - subject_category_name="subject_category1" + uuid4().hex, - object_category_name="object_category1" + uuid4().hex, - action_category_name="action_category1" + uuid4().hex, - meta_rule_name="meta_rule_1" + uuid4().hex, - model_name="model1" + uuid4().hex) - data = { - "name": name + uuid4().hex, - "description": "description of {}".format(name), - } - req = client.post("/policies/{}/objects/".format(policyId), data=json.dumps(data), - headers={'Content-Type': 'application/json'}) +def add_objects(client, name, policyId=None, data=None, perimeter_id=None): + if not policyId: + subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) + if not data: + data = { + "name": name + uuid4().hex, + "description": "description of {}".format(name), + } + if not perimeter_id: + req = client.post("/policies/{}/objects/".format(policyId), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + else: + req = client.post("/policies/{}/objects/{}".format(policyId, perimeter_id), + data=json.dumps(data), + headers={'Content-Type': 'application/json'}) objects = utilities.get_json(req.data) return req, objects -def delete_object(client): - objects = get_objects(client) - value = objects[1]['objects'] - id = list(value.keys())[0] - policy_id = builder.get_policy_id_with_object_assignment() - return client.delete("/policies/{}/objects/{}".format(policy_id, id)) - - def delete_objects_without_perimeter_id(client): req = client.delete("/objects/{}".format("")) return req @@ -152,37 +389,279 @@ def test_perimeter_add_object(): req, objects = add_objects(client, "testuser") value = list(objects["objects"].values())[0] assert req.status_code == 200 - assert "objects" in objects - assert value['name'] is not None + assert value['name'] + + +def test_perimeter_add_object_with_wrong_policy_id(): + client = utilities.register_client() + req, objects = add_objects(client, "testuser", policyId='wrong') + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' + + +def test_perimeter_add_object_with_policy_id_none(): + client = utilities.register_client() + data = { + "name": "testuser" + uuid4().hex, + "description": "description of {}".format("testuser"), + } + req = client.post("/policies/{}/objects/".format(None), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' + + +def test_perimeter_add_same_object_name_with_new_policy_id(): + client = utilities.register_client() + req, objects = add_objects(client, "testuser") + value1 = list(objects["objects"].values())[0] + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": value1['name'], + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + value2 = list(objects["objects"].values())[0] + assert req.status_code == 200 + assert value1['id'] == value2['id'] + assert value1['name'] == value2['name'] + + +def test_perimeter_add_same_object_perimeter_id_with_new_policy_id(): + client = utilities.register_client() + req, objects = add_objects(client, "testuser") + value1 = list(objects["objects"].values())[0] + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": value1['name'], + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data, + perimeter_id=value1['id']) + value2 = list(objects["objects"].values())[0] + assert req.status_code == 200 + assert value1['id'] == value2['id'] + assert value1['name'] == value2['name'] + + +def test_perimeter_add_same_object_perimeter_id_with_different_name(): + client = utilities.register_client() + req, objects = add_objects(client, "testuser") + value1 = list(objects["objects"].values())[0] + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": value1['name'] + 'different', + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data, + perimeter_id=value1['id']) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Perimeter content is invalid.' + + +def test_perimeter_add_same_object_name_with_same_policy_id(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + value = list(objects["objects"].values())[0] + assert req.status_code == 200 + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_perimeter_add_same_object_perimeter_id_with_existed_policy_id_in_list(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + value = list(objects["objects"].values())[0] + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data, + perimeter_id=value['id']) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_perimeter_update_object_name(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + + value1 = list(objects["objects"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update" + } + req = client.patch("/objects/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + objects = utilities.get_json(req.data) + value2 = list(objects["objects"].values())[0] + assert req.status_code == 200 + assert value1['name'] + 'update' == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] == value2['description'] + + +def test_perimeter_update_object_description(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + + value1 = list(objects["objects"].values())[0] + perimeter_id = value1['id'] + data = { + 'description': value1['description'] + "update" + } + req = client.patch("/objects/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + objects = utilities.get_json(req.data) + value2 = list(objects["objects"].values())[0] + assert req.status_code == 200 + assert value1['name'] == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] + 'update' == value2['description'] + + +def test_perimeter_update_object_description_and_name(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + + value1 = list(objects["objects"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update", + 'description': value1['description'] + "update" + } + req = client.patch("/objects/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + objects = utilities.get_json(req.data) + value2 = list(objects["objects"].values())[0] + assert req.status_code == 200 + assert value1['name'] + 'update' == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] + 'update' == value2['description'] + + +def test_perimeter_update_object_wrong_id(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data) + + value1 = list(objects["objects"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update", + 'description': value1['description'] + "update" + } + req = client.patch("/objects/{}".format(perimeter_id + "wrong"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + + +def test_perimeter_update_object_name_with_existed_one(): + client = utilities.register_client() + name = 'testuser' + uuid4().hex + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data1 = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data1) + value1 = list(objects["objects"].values())[0] + + name = 'testuser' + uuid4().hex + + data2 = { + "name": name, + "description": "description of {}".format('testuser'), + } + req, objects = add_objects(client, 'testuser', policyId=policy_id1, data=data2) + + value2 = list(objects["objects"].values())[0] + perimeter_id2 = value2['id'] + + data3 = { + 'name': value1['name'] + } + req = client.patch("/objects/{}".format(perimeter_id2), data=json.dumps(data3), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Object Existing' def test_perimeter_add_object_without_name(): client = utilities.register_client() data = { - "name": "", + "name": "
", "description": "description of {}".format(""), } req = client.post("/policies/{}/objects/".format("111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_perimeter_add_object_with_name_contain_spaces(): client = utilities.register_client() data = { - "name": "test user", + "name": "test
user", "description": "description of {}".format("test user"), } req = client.post("/policies/{}/objects/".format("111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_perimeter_delete_object(): client = utilities.register_client() - req = delete_object(client) + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + object_id = builder.create_object(policy_id) + req = client.delete("/policies/{}/objects/{}".format(policy_id, object_id)) assert req.status_code == 200 @@ -199,29 +678,30 @@ def get_actions(client): return req, actions -def add_actions(client, name): - subject_category_id, object_category_id, action_category_id, meta_rule_id, policyId = builder.create_new_policy( - subject_category_name="subject_category1" + uuid4().hex, - object_category_name="object_category1" + uuid4().hex, - action_category_name="action_category1" + uuid4().hex, - meta_rule_name="meta_rule_1" + uuid4().hex, - model_name="model1" + uuid4().hex) - data = { - "name": name + uuid4().hex, - "description": "description of {}".format(name), - } - req = client.post("/policies/{}/actions".format(policyId), data=json.dumps(data), - headers={'Content-Type': 'application/json'}) - actions = utilities.get_json(req.data) - return req, actions +def add_actions(client, name, policy_id=None, data=None, perimeter_id=None): + if not policy_id: + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = builder.create_new_policy( + subject_category_name="subject_category1" + uuid4().hex, + object_category_name="object_category1" + uuid4().hex, + action_category_name="action_category1" + uuid4().hex, + meta_rule_name="meta_rule_1" + uuid4().hex, + model_name="model1" + uuid4().hex) + if not data: + data = { + "name": name + uuid4().hex, + "description": "description of {}".format(name), + } + if not perimeter_id: + req = client.post("/policies/{}/actions/".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + else: + req = client.post("/policies/{}/actions/{}".format(policy_id, perimeter_id), + data=json.dumps(data), + headers={'Content-Type': 'application/json'}) -def delete_actions(client): - actions = get_actions(client) - value = actions[1]['actions'] - id = list(value.keys())[0] - policy_id = builder.get_policy_id_with_action_assignment() - return client.delete("/policies/{}/actions/{}".format(policy_id, id)) + actions = utilities.get_json(req.data) + return req, actions def delete_actions_without_perimeter_id(client): @@ -242,40 +722,305 @@ def test_perimeter_add_actions(): req, actions = add_actions(client, "testuser") value = list(actions["actions"].values())[0] assert req.status_code == 200 - assert "actions" in actions - assert value['name'] is not None + assert value['name'] + + +def test_perimeter_add_action_with_wrong_policy_id(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser", policy_id="wrong") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' + + +def test_perimeter_add_action_with_policy_id_none(): + client = utilities.register_client() + data = { + "name": "testuser" + uuid4().hex, + "description": "description of {}".format("testuser"), + } + req = client.post("/policies/{}/actions/".format(None), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Unknown' + + +def test_perimeter_add_same_action_name_with_new_policy_id(): + client = utilities.register_client() + req, action = add_actions(client, "testuser") + value1 = list(action["actions"].values())[0] + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": value1['name'], + "description": "description of {}".format('testuser'), + } + req, action = add_actions(client, 'testuser', policy_id=policy_id1, data=data) + value2 = list(action["actions"].values())[0] + assert req.status_code == 200 + assert value1['id'] == value2['id'] + assert value1['name'] == value2['name'] + + +def test_perimeter_add_same_action_perimeter_id_with_new_policy_id(): + client = utilities.register_client() + req, action = add_actions(client, "testuser") + value1 = list(action["actions"].values())[0] + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": value1['name'], + "description": "description of {}".format('testuser'), + } + req, action = add_actions(client, 'testuser', policy_id=policy_id1, data=data, + perimeter_id=value1['id']) + value2 = list(action["actions"].values())[0] + assert req.status_code == 200 + assert value1['id'] == value2['id'] + assert value1['name'] == value2['name'] + + +def test_perimeter_add_same_action_perimeter_id_with_different_name(): + client = utilities.register_client() + req, action = add_actions(client, "testuser") + value1 = list(action["actions"].values())[0] + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + data = { + "name": value1['name'] + 'different', + "description": "description of {}".format('testuser'), + } + req, action = add_actions(client, 'testuser', policy_id=policy_id1, data=data, + perimeter_id=value1['id']) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Perimeter content is invalid.' + + +def test_perimeter_add_same_action_name_with_same_policy_id(): + client = utilities.register_client() + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + req, action = add_actions(client, "testuser", policy_id=policy_id1) + value1 = list(action["actions"].values())[0] + data = { + "name": value1['name'], + "description": "description of {}".format('testuser'), + } + req, action = add_actions(client, 'testuser', policy_id=policy_id1, data=data) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_perimeter_add_same_action_perimeter_id_with_existed_policy_id_in_list(): + client = utilities.register_client() + policies1 = policy_helper.add_policies() + policy_id1 = list(policies1.keys())[0] + req, action = add_actions(client, "testuser", policy_id=policy_id1) + value1 = list(action["actions"].values())[0] + data = { + "name": value1['name'], + "description": "description of {}".format('testuser'), + } + req, action = add_actions(client, 'testuser', policy_id=policy_id1, data=data, + perimeter_id=value1['id']) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' def test_perimeter_add_actions_without_name(): client = utilities.register_client() data = { - "name": "", + "name": "", "description": "description of {}".format(""), } req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" def test_perimeter_add_actions_with_name_contain_spaces(): client = utilities.register_client() data = { - "name": "test user", + "name": "testuser", + "description": "description of {}".format("test user"), + } + req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" + + +def test_add_subjects_without_policy_id(): + client = utilities.register_client() + data = { + "name": "testuser", + "description": "description of {}".format("test user"), + } + req = client.post("/policies/{}/subjects".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + +def test_add_objects_without_policy_id(): + client = utilities.register_client() + data = { + "name": "testuser", + "description": "description of {}".format("test user"), + } + req = client.post("/policies/{}/objects".format("111"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + +def test_add_action_without_policy_id(): + client = utilities.register_client() + data = { + "name": "testuser", "description": "description of {}".format("test user"), } req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data), headers={'Content-Type': 'application/json'}) assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + +def test_perimeter_update_action_name(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser") + value1 = list(actions["actions"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update" + } + req = client.patch("/actions/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subjects = utilities.get_json(req.data) + value2 = list(subjects["actions"].values())[0] + assert req.status_code == 200 + assert value1['name'] + 'update' == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] == value2['description'] + + +def test_perimeter_update_actions_description(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser") + value1 = list(actions["actions"].values())[0] + perimeter_id = value1['id'] + data = { + 'description': value1['description'] + "update" + } + req = client.patch("/actions/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subjects = utilities.get_json(req.data) + value2 = list(subjects["actions"].values())[0] + assert req.status_code == 200 + assert value1['name'] == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] + 'update' == value2['description'] + + +def test_perimeter_update_actions_description_and_name(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser") + value1 = list(actions["actions"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update", + 'description': value1['description'] + "update" + } + req = client.patch("/actions/{}".format(perimeter_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + subjects = utilities.get_json(req.data) + value2 = list(subjects["actions"].values())[0] + assert req.status_code == 200 + assert value1['name'] + 'update' == value2['name'] + assert value1['id'] == value2['id'] + assert value1['description'] + 'update' == value2['description'] + + +def test_perimeter_update_action_wrong_id(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser") + value1 = list(actions["actions"].values())[0] + perimeter_id = value1['id'] + data = { + 'name': value1['name'] + "update", + 'description': value1['description'] + "update" + } + req = client.patch("/actions/{}".format(perimeter_id + "wrong"), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Perimeter content is invalid.' + + +def test_perimeter_update_action_name_with_existed_one(): + client = utilities.register_client() + req, actions = add_actions(client, "testuser") + value1 = list(actions["actions"].values())[0] + req, actions = add_actions(client, "testuser") + value2 = list(actions["actions"].values())[0] + perimeter_id2 = value2['id'] + data = { + 'name': value1['name'], + } + req = client.patch("/actions/{}".format(perimeter_id2), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Action Existing' def test_perimeter_delete_actions(): client = utilities.register_client() - req = delete_actions(client) + + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + action_id = builder.create_action(policy_id) + req = client.delete("/policies/{}/actions/{}".format(policy_id, action_id)) assert req.status_code == 200 +def test_delete_subject_without_policy(): + client = utilities.register_client() + + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + + action_id = builder.create_action(policy_id) + + req = client.delete("/subjects/{}".format(action_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + +def test_delete_objects_without_policy(): + client = utilities.register_client() + + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + + action_id = builder.create_action(policy_id) + + req = client.delete("/objects/{}".format(action_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + +def test_delete_actions_without_policy(): + client = utilities.register_client() + + policies = policy_helper.add_policies() + policy_id = list(policies.keys())[0] + + action_id = builder.create_action(policy_id) + + req = client.delete("/actions/{}".format(action_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Policy Unknown" + + def test_perimeter_delete_actions_without_perimeter_id(): client = utilities.register_client() req = delete_actions_without_perimeter_id(client) diff --git a/moon_manager/tests/unit_python/api/test_policies.py b/moon_manager/tests/unit_python/api/test_policies.py index cd50f4c7..76161d53 100644 --- a/moon_manager/tests/unit_python/api/test_policies.py +++ b/moon_manager/tests/unit_python/api/test_policies.py @@ -7,6 +7,8 @@ import json from uuid import uuid4 import api.utilities as utilities from helpers import model_helper +from helpers import policy_helper +from helpers import data_builder def get_policies(client): @@ -16,7 +18,7 @@ def get_policies(client): def add_policies(client, name): - req = model_helper.add_model(model_id="mls_model_id"+uuid4().hex) + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) model_id = list(req.keys())[0] data = { "name": name, @@ -30,14 +32,6 @@ def add_policies(client, name): return req, policies -def delete_policies(client, name): - request, policies = get_policies(client) - for key, value in policies['policies'].items(): - req = client.delete("/policies/{}".format(key)) - break - return req - - def delete_policies_without_id(client): req = client.delete("/policies/{}".format("")) return req @@ -63,15 +57,286 @@ def test_add_policies(): assert value["description"] == "description of {}".format(policy_name) +def test_add_policies_without_model(): + policy_name = "testuser" + uuid4().hex + client = utilities.register_client() + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": "", + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + assert req.status_code == 200 + + +def test_add_policies_with_same_name(): + name = uuid4().hex + policy_name = name + client = utilities.register_client() + req, policies = add_policies(client, policy_name) + assert req.status_code == 200 + assert isinstance(policies, dict) + value = list(policies["policies"].values())[0] + assert "policies" in policies + assert value['name'] == policy_name + assert value["description"] == "description of {}".format(policy_name) + client = utilities.register_client() + req, policies = add_policies(client, policy_name) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_add_policy_with_empty_name(): + policy_name = "" + client = utilities.register_client() + req, policies = add_policies(client, policy_name) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Content Error' + + +def test_update_policies_with_model(): + policy_name = "testuser" + uuid4().hex + client = utilities.register_client() + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": "", + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id = next(iter(utilities.get_json(req.data)['policies'])) + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name + "-2", + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.patch("/policies/{}".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 200 + assert json.loads(req.data)['policies'][policy_id]['name'] == policy_name + '-2' + + +def test_update_policies_name_success(): + policy_name = "testuser" + uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id = next(iter(utilities.get_json(req.data)['policies'])) + + data = { + "name": policy_name + "-2", + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.patch("/policies/{}".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 200 + assert json.loads(req.data)['policies'][policy_id]['name'] == policy_name + '-2' + + +def test_update_policies_model_unused(): + policy_name = uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id = next(iter(utilities.get_json(req.data)['policies'])) + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.patch("/policies/{}".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 200 + + +def test_update_policy_name_with_existed_one(): + policy_name1 = "testuser" + uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name1, + "description": "description of {}".format(policy_name1), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id1 = next(iter(utilities.get_json(req.data)['policies'])) + + policy_name2 = "testuser" + uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name2, + "description": "description of {}".format(policy_name2), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id2 = next(iter(utilities.get_json(req.data)['policies'])) + + data = { + "name": policy_name1, + "description": "description of {}".format(policy_name1), + "model_id": model_id, + "genre": "genre" + } + req = client.patch("/policies/{}".format(policy_id2), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Policy Already Exists' + + +def test_update_policies_with_empty_name(): + policy_name = "testuser" + uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id = next(iter(utilities.get_json(req.data)['policies'])) + + data = { + "name": "", + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.patch("/policies/{}".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy Content Error' + + +def test_update_policies_with_blank_model(): + policy_name = "testuser" + uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies/", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + policy_id = next(iter(utilities.get_json(req.data)['policies'])) + + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": "", + "genre": "genre" + } + + req = client.patch("/policies/{}".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 200 + + +def test_update_policies_connected_to_rules_with_blank_model(): + client = utilities.register_client() + req, rules, policy_id = data_builder.add_rules(client) + req = client.get("/policies") + data = utilities.get_json(req.data) + for policy_obj_id in data['policies']: + if policy_obj_id == policy_id: + policy = data['policies'][policy_obj_id] + policy['model_id'] = '' + req = client.patch("/policies/{}".format(policy_id), data=json.dumps(policy), + headers={'Content-Type': 'application/json'}) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy update error' + + def test_delete_policies(): client = utilities.register_client() - req = delete_policies(client, "testuser") + + policy = policy_helper.add_policies() + policy_id = list(policy.keys())[0] + + req = client.delete("/policies/{}".format(policy_id)) assert req.status_code == 200 +def test_delete_policy_with_dependencies_rule(): + client = utilities.register_client() + req, rules, policy_id = data_builder.add_rules(client) + req = client.delete("/policies/{}".format(policy_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy With Rule Error' + + +def test_delete_policy_with_dependencies_subject_data(): + client = utilities.register_client() + req, rules, policy_id = data_builder.add_rules(client) + req = client.delete("/policies/{}/rules/{}".format(policy_id, next(iter(rules['rules'])))) + assert req.status_code == 200 + req = client.delete("/policies/{}".format(policy_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy With Data Error' + + +def test_delete_policy_with_dependencies_perimeter(): + client = utilities.register_client() + policy = policy_helper.add_policies() + policy_id = next(iter(policy)) + + data = { + "name": 'testuser'+uuid4().hex, + "description": "description of {}".format(uuid4().hex), + "password": "password for {}".format(uuid4().hex), + "email": "{}@moon".format(uuid4().hex) + } + req = client.post("/policies/{}/subjects".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + assert req.status_code == 200 + req = client.delete("/policies/{}".format(policy_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Policy With Perimeter Error' + + def test_delete_policies_without_id(): client = utilities.register_client() req = delete_policies_without_id(client) assert req.status_code == 400 assert json.loads(req.data)["message"] == '400: Policy Unknown' - diff --git a/moon_manager/tests/unit_python/api/test_rules.py b/moon_manager/tests/unit_python/api/test_rules.py index af1501e4..a3c21839 100644 --- a/moon_manager/tests/unit_python/api/test_rules.py +++ b/moon_manager/tests/unit_python/api/test_rules.py @@ -11,31 +11,11 @@ def get_rules(client, policy_id): return req, rules -def add_rules(client): - sub_id, obj_id, act_id, meta_rule_id, policy_id = builder.create_new_policy("sub_cat" + uuid4().hex, - "obj_cat" + uuid4().hex, - "act_cat" + uuid4().hex) - sub_data_id = builder.create_subject_data(policy_id, sub_id) - obj_data_id = builder.create_object_data(policy_id, obj_id) - act_data_id = builder.create_action_data(policy_id, act_id) - data = { - "meta_rule_id": meta_rule_id, - "rule": [sub_data_id, obj_data_id, act_data_id], - "instructions": ( - {"decision": "grant"}, - ), - "enabled": True - } - req = client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data), - headers={'Content-Type': 'application/json'}) - rules = utilities.get_json(req.data) - return req, rules - - def add_rules_without_policy_id(client): + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule() data = { - "meta_rule_id": "meta_rule_id", - "rule": ["sub_data_id", "obj_data_id", "act_data_id"], + "meta_rule_id": meta_rule_id, + "rule": [subject_category_id, object_category_id, action_category_id], "instructions": ( {"decision": "grant"}, ), @@ -93,7 +73,7 @@ def test_get_rules(): def test_add_rules(): client = utilities.register_client() - req, rules = add_rules(client, ) + req, rules, policy = builder.add_rules(client, ) assert req.status_code == 200 @@ -103,13 +83,13 @@ def test_add_rules_without_policy_id(): assert req.status_code == 400 assert json.loads(req.data)["message"] == "400: Policy Unknown" - -def test_add_rules_without_meta_rule_id(): - policy_id = utilities.get_policy_id() - client = utilities.register_client() - req, rules = add_rules_without_meta_rule_id(client, policy_id) - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'meta_rule_id', [Empty String]" +# +# def test_add_rules_without_meta_rule_id(): +# policy_id = utilities.get_policy_id() +# client = utilities.register_client() +# req, rules = add_rules_without_meta_rule_id(client, policy_id) +# assert req.status_code == 400 +# assert json.loads(req.data)["message"] == "Key: 'meta_rule_id', [Empty String]" def test_add_rules_without_rule(): @@ -122,8 +102,9 @@ def test_add_rules_without_rule(): def test_delete_rules_with_invalid_parameters(): client = utilities.register_client() - rules = delete_rules(client, "", "") - assert rules.status_code == 404 + req = delete_rules(client, "", "") + assert req.status_code == 404 + # assert json.loads(req.data)["message"] == 'Invalid Key :rule not found' def test_delete_rules_without_policy_id(): diff --git a/moon_manager/tests/unit_python/api/test_unit_models.py b/moon_manager/tests/unit_python/api/test_unit_models.py index d754b976..6e93ed28 100644 --- a/moon_manager/tests/unit_python/api/test_unit_models.py +++ b/moon_manager/tests/unit_python/api/test_unit_models.py @@ -6,6 +6,8 @@ import json import api.utilities as utilities from helpers import data_builder as builder +from helpers import policy_helper +from helpers import model_helper from uuid import uuid4 @@ -15,16 +17,15 @@ def get_models(client): return req, models -def add_models(client, name): - subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule( - subject_category_name="subject_category"+uuid4().hex, - object_category_name="object_category"+uuid4().hex, action_category_name="action_category"+uuid4().hex, - meta_rule_name="meta_rule" + uuid4().hex) - data = { - "name": name, - "description": "description of {}".format(name), - "meta_rules": [meta_rule_id] - } +def add_models(client, name, data=None): + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule() + + if not data: + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [meta_rule_id] + } req = client.post("/models", data=json.dumps(data), headers={'Content-Type': 'application/json'}) models = utilities.get_json(req.data) @@ -32,10 +33,7 @@ def add_models(client, name): def update_model(client, name, model_id): - subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule( - subject_category_name="subject_category" + uuid4().hex, - object_category_name="object_category" + uuid4().hex, action_category_name="action_category" + uuid4().hex, - meta_rule_name="meta_rule" + uuid4().hex) + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule() data = { "name": name, @@ -60,13 +58,26 @@ def add_model_without_meta_rules_ids(client, name): return req, models -def update_model_without_meta_rules_ids(client, name): +def add_model_with_empty_meta_rule_id(client, name): + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [""] + } + req = client.post("/models", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + models = utilities.get_json(req.data) + return req, models + + +def update_model_without_meta_rules_ids(client, model_id): + name = "model_id" + uuid4().hex data = { "name": name, "description": "description of {}".format(name), "meta_rules": [] } - req = client.patch("/models", data=json.dumps(data), + req = client.patch("/models/{}".format(model_id), data=json.dumps(data), headers={'Content-Type': 'application/json'}) models = utilities.get_json(req.data) return req, models @@ -86,6 +97,24 @@ def delete_models_without_id(client): return req +def test_delete_model_assigned_to_policy(): + policy_name = "testuser" + uuid4().hex + client = utilities.register_client() + req = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(req.keys())[0] + data = { + "name": policy_name, + "description": "description of {}".format(policy_name), + "model_id": model_id, + "genre": "genre" + } + req = client.post("/policies", data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + req = client.delete("/models/{}".format(model_id)) + assert req.status_code == 400 + assert json.loads(req.data)["message"] == '400: Model With Policy Error' + + def clean_models(): client = utilities.register_client() req, models = get_models(client) @@ -121,6 +150,64 @@ def test_delete_models(): assert req.status_code == 200 +def test_update_models_with_assigned_policy(): + client = utilities.register_client() + + model = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(model.keys())[0] + value = { + "name": "test_policy" + uuid4().hex, + "model_id": model_id, + "description": "test", + } + policy = policy_helper.add_policies(value=value) + data = { + "name": "model_" + uuid4().hex, + "description": "description of model_2", + "meta_rules": [] + } + req = client.patch("/models/{}".format(model_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "400: Model With Policy Error" + + +def test_update_models_with_no_assigned_policy(): + client = utilities.register_client() + + model = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(model.keys())[0] + + data = { + "name": "model_" + uuid4().hex, + "description": "description of model_2", + "meta_rules": [] + } + req = client.patch("/models/{}".format(model_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + assert req.status_code == 200 + + +def test_add_models_with_meta_rule_key(): + client = utilities.register_client() + + model = model_helper.add_model(model_id="mls_model_id" + uuid4().hex) + model_id = list(model.keys())[0] + + data = { + "name": "model_" + uuid4().hex, + "description": "description of model_2", + + } + req = client.patch("/models/{}".format(model_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Invalid Key :meta_rules not found" + + def test_delete_models_without_id(): client = utilities.register_client() req = delete_models_without_id(client) @@ -128,28 +215,80 @@ def test_delete_models_without_id(): assert json.loads(req.data)["message"] == "400: Model Unknown" -def test_add_model_with_empty_user(): +def test_add_model_with_empty_name(): + clean_models() + client = utilities.register_client() + req, models = add_models(client, "
") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" + + +def test_add_model_with_name_contain_space(): + clean_models() + client = utilities.register_client() + req, models = add_models(client, "test
user") + assert req.status_code == 400 + assert json.loads(req.data)["message"] == "Key: 'name', [Forbidden characters in string]" + + +def test_add_model_with_name_space(): clean_models() client = utilities.register_client() - req, models = add_models(client, "") + req, models = add_models(client, " ") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req.data)["message"] == '400: Model Unknown' -def test_add_model_with_user_contain_space(): +def test_add_model_with_empty_meta_rule_id(): clean_models() client = utilities.register_client() - req, models = add_models(client, "test user") + req, meta_rules = add_model_with_empty_meta_rule_id(client, "testuser") assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'name', [String contains space]" + assert json.loads(req.data)["message"] == '400: Meta Rule Unknown' + + +def test_add_model_with_existed_name(): + clean_models() + client = utilities.register_client() + name = uuid4().hex + req, models = add_models(client, name) + assert req.status_code == 200 + req, models = add_models(client, name) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Model Error' + + +def test_add_model_with_existed_meta_rules_list(): + clean_models() + client = utilities.register_client() + name = uuid4().hex + + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule() + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [meta_rule_id] + } + name = uuid4().hex + req, models = add_models(client=client, name=name, data=data) + assert req.status_code == 200 + + data = { + "name": name, + "description": "description of {}".format(name), + "meta_rules": [meta_rule_id] + } + req, models = add_models(client=client, name=name, data=data) + assert req.status_code == 409 + assert json.loads(req.data)["message"] == '409: Model Error' def test_add_model_without_meta_rules(): clean_models() client = utilities.register_client() req, meta_rules = add_model_without_meta_rules_ids(client, "testuser") - assert req.status_code == 400 - assert json.loads(req.data)["message"] == "Key: 'meta_rules', [Empty Container]" + assert req.status_code == 200 + # assert json.loads(req.data)["message"] == "Key: 'meta_rules', [Empty Container]" def test_update_model(): @@ -164,6 +303,26 @@ def test_update_model(): delete_models(client, "testuser") +def test_update_model_name_with_space(): + clean_models() + client = utilities.register_client() + req = add_models(client, "testuser") + model_id = list(req[1]['models'])[0] + req_update = update_model(client, " ", model_id) + assert req_update[0].status_code == 400 + assert req_update[1]["message"] == '400: Model Unknown' + + +def test_update_model_with_empty_name(): + clean_models() + client = utilities.register_client() + req = add_models(client, "testuser") + model_id = list(req[1]['models'])[0] + req_update = update_model(client, "", model_id) + assert req_update[0].status_code == 400 + assert req_update[1]['message'] == '400: Model Unknown' + + def test_update_meta_rules_without_id(): clean_models() client = utilities.register_client() @@ -172,15 +331,22 @@ def test_update_meta_rules_without_id(): assert json.loads(req_update[0].data)["message"] == "400: Model Unknown" -def test_update_meta_rules_without_user(): +def test_update_meta_rules_without_name(): client = utilities.register_client() - req_update = update_model(client, "", "") + req_update = update_model(client, "
", "1234567") assert req_update[0].status_code == 400 - assert json.loads(req_update[0].data)["message"] == "Key: 'name', [Empty String]" + assert json.loads(req_update[0].data)[ + "message"] == "Key: 'name', [Forbidden characters in string]" def test_update_meta_rules_without_meta_rules(): + value = { + "name": "mls_model_id" + uuid4().hex, + "description": "test", + "meta_rules": [] + } + model = model_helper.add_model(value=value) + model_id = list(model.keys())[0] client = utilities.register_client() - req_update = update_model_without_meta_rules_ids(client, "testuser") - assert req_update[0].status_code == 400 - assert json.loads(req_update[0].data)["message"] == "Key: 'meta_rules', [Empty Container]" + req_update = update_model_without_meta_rules_ids(client, model_id) + assert req_update[0].status_code == 200 diff --git a/moon_manager/tests/unit_python/conftest.py b/moon_manager/tests/unit_python/conftest.py index d9899231..90a27e54 100644 --- a/moon_manager/tests/unit_python/conftest.py +++ b/moon_manager/tests/unit_python/conftest.py @@ -153,6 +153,24 @@ PODS = { } } +SLAVES = { + "slaves": [ + { + "context": + { + "cluster": "kubernetes", + "user": "kubernetes-admin" + }, + "name": "kubernetes-admin@kubernetes", + "configured": True, + "wrapper_name": "mywrapper", + "ip": "NC", + "port": 31002, + "internal_port": 8080 + } + ] +} + def get_b64_conf(component=None): if component in CONF: @@ -210,6 +228,10 @@ def no_requests(monkeypatch): 'GET', 'http://orchestrator:8083/pods', json=PODS ) + m.register_uri( + 'GET', 'http://localhost/slaves', + json=SLAVES + ) m.register_uri( 'DELETE', 'http://orchestrator:8083/pods/{}'.format(list([PODS['pods'].keys()])[0]), headers={"content-type": "application/json"} diff --git a/moon_manager/tests/unit_python/helpers/data_builder.py b/moon_manager/tests/unit_python/helpers/data_builder.py index 2a7c5979..91808cbe 100644 --- a/moon_manager/tests/unit_python/helpers/data_builder.py +++ b/moon_manager/tests/unit_python/helpers/data_builder.py @@ -10,6 +10,7 @@ from helpers import model_helper from .meta_rule_helper import * import api.utilities as utilities import json +from uuid import uuid4 def create_subject_category(name): @@ -60,31 +61,57 @@ def create_pdp(policies_ids): return value -def create_new_policy(subject_category_name="subjectCategory", object_category_name="objectCategory", - action_category_name="actionCategory", - model_name="test_model" + uuid4().hex, policy_name="policy_1" + uuid4().hex, - meta_rule_name="meta_rule1" + uuid4().hex): +def create_new_policy(subject_category_name=None, object_category_name=None, + action_category_name=None, model_name=None, policy_name=None, + meta_rule_name=None): + if not subject_category_name: + subject_category_name = "subjectCategory_" + uuid4().hex + if not object_category_name: + object_category_name = "objectCategory_" + uuid4().hex + if not action_category_name: + action_category_name = "actionCategory_" + uuid4().hex + + if not meta_rule_name: + meta_rule_name = "meta_rule_" + uuid4().hex + + if not model_name: + model_name = "model_name_" + uuid4().hex + if not policy_name: + policy_name = "policy_name_" + uuid4().hex + subject_category_id, object_category_id, action_category_id, meta_rule_id = create_new_meta_rule( subject_category_name=subject_category_name + uuid4().hex, object_category_name=object_category_name + uuid4().hex, - action_category_name=action_category_name + uuid4().hex, meta_rule_name=meta_rule_name + uuid4().hex) - model = model_helper.add_model(value=create_model(meta_rule_id, model_name)) + action_category_name=action_category_name + uuid4().hex, + meta_rule_name=meta_rule_name + uuid4().hex + ) + + model = model_helper.add_model(value=create_model(meta_rule_id, model_name + uuid4().hex)) model_id = list(model.keys())[0] - value = create_policy(model_id, policy_name) + value = create_policy(model_id, policy_name + uuid4().hex) policy = add_policies(value=value) assert policy policy_id = list(policy.keys())[0] return subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id -def create_new_meta_rule(subject_category_name="subjectCategory", object_category_name="objectCategory", - action_category_name="actionCategory", - meta_rule_name="meta_rule1" + uuid4().hex): +def create_new_meta_rule(subject_category_name=None, object_category_name=None, + action_category_name=None, meta_rule_name=None): + if not subject_category_name: + subject_category_name = "subjectCategory_" + uuid4().hex + if not object_category_name: + object_category_name = "objectCategory_" + uuid4().hex + if not action_category_name: + action_category_name = "actionCategory_" + uuid4().hex + + if not meta_rule_name: + meta_rule_name = "meta_rule_" + uuid4().hex + subject_category_id = create_subject_category(subject_category_name) object_category_id = create_object_category(object_category_name) action_category_id = create_action_category(action_category_name) value = {"name": meta_rule_name, - "algorithm": "name of the meta rule algorithm", + "description": "name of the meta rule algorithm", "subject_categories": [subject_category_id], "object_categories": [object_category_id], "action_categories": [action_category_id] @@ -125,7 +152,8 @@ def create_subject_data(policy_id, category_id): "name": "subject-security-level", "description": {"low": "", "medium": "", "high": ""}, } - subject_data = add_subject_data(policy_id=policy_id, category_id=category_id, value=value).get('data') + subject_data = add_subject_data(policy_id=policy_id, category_id=category_id, value=value).get( + 'data') assert subject_data return list(subject_data.keys())[0] @@ -135,7 +163,8 @@ def create_object_data(policy_id, category_id): "name": "object-security-level", "description": {"low": "", "medium": "", "high": ""}, } - object_data = add_object_data(policy_id=policy_id, category_id=category_id, value=value).get('data') + object_data = add_object_data(policy_id=policy_id, category_id=category_id, value=value).get( + 'data') return list(object_data.keys())[0] @@ -144,7 +173,8 @@ def create_action_data(policy_id, category_id): "name": "action-type", "description": {"vm-action": "", "storage-action": "", }, } - action_data = add_action_data(policy_id=policy_id, category_id=category_id, value=value).get('data') + action_data = add_action_data(policy_id=policy_id, category_id=category_id, value=value).get( + 'data') return list(action_data.keys())[0] @@ -207,3 +237,24 @@ def get_policy_id_with_action_assignment(): client.post("/policies/{}/action_assignments".format(policy_id), data=json.dumps(data), headers={'Content-Type': 'application/json'}) return policy_id + + +def add_rules(client): + sub_id, obj_id, act_id, meta_rule_id, policy_id = create_new_policy("sub_cat" + uuid4().hex, + "obj_cat" + uuid4().hex, + "act_cat" + uuid4().hex) + sub_data_id = create_subject_data(policy_id, sub_id) + obj_data_id = create_object_data(policy_id, obj_id) + act_data_id = create_action_data(policy_id, act_id) + data = { + "meta_rule_id": meta_rule_id, + "rule": [sub_data_id, obj_data_id, act_data_id], + "instructions": ( + {"decision": "grant"}, + ), + "enabled": True + } + req = client.post("/policies/{}/rules".format(policy_id), data=json.dumps(data), + headers={'Content-Type': 'application/json'}) + rules = utilities.get_json(req.data) + return req, rules, policy_id diff --git a/moon_manager/tests/unit_python/helpers/data_helper.py b/moon_manager/tests/unit_python/helpers/data_helper.py index da6b9376..e1c05640 100644 --- a/moon_manager/tests/unit_python/helpers/data_helper.py +++ b/moon_manager/tests/unit_python/helpers/data_helper.py @@ -16,7 +16,7 @@ def add_action_data(policy_id, data_id=None, category_id=None, value=None): def delete_action_data(policy_id, data_id): from python_moondb.core import PolicyManager - PolicyManager.delete_action_data("", policy_id, data_id) + PolicyManager.delete_action_data("", policy_id=policy_id, data_id=data_id) def get_object_data(policy_id, data_id=None, category_id=None): @@ -31,7 +31,7 @@ def add_object_data(policy_id, data_id=None, category_id=None, value=None): def delete_object_data(policy_id, data_id): from python_moondb.core import PolicyManager - PolicyManager.delete_object_data("", policy_id, data_id) + PolicyManager.delete_object_data("", policy_id=policy_id, data_id=data_id) def get_subject_data(policy_id, data_id=None, category_id=None): @@ -46,7 +46,7 @@ def add_subject_data(policy_id, data_id=None, category_id=None, value=None): def delete_subject_data(policy_id, data_id): from python_moondb.core import PolicyManager - PolicyManager.delete_subject_data("", policy_id, data_id) + PolicyManager.delete_subject_data("", policy_id=policy_id, data_id=data_id) def get_actions(policy_id, perimeter_id=None): diff --git a/moon_manager/tests/unit_python/helpers/model_helper.py b/moon_manager/tests/unit_python/helpers/model_helper.py index d2ffb85b..73808e03 100644 --- a/moon_manager/tests/unit_python/helpers/model_helper.py +++ b/moon_manager/tests/unit_python/helpers/model_helper.py @@ -15,11 +15,8 @@ def get_models(model_id=None): def add_model(model_id=None, value=None): from python_moondb.core import ModelManager if not value: - subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule( - subject_category_name="subject_category1"+uuid4().hex, - object_category_name="object_category1"+uuid4().hex, - action_category_name="action_category1"+uuid4().hex) - name = "MLS" if model_id is None else "MLS " + model_id + subject_category_id, object_category_id, action_category_id, meta_rule_id = builder.create_new_meta_rule() + name = "MLS"+uuid4().hex if model_id is None else "MLS " + model_id value = { "name": name, "description": "test", diff --git a/moon_manager/tests/unit_python/helpers/policy_helper.py b/moon_manager/tests/unit_python/helpers/policy_helper.py index c932ee3a..eddd0b8d 100644 --- a/moon_manager/tests/unit_python/helpers/policy_helper.py +++ b/moon_manager/tests/unit_python/helpers/policy_helper.py @@ -3,6 +3,8 @@ # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. +from uuid import uuid4 + def get_policies(): from python_moondb.core import PolicyManager return PolicyManager.get_policies("admin") @@ -12,7 +14,7 @@ def add_policies(policy_id=None, value=None): from python_moondb.core import PolicyManager if not value: value = { - "name": "test_policy", + "name": "test_policy"+ uuid4().hex, "model_id": "", "genre": "authz", "description": "test", diff --git a/moon_manager/tests/unit_python/requirements.txt b/moon_manager/tests/unit_python/requirements.txt index 6c6e5bb8..d6f190e4 100644 --- a/moon_manager/tests/unit_python/requirements.txt +++ b/moon_manager/tests/unit_python/requirements.txt @@ -1,5 +1,5 @@ flask flask_cors flask_restful -python_moondb -python_moonutilities +python_moondb==1.2.20 +python_moonutilities==1.4.20 diff --git a/moon_orchestrator/Changelog b/moon_orchestrator/Changelog index 783c9130..c04af79c 100644 --- a/moon_orchestrator/Changelog +++ b/moon_orchestrator/Changelog @@ -27,3 +27,10 @@ CHANGES ----- - the processing of a request is now performed in a thread +4.4.2 +----- +- apply pylint rules + +4.4.3 +----- +- add "internal_port" key in slave API diff --git a/moon_orchestrator/Dockerfile b/moon_orchestrator/Dockerfile index 09d12fda..7c59efb5 100644 --- a/moon_orchestrator/Dockerfile +++ b/moon_orchestrator/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3 +FROM python:3.6 LABEL Name=Orchestrator LABEL Description="Orchestrator component for the Moon platform" diff --git a/moon_orchestrator/moon_orchestrator/__init__.py b/moon_orchestrator/moon_orchestrator/__init__.py index bc8f2781..31d40184 100644 --- a/moon_orchestrator/moon_orchestrator/__init__.py +++ b/moon_orchestrator/moon_orchestrator/__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.1" +__version__ = "4.4.3" diff --git a/moon_orchestrator/moon_orchestrator/api/generic.py b/moon_orchestrator/moon_orchestrator/api/generic.py index 37e30a22..9128140a 100644 --- a/moon_orchestrator/moon_orchestrator/api/generic.py +++ b/moon_orchestrator/moon_orchestrator/api/generic.py @@ -77,13 +77,16 @@ class API(Resource): if "__version__" in dir(group_api_obj): api_desc[api_name]["version"] = group_api_obj.__version__ object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj))) - for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list): + for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), + object_list): if "__urls__" in dir(obj): api_desc[api_name][obj.__name__] = dict() api_desc[api_name][obj.__name__]["urls"] = obj.__urls__ api_desc[api_name][obj.__name__]["methods"] = dict() for _method in filter(lambda x: x in __methods, dir(obj)): - docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method)) + docstring = eval( + "moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, + _method)) api_desc[api_name][obj.__name__]["methods"][_method] = docstring api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__) if group_id in api_desc: diff --git a/moon_orchestrator/moon_orchestrator/api/pods.py b/moon_orchestrator/moon_orchestrator/api/pods.py index 389fa5b0..8943e018 100644 --- a/moon_orchestrator/moon_orchestrator/api/pods.py +++ b/moon_orchestrator/moon_orchestrator/api/pods.py @@ -73,7 +73,7 @@ class Pods(Resource): def __get_slave_names(self): for slave in self.driver.get_slaves(): - if "name" in slave : + if "name" in slave: yield slave["name"] @check_auth @@ -146,7 +146,7 @@ class Pods(Resource): if "name" in slave and "wrapper_name" in slave: if uuid in (slave['name'], slave["wrapper_name"]): self.driver.delete_wrapper(name=slave["wrapper_name"]) - else : + else: raise exceptions.SlaveNameUnknown except Exception as e: return {"result": False, "message": str(e)}, 500 diff --git a/moon_orchestrator/moon_orchestrator/drivers.py b/moon_orchestrator/moon_orchestrator/drivers.py index 4519f3aa..233d389e 100644 --- a/moon_orchestrator/moon_orchestrator/drivers.py +++ b/moon_orchestrator/moon_orchestrator/drivers.py @@ -209,6 +209,7 @@ class K8S(Driver): data["wrapper_name"] = value[0]['name'] data["ip"] = value[0].get("ip", "NC") data["port"] = value[0].get("external_port", "NC") + data["internal_port"] = value[0].get("port", "NC") slaves.append(data) break return slaves @@ -223,6 +224,7 @@ class K8S(Driver): data["wrapper_name"] = value[0]['name'] data["ip"] = value[0].get("ip", "NC") data["port"] = value[0].get("external_port", "NC") + data["internal_port"] = value[0].get("port", "NC") data["configured"] = True break slaves.append(data) diff --git a/moon_orchestrator/moon_orchestrator/http_server.py b/moon_orchestrator/moon_orchestrator/http_server.py index 1cb12618..72e12358 100644 --- a/moon_orchestrator/moon_orchestrator/http_server.py +++ b/moon_orchestrator/moon_orchestrator/http_server.py @@ -19,7 +19,7 @@ logger = logging.getLogger("moon.orchestrator.http_server") __API__ = ( Status, - ) +) class Server: @@ -70,7 +70,7 @@ class Root(Resource): """ The root of the web service """ - __urls__ = ("/", ) + __urls__ = ("/",) __methods = ("get", "post", "put", "delete", "options") def get(self): @@ -136,10 +136,12 @@ class HTTPServer(Server): 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) @@ -163,4 +165,3 @@ class HTTPServer(Server): @staticmethod def __filter_str(data): return data.replace("@", "-") - diff --git a/moon_wrapper/Changelog b/moon_wrapper/Changelog index 071e4ef9..b2d62657 100644 --- a/moon_wrapper/Changelog +++ b/moon_wrapper/Changelog @@ -26,3 +26,22 @@ CHANGES 4.5.1 ----- - use the threading capability of Flask app + +4.5.2 +----- +- apply pylint rules + +4.5.3 +----- +- Fix bug when OpenStack requests Moon + - bug on Keystone project ID + - bug when filtering the pipeline container name + +4.5.4 +----- +- Fix a bug in retrieval of object from OpenStack +- Fix a bug in rule element + +4.6.0 +----- +- Add the Update API diff --git a/moon_wrapper/moon_wrapper/__init__.py b/moon_wrapper/moon_wrapper/__init__.py index 98a98146..f0887748 100644 --- a/moon_wrapper/moon_wrapper/__init__.py +++ b/moon_wrapper/moon_wrapper/__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.5.1" +__version__ = "4.6.0" diff --git a/moon_wrapper/moon_wrapper/__main__.py b/moon_wrapper/moon_wrapper/__main__.py index 46cafa76..3a403293 100644 --- a/moon_wrapper/moon_wrapper/__main__.py +++ b/moon_wrapper/moon_wrapper/__main__.py @@ -1,4 +1,4 @@ from moon_wrapper.server import main -server = main() -server.run() +SERVER = main() +SERVER.run() diff --git a/moon_wrapper/moon_wrapper/api/generic.py b/moon_wrapper/moon_wrapper/api/generic.py index 498513c7..e492b327 100644 --- a/moon_wrapper/moon_wrapper/api/generic.py +++ b/moon_wrapper/moon_wrapper/api/generic.py @@ -6,14 +6,14 @@ Those API are helping API used to manage the Moon platform. """ -from flask_restful import Resource, request import logging +from flask_restful import Resource, request import moon_wrapper.api from python_moonutilities.security_functions import check_auth __version__ = "0.1.0" -logger = logging.getLogger("moon.manager.api." + __name__) +LOGGER = logging.getLogger("moon.manager.api." + __name__) class Status(Resource): @@ -35,7 +35,7 @@ class Status(Resource): } } """ - raise NotImplemented + raise NotImplementedError class Logs(Resource): @@ -70,7 +70,7 @@ class Logs(Resource): args["to"] = to_str args["event_number"] = event_number - raise NotImplemented + raise NotImplementedError class API(Resource): @@ -112,20 +112,23 @@ class API(Resource): if "__version__" in dir(group_api_obj): api_desc[api_name]["version"] = group_api_obj.__version__ object_list = list(filter(lambda x: "__" not in x, dir(group_api_obj))) - for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), object_list): + for obj in map(lambda x: eval("moon_interface.api.{}.{}".format(api_name, x)), + object_list): if "__urls__" in dir(obj): api_desc[api_name][obj.__name__] = dict() api_desc[api_name][obj.__name__]["urls"] = obj.__urls__ api_desc[api_name][obj.__name__]["methods"] = dict() for _method in filter(lambda x: x in __methods, dir(obj)): - docstring = eval("moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, _method)) + docstring = eval( + "moon_interface.api.{}.{}.{}.__doc__".format(api_name, obj.__name__, + _method)) api_desc[api_name][obj.__name__]["methods"][_method] = docstring api_desc[api_name][obj.__name__]["description"] = str(obj.__doc__) if group_id in api_desc: if endpoint_id in api_desc[group_id]: return {group_id: {endpoint_id: api_desc[group_id][endpoint_id]}} elif len(endpoint_id) > 0: - logger.error("Unknown endpoint_id {}".format(endpoint_id)) + LOGGER.error("Unknown endpoint_id {}".format(endpoint_id)) return {"error": "Unknown endpoint_id {}".format(endpoint_id)} return {group_id: api_desc[group_id]} return api_desc diff --git a/moon_wrapper/moon_wrapper/api/oslowrapper.py b/moon_wrapper/moon_wrapper/api/oslowrapper.py index 905c32db..39128621 100644 --- a/moon_wrapper/moon_wrapper/api/oslowrapper.py +++ b/moon_wrapper/moon_wrapper/api/oslowrapper.py @@ -6,17 +6,17 @@ Authz is the endpoint to get authorization response """ +import logging +import json import flask from flask import request from flask_restful import Resource -import logging -import json import requests from python_moonutilities import exceptions __version__ = "0.1.0" -logger = logging.getLogger("moon.wrapper.api." + __name__) +LOGGER = logging.getLogger("moon.wrapper.api." + __name__) class OsloWrapper(Resource): @@ -35,15 +35,15 @@ class OsloWrapper(Resource): self.TIMEOUT = 5 def post(self): - logger.debug("POST {}".format(request.form)) + LOGGER.debug("POST {}".format(request.form)) response = flask.make_response("False") try: if self.manage_data(): response = flask.make_response("True") - except exceptions.AuthzException as e: - logger.error(e, exc_info=True) - except Exception as e: - logger.error(e, exc_info=True) + except exceptions.AuthzException as exception: + LOGGER.error(exception, exc_info=True) + except Exception as exception: + LOGGER.error(exception, exc_info=True) response.headers['content-type'] = 'application/octet-stream' return response @@ -64,20 +64,22 @@ class OsloWrapper(Resource): pass # note: default case - return target.get("project_id", "none") + return "none" @staticmethod def __get_project_id(target, credentials): - logger.info("__get_project_id {}".format(target)) - return target.get("project_id", "none") + project_id = target.get("project_id", None) + if not project_id: + project_id = credentials.get("project_id", None) + return project_id def get_interface_url(self, project_id): - logger.debug("project_id {}".format(project_id)) + LOGGER.debug("project_id {}".format(project_id)) for containers in self.CACHE.containers.values(): - logger.info("containers {}".format(containers)) + LOGGER.info("containers {}".format(containers)) for container in containers: if container.get("keystone_project_id") == project_id: - if "interface" in container['name']: + if "pipeline" in container['name']: return "http://{}:{}".format( container['name'], container['port']) @@ -86,7 +88,7 @@ class OsloWrapper(Resource): for containers in self.CACHE.containers.values(): for container in containers: if container.get("keystone_project_id") == project_id: - if "interface" in container['name']: + if "pipeline" in container['name']: return "http://{}:{}".format( container['name'], container['port']) @@ -100,14 +102,15 @@ class OsloWrapper(Resource): data = json.loads(request.data.decode("utf-8")) target = json.loads(data.get('target', {})) credentials = json.loads(data.get('credentials', {})) - rule = data.get('rule', "") + rule = data.get('rule', "").strip('"').strip("'") _subject = self.__get_subject(target, credentials) _object = self.__get_object(target, credentials) _action = rule + LOGGER.info("authz {} {} {}".format(_subject, _object, _action)) _project_id = self.__get_project_id(target, credentials) _pdp_id = self.CACHE.get_pdp_from_keystone_project(_project_id) interface_url = self.get_interface_url(_project_id) - logger.debug("interface_url={}".format(interface_url)) + LOGGER.debug("interface_url={}".format(interface_url)) req = requests.get("{}/authz/{}/{}/{}/{}".format( interface_url, _pdp_id, @@ -116,9 +119,9 @@ class OsloWrapper(Resource): _action )) - logger.debug("Get interface {}".format(req.text)) + LOGGER.debug("Get interface {}".format(req.text)) if req.status_code == 200: if req.json().get("result", False): return True - raise exceptions.AuthzException("error in authz request") \ No newline at end of file + raise exceptions.AuthzException("error in authz request") diff --git a/moon_wrapper/moon_wrapper/api/slaveupdate.py b/moon_wrapper/moon_wrapper/api/slaveupdate.py new file mode 100644 index 00000000..b2ce22f0 --- /dev/null +++ b/moon_wrapper/moon_wrapper/api/slaveupdate.py @@ -0,0 +1,87 @@ +# 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'. +""" +Authz is the endpoint to get authorization response +""" + +import logging +import json +import flask +from flask import request +from flask_restful import Resource +import requests +from python_moonutilities import exceptions + +__version__ = "0.1.0" + +LOGGER = logging.getLogger("moon.wrapper.api." + __name__) + + +class SlaveUpdate(Resource): + """ + Endpoint for authz requests + """ + + __urls__ = ( + "/update", + "/update/", + ) + + def __init__(self, **kwargs): + self.port = kwargs.get("port") + self.CACHE = kwargs.get("cache", {}) + self.TIMEOUT = 5 + + def put(self): + LOGGER.warning("PUT {}".format(request.form)) + response = flask.make_response("False") + try: + if self.update_slave(): + response = flask.make_response("True") + except Exception as exception: + LOGGER.error(exception, exc_info=True) + + response.headers['content-type'] = 'application/octet-stream' + return response + + def get_interface_url(self, pdp_id): + LOGGER.debug("pdp_id {}".format(pdp_id)) + for containers in self.CACHE.containers.values(): + LOGGER.info("containers0 {}".format(containers)) + for container in containers: + if container.get("pdp_id") == pdp_id: + if "pipeline" in container['name']: + yield "http://{}:{}".format( + container['name'], + container['port']) + self.CACHE.update() + # Note (asteroide): test an other time after the update + for containers in self.CACHE.containers.values(): + LOGGER.info("containers1 {}".format(containers)) + for container in containers: + if container.get("pdp_id") == pdp_id: + if "pipeline" in container['name']: + yield "http://{}:{}".format( + container['name'], + container['port']) + + def update_slave(self): + result = {} + result_list = [] + for _pdp_id in self.CACHE.pdp: + result[_pdp_id] = {} + for interface_url in self.get_interface_url(_pdp_id): + + req = requests.put("{}/update".format(interface_url), request.form) + + if req.status_code == 200: + if req.json().get("result", False): + result[_pdp_id][interface_url] = True + result_list.append(True) + continue + LOGGER.warning("Error in {} {}: {}".format(_pdp_id, interface_url, req.text)) + result[_pdp_id][interface_url] = False + result_list.append(False) + return all(result_list) diff --git a/moon_wrapper/moon_wrapper/http_server.py b/moon_wrapper/moon_wrapper/http_server.py index dfbaed9f..015bb285 100644 --- a/moon_wrapper/moon_wrapper/http_server.py +++ b/moon_wrapper/moon_wrapper/http_server.py @@ -10,17 +10,17 @@ import logging from moon_wrapper import __version__ from moon_wrapper.api.generic import Status, Logs, API from moon_wrapper.api.oslowrapper import OsloWrapper +from moon_wrapper.api.slaveupdate import SlaveUpdate from python_moonutilities.cache import Cache from python_moonutilities import configuration, exceptions -logger = logging.getLogger("moon.wrapper.http_server") - +LOGGER = logging.getLogger("moon.wrapper.http_server") CACHE = Cache() __API__ = ( Status, Logs, API - ) +) class Server: @@ -71,7 +71,7 @@ class Root(Resource): """ The root of the web service """ - __urls__ = ("/", ) + __urls__ = ("/",) __methods = ("get", "post", "put", "delete", "options") def get(self): @@ -111,7 +111,6 @@ class HTTPServer(Server): self.__hook_errors() def __hook_errors(self): - def get_404_json(e): return flask.make_response("False") @@ -134,7 +133,12 @@ class HTTPServer(Server): "cache": CACHE, } ) + self.api.add_resource(SlaveUpdate, *SlaveUpdate.__urls__, + resource_class_kwargs={ + "orchestrator_url": self.orchestrator_url, + "cache": CACHE, + } + ) def run(self): self.app.run(host=self._host, port=self._port, threaded=True) # nosec - diff --git a/moon_wrapper/moon_wrapper/server.py b/moon_wrapper/moon_wrapper/server.py index 280fdb68..77def174 100644 --- a/moon_wrapper/moon_wrapper/server.py +++ b/moon_wrapper/moon_wrapper/server.py @@ -28,5 +28,5 @@ def main(): if __name__ == '__main__': - server = main() - server.run() + SERVER = main() + SERVER.run() diff --git a/moon_wrapper/tests/unit_python/conftest.py b/moon_wrapper/tests/unit_python/conftest.py index 2c332c89..a6677849 100644 --- a/moon_wrapper/tests/unit_python/conftest.py +++ b/moon_wrapper/tests/unit_python/conftest.py @@ -288,10 +288,10 @@ def set_consul_and_db(monkeypatch): "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd", "port": 8080, "genre": "interface", - "name": "interface-paltry", + "name": "pipeline-paltry", "keystone_project_id": "a64beb1cc224474fb4badd43173e7101", "namespace": "moon", - "container": "wukongsun/moon_interface:v4.3" + "container": "wukongsun/moon_pipeline:v4.3" }, { "pdp_id": "b3d3e18abf3340e8b635fd49e6634ccd", @@ -308,7 +308,7 @@ def set_consul_and_db(monkeypatch): "pdp_id": "invalid_pdp_id", "port": 8080, "genre": "interface", - "name": "interface-paltry", + "name": "pipeline-paltry", "keystone_project_id": "invalid_project_id", "namespace": "moon", "container": "wukongsun/moon_authz:v4.3" @@ -696,7 +696,7 @@ def set_consul_and_db(monkeypatch): content=get_pickled_context() ) m.register_uri( - 'GET', 'http://interface-paltry:8080/authz/{}/{}/{}/{}'.format( + 'GET', 'http://pipeline-paltry:8080/authz/{}/{}/{}/{}'.format( CONTEXT.get("pdp_id"), CONTEXT.get("subject_name"), CONTEXT.get("object_name"), @@ -705,7 +705,7 @@ def set_consul_and_db(monkeypatch): json={"result": True, "message": "================"} ) m.register_uri( - 'GET', 'http://interface-paltry:8080/authz/{}/{}/{}/{}'.format( + 'GET', 'http://pipeline-paltry:8080/authz/{}/{}/{}/{}'.format( CONTEXT.get("invalid_pdp_id"), CONTEXT.get("subject_name"), CONTEXT.get("object_name"), diff --git a/python_moonclient/.gitignore b/python_moonclient/.gitignore new file mode 100644 index 00000000..9c29724f --- /dev/null +++ b/python_moonclient/.gitignore @@ -0,0 +1,106 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +/tests/unit_python/database.db diff --git a/python_moonclient/Changelog b/python_moonclient/Changelog index 9066e449..7cd14340 100644 --- a/python_moonclient/Changelog +++ b/python_moonclient/Changelog @@ -72,3 +72,7 @@ CHANGES 1.4.1 ----- - Update exception during configuration + +1.4.2 +----- +- apply PyLint rules \ No newline at end of file diff --git a/python_moonclient/python_moonclient/__init__.py b/python_moonclient/python_moonclient/__init__.py index e3ad9307..bbd31082 100644 --- a/python_moonclient/python_moonclient/__init__.py +++ b/python_moonclient/python_moonclient/__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__ = "1.4.1" +__version__ = "1.4.2" diff --git a/python_moonclient/python_moonclient/cli/authz.py b/python_moonclient/python_moonclient/cli/authz.py index 2f45e847..4edc307f 100644 --- a/python_moonclient/python_moonclient/cli/authz.py +++ b/python_moonclient/python_moonclient/cli/authz.py @@ -1,12 +1,13 @@ import logging -from cliff.command import Command + from importlib.machinery import SourceFileLoader +from cliff.command import Command from python_moonclient.core import models, policies, pdp, authz from python_moonclient.cli.parser import Parser from python_moonclient.cli.projects import ProjectsUtils -logger = logging.getLogger("moonclient.cli.authz") +LOGGER = logging.getLogger("moonclient.cli.authz") class SendAuthz(Command): @@ -29,13 +30,14 @@ class SendAuthz(Command): pdp.init(consul_host, consul_port) if parsed_args.filename: - logger.info("Loading: {}".format(parsed_args.filename)) + LOGGER.info("Loading: {}".format(parsed_args.filename)) m = SourceFileLoader("scenario", parsed_args.filename) scenario = m.load_module() - keystone_project_id = ProjectsUtils.get_project_id(pdp, parsed_args.id_project, parsed_args.name_project) + keystone_project_id = ProjectsUtils.get_project_id(pdp, parsed_args.id_project, + parsed_args.name_project) if keystone_project_id is None: - logger.error("Project not found !") + LOGGER.error("Project not found !") keystone_project_id = pdp.get_keystone_id(keystone_project_id) time_data = authz.send_requests( @@ -50,4 +52,4 @@ class SendAuthz(Command): destination=parsed_args.destination ) if not parsed_args.dry_run: - authz.save_data(parsed_args.write, time_data) \ No newline at end of file + authz.save_data(parsed_args.write, time_data) diff --git a/python_moonclient/python_moonclient/cli/export.py b/python_moonclient/python_moonclient/cli/export.py index a16928de..4ea5cf4f 100644 --- a/python_moonclient/python_moonclient/cli/export.py +++ b/python_moonclient/python_moonclient/cli/export.py @@ -8,6 +8,7 @@ from cliff.command import Command class Export(Command): """dump the complete moon database into a json file""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_filename_argument(parser) @@ -27,6 +28,5 @@ class Export(Command): json_file = open(parsed_args.filename, "w") json.dump(res["content"], json_file) return "Export ok!" - else: - return "Unexpected results : the returned json does not have the correct syntax" + return "Unexpected results : the returned json does not have the correct syntax" diff --git a/python_moonclient/python_moonclient/cli/import.py b/python_moonclient/python_moonclient/cli/import.py index c6c43439..efefc304 100644 --- a/python_moonclient/python_moonclient/cli/import.py +++ b/python_moonclient/python_moonclient/cli/import.py @@ -1,4 +1,3 @@ - from python_moonclient.core import models, policies, pdp, json_import from python_moonclient.cli.parser import Parser from python_moonclient.cli.projects import ProjectsUtils @@ -8,6 +7,7 @@ from cliff.command import Command class Import(Command): """import a json file describing pdps """ + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -26,4 +26,3 @@ class Import(Command): if "message" in res: return res["message"] return res - diff --git a/python_moonclient/python_moonclient/cli/models.py b/python_moonclient/python_moonclient/cli/models.py index 922a1830..369d9027 100644 --- a/python_moonclient/python_moonclient/cli/models.py +++ b/python_moonclient/python_moonclient/cli/models.py @@ -1,13 +1,12 @@ import logging +from importlib.machinery import SourceFileLoader from cliff.lister import Lister from cliff.command import Command -from importlib.machinery import SourceFileLoader - from python_moonclient.core import models, policies, pdp from python_moonclient.cli.parser import Parser from python_moonclient.cli.projects import ProjectsUtils -logger = logging.getLogger("moonclient.cli.pdps") +LOGGER = logging.getLogger("moonclient.cli.pdps") class ModelUtils: @@ -19,7 +18,8 @@ class ModelUtils: modelz = models.check_model() for _model_key, _model_value in modelz["models"].items(): if _model_key == parsed_id or _model_value['name'] == parsed_name: - # logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) + # LOGGER.info( + # "Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) return _model_key return None @@ -28,7 +28,8 @@ class ModelUtils: modelz = models.check_model() for _model_key, _model_value in modelz["models"].items(): if _model_key == parsed_id or _model_value['name'] == parsed_name: - # logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) + # LOGGER.info( + # "Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) return _model_value['name'] return None @@ -156,6 +157,3 @@ class SubjectCategoryAdd(Command): else: print("Error while creating subject category") # subject_categories = models.check_subject_category(subject_category_id) - - - diff --git a/python_moonclient/python_moonclient/cli/parser.py b/python_moonclient/python_moonclient/cli/parser.py index edd18a25..e71cd6c9 100644 --- a/python_moonclient/python_moonclient/cli/parser.py +++ b/python_moonclient/python_moonclient/cli/parser.py @@ -1,10 +1,13 @@ - class Parser: @staticmethod def add_common_options(parser): - parser.add_argument('--consul-host', help='Set the name of the consul server (default: 127.0.0.1)', default="127.0.0.1") - parser.add_argument('--consul-port', help='Set the port of the consult server (default: 30005)',default="30005") + parser.add_argument('--consul-host', + help='Set the name of the consul server (default: 127.0.0.1)', + default="127.0.0.1") + parser.add_argument('--consul-port', + help='Set the port of the consult server (default: 30005)', + default="30005") parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode") parser.add_argument("--debug", "-d", action='store_true', help="debug mode") @@ -30,7 +33,7 @@ class Parser: @staticmethod def add_id_or_name_argument(parser): - group = parser.add_mutually_exclusive_group(required=True) + group = parser.add_mutually_exclusive_group(required=True) Parser._add_id_argument(group) Parser._add_name_argument(group) @@ -44,7 +47,7 @@ class Parser: @staticmethod def add_id_or_name_pdp_argument(parser): - group = parser.add_mutually_exclusive_group(required=True) + group = parser.add_mutually_exclusive_group(required=True) Parser._add_id_pdp_argument(group) Parser._add_name_pdp_argument(group) @@ -55,10 +58,10 @@ class Parser: @staticmethod def _add_name_pdp_argument(parser): parser.add_argument('--name-pdp', help='name of the pdp') - + @staticmethod def add_id_or_name_project_argument(parser): - group = parser.add_mutually_exclusive_group(required=True) + group = parser.add_mutually_exclusive_group(required=True) Parser._add_id_project_argument(group) Parser._add_name_project_argument(group) @@ -92,4 +95,4 @@ class Parser: help="Execute stressing tests (warning delta measures " "will be false, implies -t)") parser.add_argument("--write", "-w", help="Write test data to a JSON file", - default="/tmp/data.json") + default="/tmp/data.json") diff --git a/python_moonclient/python_moonclient/cli/pdps.py b/python_moonclient/python_moonclient/cli/pdps.py index f1f8fe35..a4f7bba0 100644 --- a/python_moonclient/python_moonclient/cli/pdps.py +++ b/python_moonclient/python_moonclient/cli/pdps.py @@ -1,13 +1,13 @@ import logging +from importlib.machinery import SourceFileLoader from cliff.lister import Lister from cliff.command import Command -from importlib.machinery import SourceFileLoader from python_moonclient.core import models, policies, pdp from python_moonclient.cli.parser import Parser from python_moonclient.cli.projects import ProjectsUtils -logger = logging.getLogger("moonclient.cli.pdps") +LOGGER = logging.getLogger("moonclient.cli.pdps") class PdpUtils: @@ -19,7 +19,8 @@ class PdpUtils: pdps = pdp.check_pdp() for _pdp_key, _pdp_value in pdps["pdps"].items(): if _pdp_key == parsed_id or _pdp_value['name'] == parsed_name: - #logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) + # LOGGER.info( + # "Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) return _pdp_key return None @@ -28,10 +29,12 @@ class PdpUtils: pdps = pdp.check_pdp() for _pdp_key, _pdp_value in pdps["pdps"].items(): if _pdp_key == parsed_id or _pdp_value['name'] == parsed_name: - #logger.info("Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) + # LOGGER.info( + # "Found pdp : [key='{}' , name='{}']".format(_pdp_key, _pdp_value['name'])) return _pdp_value['name'] return None + class Pdps(Lister): """show the list of existing pdps """ @@ -50,13 +53,15 @@ class Pdps(Lister): pdps = pdp.check_pdp() - return (('Key' , 'Name', 'Project id'), - ((_pdp_key, _pdp_value['name'], _pdp_value['keystone_project_id']) for _pdp_key, _pdp_value in pdps["pdps"].items()) - ) + return (('Key', 'Name', 'Project id'), + ((_pdp_key, _pdp_value['name'], _pdp_value['keystone_project_id']) for + _pdp_key, _pdp_value in pdps["pdps"].items()) + ) class CreatePdp(Command): """create a new pdp from a json file and returns the newly created pdp id""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -78,7 +83,7 @@ class CreatePdp(Command): pdp.init(consul_host, consul_port) if parsed_args.filename: - logger.info("Loading: {}".format(parsed_args.filename)) + LOGGER.info("Loading: {}".format(parsed_args.filename)) m = SourceFileLoader("scenario", parsed_args.filename) scenario = m.load_module() @@ -94,11 +99,12 @@ class CreatePdp(Command): policy_id = policies.create_policy(scenario, model_id, meta_rule_list) pdp_id = pdp.create_pdp(scenario, policy_id=policy_id) pdp_name = PdpUtils.get_pdp_name(pdp, pdp_id, None) - logger.info("Pdp created : [id='{}', name='{}']".format(pdp_id, pdp_name)) + LOGGER.info("Pdp created : [id='{}', name='{}']".format(pdp_id, pdp_name)) class DeletePdp(Command): """delete an existing pdp""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -117,36 +123,38 @@ class DeletePdp(Command): _search = PdpUtils.get_pdp_id(pdp, parsed_args.id, parsed_args.name) _pdp_key = _search if _pdp_key is None: - logger.error("Error pdp not found ") + LOGGER.error("Error pdp not found ") return - #if parsed_args.id: + # if parsed_args.id: # logger.info("Deleting: {}".format(parsed_args.id)) # _search = parsed_args.id - #if parsed_args.name: + # if parsed_args.name: # logger.info("Deleting: {}".format(parsed_args.name)) # _search = parsed_args.name - - #pdps = pdp.check_pdp() - #for _pdp_key, _pdp_value in pdps["pdps"].items(): + + # pdps = pdp.check_pdp() + # for _pdp_key, _pdp_value in pdps["pdps"].items(): # if _pdp_key == _search or _pdp_value['name'] == _search: - logger.info("Found {}".format(_pdp_key)) + LOGGER.info("Found {}".format(_pdp_key)) pdp.delete_pdp(_pdp_key) pdps = pdp.check_pdp() - logger.info("Listing all PDP:") + LOGGER.info("Listing all PDP:") for _pdp_key, _pdp_value in pdps["pdps"].items(): - if _pdp_key == _search : #or _pdp_value['name'] == _search: - logger.error("Error in deleting {}".format(_search)) + if _pdp_key == _search: # or _pdp_value['name'] == _search: + LOGGER.error("Error in deleting {}".format(_search)) return (('Key', 'Name', 'Project id'), - ((_pdp_key, _pdp_value['name'], _pdp_value['keystone_project_id']) for _pdp_key, _pdp_value in + ((_pdp_key, _pdp_value['name'], _pdp_value['keystone_project_id']) for + _pdp_key, _pdp_value in pdps["pdps"].items()) ) class MapPdp(Command): """map an existing pdp to a keystone project""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -162,19 +170,21 @@ class MapPdp(Command): policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) - #_pdp_key = PdpUtils.get_pdp_id(pdp, parsed_args.id_pdp, parsed_args.name_pdp) + # _pdp_key = PdpUtils.get_pdp_id(pdp, parsed_args.id_pdp, parsed_args.name_pdp) _pdp_name = PdpUtils.get_pdp_name(pdp, parsed_args.id_pdp, parsed_args.name_pdp) if _pdp_name is None: - logger.error("Error pdp not found ") + LOGGER.error("Error pdp not found ") return - #_project_key = ProjectsUtils.get_project_id(pdp, parsed_args.id_project, parsed_args.name_project) - _project_name = ProjectsUtils.get_project_name(pdp, parsed_args.id_project, parsed_args.name_project) + # _project_key = ProjectsUtils.get_project_id( + # pdp, parsed_args.id_project, parsed_args.name_project) + _project_name = ProjectsUtils.get_project_name(pdp, parsed_args.id_project, + parsed_args.name_project) if _project_name is None: - logger.error("Error project not found ") + LOGGER.error("Error project not found ") return - logger.info("Mapping: {}=>{}".format(_pdp_name, _project_name)) + LOGGER.info("Mapping: {}=>{}".format(_pdp_name, _project_name)) - #pdp.map_to_keystone(pdp_id=parsed_args.id_pdp, keystone_project_id=parsed_args.id_project) + # pdp.map_to_keystone(pdp_id=parsed_args.id_pdp, keystone_project_id=parsed_args.id_project) pdp.map_to_keystone(pdp_id=_pdp_name, keystone_project_id=_project_name) diff --git a/python_moonclient/python_moonclient/cli/policies.py b/python_moonclient/python_moonclient/cli/policies.py index 94d13db1..af8e959b 100644 --- a/python_moonclient/python_moonclient/cli/policies.py +++ b/python_moonclient/python_moonclient/cli/policies.py @@ -6,7 +6,7 @@ from python_moonclient.cli.parser import Parser from python_moonclient.core import models, policies, pdp -logger = logging.getLogger("moonclient.cli.pdps") +LOGGER = logging.getLogger("moonclient.cli.pdps") class PoliciesUtils: @@ -16,23 +16,25 @@ class PoliciesUtils: @staticmethod def get_policy_id(policies, parsed_id, parsed_name): _policies = policies.check_policy() - for _policy_key, _policy_value in _policies["policies"].items(): + for _policy_key, _policy_value in _policies["policies"].items(): if _policy_key == parsed_id or _policy_value['name'] == parsed_name: - #logger.info("Found {}".format(_policy_key)) + # logger.info("Found {}".format(_policy_key)) return _policy_key return None @staticmethod def get_policy_name(policies, parsed_id, parsed_name): _policies = policies.check_policy() - for _policy_key, _policy_value in _policies["policies"].items(): + for _policy_key, _policy_value in _policies["policies"].items(): if _policy_key == parsed_id or _policy_value['name'] == parsed_name: - #logger.info("Found {}".format(_policy_key)) + # logger.info("Found {}".format(_policy_key)) return _policy_value['name'] return None + class Policies(Lister): """show the list of existing policies""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -47,9 +49,10 @@ class Policies(Lister): pdp.init(consul_host, consul_port) _policies = policies.check_policy() - return (('Key' , 'Name'), - ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in _policies["policies"].items()) - ) + return (('Key', 'Name'), + ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in + _policies["policies"].items()) + ) class Subjects(Lister): @@ -70,14 +73,15 @@ class Subjects(Lister): _policies = policies.check_subject(parsed_args.id, parsed_args.policy_id) - return (('Key' , 'Name'), - ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in _policies["policies"].items()) - ) - + return (('Key', 'Name'), + ((_policy_key, _policy_value['name']) for _policy_key, _policy_value in + _policies["policies"].items()) + ) class DeletePolicy(Command): """delete an existing policy""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -92,27 +96,28 @@ class DeletePolicy(Command): policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) - policy_id = PoliciesUtils.get_policy_id(policies,parsed_args.id, parsed_args.name) + policy_id = PoliciesUtils.get_policy_id(policies, parsed_args.id, parsed_args.name) policy_name = PoliciesUtils.get_policy_name(policies, parsed_args.id, parsed_args.name) - logger.info("Deleting: {}".format(policy_name)) + LOGGER.info("Deleting: {}".format(policy_name)) pdp.delete_pdp(policy_id) _policies = policies.check_policy() - #logger.info("Listing all Policies:") + # logger.info("Listing all Policies:") for _policy_key, _policy_value in _policies["policies"].items(): - #print(" {} {}".format(_policy_key, _policy_value['name'])) + # print(" {} {}".format(_policy_key, _policy_value['name'])) if _policy_key == policy_id: - logger.error("Error in deleting {}".format(policy_id)) + LOGGER.error("Error in deleting {}".format(policy_id)) return (('Key', 'Value'), - ((_policy_key, _policy_value) for _policy_key, _policy_value in _policies["policies"].items()) + ((_policy_key, _policy_value) for _policy_key, _policy_value in + _policies["policies"].items()) ) - class SubjectDatas(Lister): """list the subject data """ + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -128,17 +133,20 @@ class SubjectDatas(Lister): policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) - subject_data = policies.check_subject_data(parsed_args.policy_id, None, parsed_args.category_id) + subject_data = policies.check_subject_data(parsed_args.policy_id, None, + parsed_args.category_id) if len(subject_data["subject_data"]) == 0: - return (('Key', 'Name'),()) + return (('Key', 'Name'), ()) return (('Key', 'Name'), - ((_subject_key, subject_data["subject_data"][0]["data"][_subject_key]['name']) for _subject_key in subject_data["subject_data"][0]["data"].keys()) - ) + ((_subject_key, subject_data["subject_data"][0]["data"][_subject_key]['name']) for + _subject_key in subject_data["subject_data"][0]["data"].keys()) + ) class ObjectDatas(Lister): """list the object data""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -154,19 +162,22 @@ class ObjectDatas(Lister): policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) - object_datas = policies.check_object_data(parsed_args.policy_id, None, parsed_args.category_id) + object_datas = policies.check_object_data(parsed_args.policy_id, None, + parsed_args.category_id) if len(object_datas["object_data"]) == 0: - return (('Key', 'Name'),()) + return (('Key', 'Name'), ()) object_data = object_datas["object_data"][0]["data"] - res = (('Key', 'Name'), - ((_object_key, object_data[_object_key]["value"]['name']) for _object_key in list(object_data)) + res = (('Key', 'Name'), + ((_object_key, object_data[_object_key]["value"]['name']) for _object_key in + list(object_data)) ) return res class ActionDatas(Lister): """list the action data""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -182,19 +193,22 @@ class ActionDatas(Lister): policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) - action_datas = policies.check_action_data(parsed_args.policy_id, None, parsed_args.category_id) + action_datas = policies.check_action_data(parsed_args.policy_id, None, + parsed_args.category_id) if len(action_datas["action_data"]) == 0: - return (('Key', 'Name'),()) + return (('Key', 'Name'), ()) action_data = action_datas["action_data"][0]["data"] - res = (('Key', 'Name'), - ((_action_key, action_data[_action_key]["value"]['name']) for _action_key in list(action_data)) + res = (('Key', 'Name'), + ((_action_key, action_data[_action_key]["value"]['name']) for _action_key in + list(action_data)) ) return res class MetaRules(Lister): """list the meta rules""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -211,16 +225,18 @@ class MetaRules(Lister): metarule_datas = policies.check_meta_rule() if len(metarule_datas["meta_rules"]) == 0: - return (('Key', 'Name'),()) + return (('Key', 'Name'), ()) metarule_data = metarule_datas["meta_rules"] - res = (('Key', 'Name'), - ((_key, metarule_data[_key]['name']) for _key in list(metarule_data)) + res = (('Key', 'Name'), + ((_key, metarule_data[_key]['name']) for _key in list(metarule_data)) ) return res + class CreateSubjectData(Command): """create a subject data according to a policy and a category""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -237,10 +253,12 @@ class CreateSubjectData(Command): policies.init(consul_host, consul_port) pdp.init(consul_host, consul_port) - subject_data_id = policies.add_subject_data(parsed_args.policy_id, parsed_args.category_id, parsed_args.name) + subject_data_id = policies.add_subject_data(parsed_args.policy_id, parsed_args.category_id, + parsed_args.name) if subject_data_id is not None: print("Subject category created with id {}".format(subject_data_id)) else: print("Error while creating subject category") - subject_data = policies.check_subject_data(parsed_args.policy_id, None, parsed_args.category_id) + subject_data = policies.check_subject_data(parsed_args.policy_id, None, + parsed_args.category_id) # subject_categories = models.check_subject_category(subject_category_id) diff --git a/python_moonclient/python_moonclient/cli/projects.py b/python_moonclient/python_moonclient/cli/projects.py index c4653a51..1caa0ace 100644 --- a/python_moonclient/python_moonclient/cli/projects.py +++ b/python_moonclient/python_moonclient/cli/projects.py @@ -3,7 +3,7 @@ from python_moonclient.core import models, policies, pdp from python_moonclient.cli.parser import Parser from cliff.lister import Lister -logger = logging.getLogger("moonclient.cli.projects") +LOGGER = logging.getLogger("moonclient.cli.projects") class ProjectsUtils: @@ -15,7 +15,8 @@ class ProjectsUtils: projects = pdp.get_keystone_projects() for _project_value in projects['projects']: if _project_value['id'] == parsed_id or _project_value['name'] == parsed_name: - #logger.info("Found project : [key='{}' , name='{}']".format(_project_value['id'], _project_value['name'])) + # LOGGER.info( + # "Found project : [key='{}' , name='{}']".format(_project_value['id'], _project_value['name'])) return _project_value['id'] return None @@ -24,7 +25,8 @@ class ProjectsUtils: projects = pdp.get_keystone_projects() for _project_value in projects['projects']: if _project_value['id'] == parsed_id or _project_value['name'] == parsed_name: - #logger.info("Found project : [key='{}' , name='{}']".format(_project_value['id'], _project_value['name'])) + # LOGGER.info( + # "Found project : [key='{}' , name='{}']".format(_project_value['id'], _project_value['name'])) return _project_value['name'] return None @@ -47,10 +49,6 @@ class Projects(Lister): projects = pdp.get_keystone_projects() - return (('Id' , 'Name'), - ((_project['id'], _project['name']) for _project in projects['projects']) - ) - - - - + return (('Id', 'Name'), + ((_project['id'], _project['name']) for _project in projects['projects']) + ) diff --git a/python_moonclient/python_moonclient/cli/slaves.py b/python_moonclient/python_moonclient/cli/slaves.py index 1880f4c2..587e9033 100644 --- a/python_moonclient/python_moonclient/cli/slaves.py +++ b/python_moonclient/python_moonclient/cli/slaves.py @@ -5,7 +5,7 @@ from cliff.command import Command from python_moonclient.core import models, policies, pdp, slaves from python_moonclient.cli.parser import Parser -logger = logging.getLogger("moonclient.cli.slaves") +LOGGER = logging.getLogger("moonclient.cli.slaves") class SlavesUtils: @@ -17,13 +17,14 @@ class SlavesUtils: _slaves = slaves.get_slaves() for _slave_value in _slaves['slaves']: if _slave_value['name'] == parsed_name: - logger.info("Found {}".format(_slave_value['name'])) + LOGGER.info("Found {}".format(_slave_value['name'])) return _slave_value['name'] return None class Slaves(Lister): """show the list of slaves""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -43,12 +44,14 @@ class Slaves(Lister): slaves.init(consul_host, consul_port) return (('Name', 'Configured'), - ((value['name'], value['configured']) for value in slaves.get_slaves().get('slaves', dict())) + ((value['name'], value['configured']) for value in + slaves.get_slaves().get('slaves', dict())) ) class SetSlave(Command): """update an existing slave to a configured state""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -73,14 +76,14 @@ class SetSlave(Command): slave_input_name = "kubernetes-admin@kubernetes" slaves.set_slave(slave_input_name) - #if slave_name is None: + # if slave_name is None: # slave_name = "kubernetes-admin@kubernetes" - #if parsed_args.name: + # if parsed_args.name: # slave_name = parsed_args.name print(" {} (configured=True)".format(slave_input_name)) - #for value in slaves.set_slave(slave_name).get('slaves', dict()): + # for value in slaves.set_slave(slave_name).get('slaves', dict()): # if value['configured']: # print(" {} (configured)".format(value['name'])) # else: @@ -89,6 +92,7 @@ class SetSlave(Command): class DeleteSlave(Command): """update an existing slave to a unconfigured state""" + def get_parser(self, prog_name): parser = super().get_parser(prog_name) Parser.add_common_options(parser) @@ -114,7 +118,3 @@ class DeleteSlave(Command): slaves.delete_slave(slave_input_name) print(" {} (configured=False)".format(slave_input_name)) - - - - diff --git a/python_moonclient/python_moonclient/core/authz.py b/python_moonclient/python_moonclient/core/authz.py index 7bf9b57b..d331004c 100644 --- a/python_moonclient/python_moonclient/core/authz.py +++ b/python_moonclient/python_moonclient/core/authz.py @@ -1,19 +1,19 @@ +from uuid import uuid4 import copy import logging import threading -import requests import time import json import random -from uuid import uuid4 +import requests HOST_MANAGER = None PORT_MANAGER = None HOST_KEYSTONE = None PORT_KEYSTONE = None -lock = threading.Lock() -logger = logging.getLogger("moonclient.core.authz") +LOCK = threading.Lock() +LOGGER = logging.getLogger("moonclient.core.authz") def _construct_payload(creds, current_rule, enforcer, target): @@ -43,15 +43,16 @@ def _send(url, data=None, stress_test=False): try: if stress_test: current_request['start'] = time.time() - # with lock: + # with LOCK: res = requests.get(url) current_request['end'] = time.time() current_request['delta'] = current_request["end"] - current_request["start"] else: - with lock: + with LOCK: current_request['start'] = time.time() if data: - data, _ = _construct_payload(data['credentials'], data['rule'], True, data['target']) + data, _ = _construct_payload(data['credentials'], data['rule'], True, + data['target']) res = requests.post(url, json=data, headers={'content-type': "application/x-www-form-urlencode"} ) @@ -60,34 +61,34 @@ def _send(url, data=None, stress_test=False): current_request['end'] = time.time() current_request['delta'] = current_request["end"] - current_request["start"] except requests.exceptions.ConnectionError: - logger.warning("Unable to connect to server") + LOGGER.warning("Unable to connect to server") return {} if not stress_test: try: j = res.json() if res.status_code == 200: - logger.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url)) + LOGGER.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url)) elif res.status_code == 401: - logger.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url)) + LOGGER.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url)) else: - logger.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text)) + LOGGER.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text)) except Exception as e: if res.text == "True": - logger.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url)) + LOGGER.warning("\033[1m{}\033[m \033[32mGrant\033[m".format(url)) elif res.text == "False": - logger.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url)) + LOGGER.warning("\033[1m{}\033[m \033[31mDeny\033[m".format(url)) else: - logger.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text)) - logger.exception(e) - logger.error(res.text) + LOGGER.error("\033[1m{}\033[m {} {}".format(url, res.status_code, res.text)) + LOGGER.exception(e) + LOGGER.error(res.text) else: if j.get("result"): # logger.warning("{} \033[32m{}\033[m".format(url, j.get("result"))) - logger.debug("{}".format(j.get("error", ""))) + LOGGER.debug("{}".format(j.get("error", ""))) current_request['result'] = "Grant" else: # logger.warning("{} \033[31m{}\033[m".format(url, "Deny")) - logger.debug("{}".format(j)) + LOGGER.debug("{}".format(j)) current_request['result'] = "Deny" return current_request @@ -110,35 +111,37 @@ class AsyncGet(threading.Thread): self.result['index'] = self.index -def send_requests(scenario, authz_host, authz_port, keystone_project_id, request_second=1, limit=500, +def send_requests(scenario, authz_host, authz_port, keystone_project_id, request_second=1, + limit=500, dry_run=None, stress_test=False, destination="wrapper"): backgrounds = [] time_data = list() start_timing = time.time() request_cpt = 0 - SUBJECTS = tuple(scenario.subjects.keys()) - OBJECTS = tuple(scenario.objects.keys()) - ACTIONS = tuple(scenario.actions.keys()) + subjects = tuple(scenario.subjects.keys()) + objects = tuple(scenario.objects.keys()) + actions = tuple(scenario.actions.keys()) while request_cpt < limit: - rule = (random.choice(SUBJECTS), random.choice(OBJECTS), random.choice(ACTIONS)) + rule = (random.choice(subjects), random.choice(objects), random.choice(actions)) if destination.lower() == "wrapper": url = "http://{}:{}/authz/oslo".format(authz_host, authz_port) data = { 'target': { - "user_id": random.choice(SUBJECTS), + "user_id": random.choice(subjects), "target": { - "name": random.choice(OBJECTS) + "name": random.choice(objects) }, "project_id": keystone_project_id }, 'credentials': None, - 'rule': random.choice(ACTIONS) + 'rule': random.choice(actions) } else: - url = "http://{}:{}/authz/{}/{}".format(authz_host, authz_port, keystone_project_id, "/".join(rule)) + url = "http://{}:{}/authz/{}/{}".format(authz_host, authz_port, keystone_project_id, + "/".join(rule)) data = None if dry_run: - logger.info(url) + LOGGER.info(url) continue request_cpt += 1 if stress_test: @@ -150,9 +153,9 @@ def send_requests(scenario, authz_host, authz_port, keystone_project_id, request background.start() if request_second > 0: if request_cpt % request_second == 0: - if time.time()-start_timing < 1: + if time.time() - start_timing < 1: while True: - if time.time()-start_timing > 1: + if time.time() - start_timing > 1: break start_timing = time.time() if not stress_test: @@ -175,4 +178,3 @@ def get_delta(time_data): time_delta_sum1 += item['delta'] time_delta_average1 = time_delta_sum1 / len(time_data) return time_delta, time_delta_average1 - diff --git a/python_moonclient/python_moonclient/core/check_tools.py b/python_moonclient/python_moonclient/core/check_tools.py index 8138f54e..381e92c7 100644 --- a/python_moonclient/python_moonclient/core/check_tools.py +++ b/python_moonclient/python_moonclient/core/check_tools.py @@ -10,16 +10,19 @@ def check_optionnal_result(result): def check_result(result): if type(result) is not dict or "result" not in result: - raise MoonCliException("Unexpected request result. It should be a dictionnary with a 'result' entry") + raise MoonCliException( + "Unexpected request result. It should be a dictionnary with a 'result' entry") if result["result"] is None: raise MoonCliException("Unexpected request result. The 'result' entry shall not be null") def _check_generic_in_result(field, result, check_not_null=False): if type(field) is not str or type(result) is not dict or field not in result: - raise MoonCliException("Unexpected request result. It should be a dictionnary with a '{}' entry".format(field)) + raise MoonCliException( + "Unexpected request result. It should be a dictionnary with a '{}' entry".format(field)) if check_not_null is True and result[field] is None: - raise MoonCliException("Unexpected request result. The '{}' entry shall not be null".format(field)) + raise MoonCliException( + "Unexpected request result. The '{}' entry shall not be null".format(field)) def check_slaves_in_result(result): @@ -93,13 +96,17 @@ def check_pdp_id(pdp_id, result): def _check_generic_name(field, name, field_elt_id, result, do_check_name=True): if type(field) is str: if result[field] is None: - raise MoonCliException("Unexpected request result : {} shall not be empty".format(field)) + raise MoonCliException( + "Unexpected request result : {} shall not be empty".format(field)) if field_elt_id not in result[field]: raise MoonCliException("Unexpected request result. Unknown {} id".format(field)) if "name" not in result[field][field_elt_id]: - raise MoonCliException("Unexpected request result : {} with id {} has no name".format(field, field_elt_id)) + raise MoonCliException( + "Unexpected request result : {} with id {} has no name".format(field, field_elt_id)) if do_check_name and name != result[field][field_elt_id]["name"]: - raise MoonCliException("Unexpected request result : {} with id {} has a bad name. Expected {}".format(field, field_elt_id, name)) + raise MoonCliException( + "Unexpected request result : {} with id {} has a bad name. Expected {}".format( + field, field_elt_id, name)) def check_model_name(name, model_id, result, do_check_name): @@ -159,7 +166,9 @@ def check_acat_id_in_dict(acat_id, in_dict): def check_policy_id_in_pipeline(policy_id, pipeline): if policy_id not in pipeline: - raise MoonCliException("Unexpected request result. The policy id {} shall be in the pipeline".format(policy_id)) + raise MoonCliException( + "Unexpected request result. The policy id {} shall be in the pipeline".format( + policy_id)) def _check_generic_policy_in_dict(field, policy_id, in_dict): @@ -167,10 +176,12 @@ def _check_generic_policy_in_dict(field, policy_id, in_dict): if policy_id is not None: if "policy_list" not in in_dict: raise MoonCliException( - "Unexpected request result. The policy list of the {} shall not be empty".format(field)) + "Unexpected request result. The policy list of the {} shall not be empty".format( + field)) if policy_id not in in_dict["policy_list"]: raise MoonCliException( - "Unexpected request result. The policy with id {} shall be in the {}".format(policy_id, field)) + "Unexpected request result. The policy with id {} shall be in the {}".format( + policy_id, field)) def check_subject_policy(policy_id, in_dict): @@ -188,14 +199,19 @@ def check_action_policy(policy_id, in_dict): def _check_generic_elt_id(field1, field1_id, field2, field2_id, result): if type(field1) is str and type(field2) is str: if result[field1] is None: - raise MoonCliException("Unexpected request result: {} shall not be empty".format(field1)) + raise MoonCliException( + "Unexpected request result: {} shall not be empty".format(field1)) if field1_id not in result[field1]: raise MoonCliException("Unexpected request result. Unknown {} with id".format(field1)) if field2 not in result[field1][field1_id]: - raise MoonCliException("Unexpected request result. {} element with id {} has no {} field".format(field1, field1_id, field2)) + raise MoonCliException( + "Unexpected request result. {} element with id {} has no {} field".format(field1, + field1_id, + field2)) if field2_id != result[field1][field1_id][field2]: raise MoonCliException( - "Unexpected request result. {} element with id {} has a bad {} id. Expected {}".format(field1, field1_id, field2, field2_id)) + "Unexpected request result. {} element with id {} has a bad {} id. Expected {}".format( + field1, field1_id, field2, field2_id)) def check_policy_model_id(model_id, policy_id, result): @@ -213,7 +229,8 @@ def check_subject_description(description, in_dict): "Unexpected request result. The description of the subject shall not be empty") if description not in in_dict["description"]: raise MoonCliException( - "Unexpected request result. The description {} shall be in the subject".format(description)) + "Unexpected request result. The description {} shall be in the subject".format( + description)) def check_meta_rules_list_in_model(meta_rule_list, model_id, result): @@ -222,9 +239,13 @@ def check_meta_rules_list_in_model(meta_rule_list, model_id, result): if model_id not in result['models']: raise MoonCliException("Unexpected request result. Unknown Model id") if "meta_rules" not in result['models'][model_id]: - raise MoonCliException("Unexpected request result. Meta rules related to model with id {} are empty".format(model_id)) + raise MoonCliException( + "Unexpected request result. Meta rules related to model with id {} are empty".format( + model_id)) if meta_rule_list != result['models'][model_id]["meta_rules"]: - raise MoonCliException("Unexpected request result. Meta rule of model with id {} are different from those expected".format(model_id)) + raise MoonCliException( + "Unexpected request result. Meta rule of model with id {} are different from those expected".format( + model_id)) def check_name_in_slaves(name, slaves): @@ -235,10 +256,11 @@ def check_name_in_slaves(name, slaves): raise MoonCliException("The slave '{}' was not found !".format(name)) -def _check_generic_data_data(field,result): +def _check_generic_data_data(field, result): if type(field) is str: if field not in result: - raise MoonCliException("Unexpected request result. The {} field shall be in result".format(field)) + raise MoonCliException( + "Unexpected request result. The {} field shall be in result".format(field)) # if "data" not in resulti[field]: # raise MoonCliException("Unexpected request result. The data field shall be in result['{}']".format(field)) @@ -248,7 +270,8 @@ def _check_id_in_generic_data_data(field, data_id, result): _check_generic_data_data(field, result) for _data in result[field]: if data_id not in list(_data['data'].keys()): - raise MoonCliException("Unexpected request result. Data id {} not in {}".format(data_id, field)) + raise MoonCliException( + "Unexpected request result. Data id {} not in {}".format(data_id, field)) def _check_id_not_in_generic_data_data(field, data_id, result): @@ -256,14 +279,18 @@ def _check_id_not_in_generic_data_data(field, data_id, result): _check_generic_data_data(field, result) for _data in result[field]: if data_id in list(_data['data'].keys()): - raise MoonCliException("Unexpected request result. Data id {} shall not be in {}".format(data_id, field)) + raise MoonCliException( + "Unexpected request result. Data id {} shall not be in {}".format(data_id, + field)) def _check_category_in_generic_data_data(field, category_id, result): _check_generic_data_data(field, result) for _data in result[field]: if category_id != _data["category_id"]: - raise MoonCliException("Unexpected request result. Category id {} not in {} data".format(category_id, field)) + raise MoonCliException( + "Unexpected request result. Category id {} not in {} data".format(category_id, + field)) def check_subject_data_data(result): @@ -314,74 +341,92 @@ def check_category_id_in_action_data_data(category_id, result): _check_category_in_generic_data_data('action_data', category_id, result) -def _check_generic_assignments(field, field_id_name, field_id, field_cat_id, field_data_id, result): +def _check_generic_assignments(field, field_id_name, field_id, field_cat_id, field_data_id, result): if type(field) is str and type(field_id_name) is str: for key in result[field]: if field_id_name not in result[field][key]: - raise MoonCliException("Unexpected request result. subject_id not in result[{}] data".format(field)) + raise MoonCliException( + "Unexpected request result. subject_id not in result[{}] data".format(field)) if "category_id" not in result[field][key]: - raise MoonCliException("Unexpected request result. category_id not in result[{}] data".format(field)) + raise MoonCliException( + "Unexpected request result. category_id not in result[{}] data".format(field)) if "assignments" not in result[field][key]: - raise MoonCliException("Unexpected request result. assignments not in result[{}] data".format(field)) + raise MoonCliException( + "Unexpected request result. assignments not in result[{}] data".format(field)) if result[field][key][field_id_name] == field_id and \ result[field][key]["category_id"] == field_cat_id: if field_data_id not in result[field][key]["assignments"]: raise MoonCliException( - "Unexpected request result. {} data with id {} not in result[{}][]['assignements'] data".format(field, field_data_id, field)) + "Unexpected request result. {} data with id {} not in result[{}][]['assignements'] data".format( + field, field_data_id, field)) def check_subject_assignements(subject_id, subject_act_id, subject_data_id, result): - _check_generic_assignments("subject_assignments", "subject_id", subject_id, subject_act_id, subject_data_id, result) + _check_generic_assignments("subject_assignments", "subject_id", subject_id, subject_act_id, + subject_data_id, result) def check_object_assignements(object_id, object_act_id, object_data_id, result): - _check_generic_assignments("object_assignments", "object_id", object_id, object_act_id, object_data_id, result) + _check_generic_assignments("object_assignments", "object_id", object_id, object_act_id, + object_data_id, result) def check_action_assignements(action_id, action_act_id, action_data_id, result): - _check_generic_assignments("action_assignments", "action_id", action_id, action_act_id, action_data_id, result) + _check_generic_assignments("action_assignments", "action_id", action_id, action_act_id, + action_data_id, result) -def _check_not_generic_assignments(field, field_id_name, field_id, field_cat_id, field_data_id, result): +def _check_not_generic_assignments(field, field_id_name, field_id, field_cat_id, field_data_id, + result): if type(field) is str and type(field_id_name) is str: for key in result[field]: if field_id_name not in result[field][key]: - raise MoonCliException("Unexpected request result. subject_id not in result[{}] data".format(field)) + raise MoonCliException( + "Unexpected request result. subject_id not in result[{}] data".format(field)) if "category_id" not in result[field][key]: - raise MoonCliException("Unexpected request result. category_id not in result[{}] data".format(field)) + raise MoonCliException( + "Unexpected request result. category_id not in result[{}] data".format(field)) if "assignments" not in result[field][key]: - raise MoonCliException("Unexpected request result. assignments not in result[{}] data".format(field)) + raise MoonCliException( + "Unexpected request result. assignments not in result[{}] data".format(field)) if result[field][key]['subject_id'] == field_id and \ result[field][key]["category_id"] == field_cat_id: if field_data_id in result[field][key]["assignments"]: raise MoonCliException( - "Unexpected request result. {} data with id {} shall not be in result[{}][]['assignements'] data".format(field, field_data_id, field)) + "Unexpected request result. {} data with id {} shall not be in result[{}][]['assignements'] data".format( + field, field_data_id, field)) def check_not_subject_assignements(subject_id, subject_act_id, subject_data_id, result): - _check_not_generic_assignments("subject_assignments", "subject_id", subject_id, subject_act_id, subject_data_id, result) + _check_not_generic_assignments("subject_assignments", "subject_id", subject_id, subject_act_id, + subject_data_id, result) def check_not_object_assignements(object_id, object_act_id, object_data_id, result): - _check_not_generic_assignments("object_assignments", "object_id", object_id, object_act_id, object_data_id, result) + _check_not_generic_assignments("object_assignments", "object_id", object_id, object_act_id, + object_data_id, result) def check_not_action_assignements(action_id, action_act_id, action_data_id, result): - _check_not_generic_assignments("action_assignments", "action_id", action_id, action_act_id, action_data_id, result) + _check_not_generic_assignments("action_assignments", "action_id", action_id, action_act_id, + action_data_id, result) def check_policy_id_in_dict(policy_id, in_dict): if "policy_id" not in in_dict: raise MoonCliException("Unexpected request result. policy_id not in result") if policy_id != in_dict["policy_id"]: - raise MoonCliException("Unexpected request result. Bad policy id in result, expected {}".format(policy_id)) + raise MoonCliException( + "Unexpected request result. Bad policy id in result, expected {}".format(policy_id)) def check_meta_rule_id_in_dict(meta_rule_id, in_dict): if "meta_rule_id" not in in_dict: raise MoonCliException("Unexpected request result. meta_rule_id not in result") if meta_rule_id != in_dict["meta_rule_id"]: - raise MoonCliException("Unexpected request result. Bad meta rule id in result, expected {}".format(meta_rule_id)) + raise MoonCliException( + "Unexpected request result. Bad meta rule id in result, expected {}".format( + meta_rule_id)) def check_rule_in_dict(rule, in_dict): @@ -399,7 +444,8 @@ def check_rule_id_in_list(meta_rule_id, rule_id, rule, in_dict): if meta_rule_id == item["meta_rule_id"]: if rule_id == item["id"]: if rule != item["rule"]: - raise MoonCliException("Unexpected request result. Bad rule in result, expected {}".format(rule)) + raise MoonCliException( + "Unexpected request result. Bad rule in result, expected {}".format(rule)) def check_rule_id_not_in_list(rule_id, in_dict): @@ -408,4 +454,5 @@ def check_rule_id_not_in_list(rule_id, in_dict): if rule_id == item["id"]: found_rule = True if found_rule is True: - raise MoonCliException("Unexpected request result. Rule with id {} shall not be in result".format(rule_id)) \ No newline at end of file + raise MoonCliException( + "Unexpected request result. Rule with id {} shall not be in result".format(rule_id)) diff --git a/python_moonclient/python_moonclient/core/cli_exceptions.py b/python_moonclient/python_moonclient/core/cli_exceptions.py index 2ec2ed18..01fd23e0 100644 --- a/python_moonclient/python_moonclient/core/cli_exceptions.py +++ b/python_moonclient/python_moonclient/core/cli_exceptions.py @@ -1,7 +1,4 @@ class MoonCliException(Exception): def __init__(self, message): - # Call the base class constructor with the parameters it needs super(MoonCliException, self).__init__(message) - - diff --git a/python_moonclient/python_moonclient/core/config.py b/python_moonclient/python_moonclient/core/config.py index f8e3fe29..c123499b 100644 --- a/python_moonclient/python_moonclient/core/config.py +++ b/python_moonclient/python_moonclient/core/config.py @@ -14,11 +14,10 @@ def get_configuration(consul_host, consul_port, key): if len(data) == 1: data = data[0] return {data["Key"]: json.loads(base64.b64decode(data["Value"]).decode("utf-8"))} - else: - return [ - {item["Key"]: json.loads(base64.b64decode(item["Value"]).decode("utf-8"))} - for item in data - ] + return [ + {item["Key"]: json.loads(base64.b64decode(item["Value"]).decode("utf-8"))} + for item in data + ] def get_config_data(consul_host, consul_port): @@ -31,9 +30,9 @@ def get_config_data(consul_host, consul_port): 'components/manager')['components/manager']['external']['port'] try: requests.get("http://{}:{}/".format( - conf_data['manager_host'], - conf_data['manager_port'] - ), + conf_data['manager_host'], + conf_data['manager_port'] + ), timeout=2) except requests.exceptions.ConnectionError: conf_data['manager_host'] = get_configuration(consul_host, consul_port, @@ -54,9 +53,12 @@ def get_config_data(consul_host, consul_port): 'openstack/keystone')['openstack/keystone']['url'] conf_data['keystone_user'] = get_configuration(consul_host, consul_port, - 'openstack/keystone')['openstack/keystone']['user'] + 'openstack/keystone')['openstack/keystone'][ + 'user'] conf_data['keystone_password'] = get_configuration(consul_host, consul_port, - 'openstack/keystone')['openstack/keystone']['password'] + 'openstack/keystone')['openstack/keystone'][ + 'password'] conf_data['keystone_project'] = get_configuration(consul_host, consul_port, - 'openstack/keystone')['openstack/keystone']['project'] + 'openstack/keystone')['openstack/keystone'][ + 'project'] return conf_data diff --git a/python_moonclient/python_moonclient/core/json_export.py b/python_moonclient/python_moonclient/core/json_export.py index 53c1b1f0..edaeb177 100644 --- a/python_moonclient/python_moonclient/core/json_export.py +++ b/python_moonclient/python_moonclient/core/json_export.py @@ -1,14 +1,14 @@ import logging -import requests import copy +import requests from python_moonclient.core import config - -logger = logging.getLogger("moonclient.core.export_json") +LOGGER = logging.getLogger("moonclient.core.export_json") URL = None HEADERS = None + def init(consul_host, consul_port): conf_data = config.get_config_data(consul_host, consul_port) global URL, HEADERS @@ -23,4 +23,4 @@ def export_to_json(): req = requests.get(URL.format("/export")) req.raise_for_status() result = req.json() - return result \ No newline at end of file + return result diff --git a/python_moonclient/python_moonclient/core/json_import.py b/python_moonclient/python_moonclient/core/json_import.py index a724476b..b65ec39b 100644 --- a/python_moonclient/python_moonclient/core/json_import.py +++ b/python_moonclient/python_moonclient/core/json_import.py @@ -3,12 +3,12 @@ import requests import copy from python_moonclient.core import config - -logger = logging.getLogger("moonclient.core.import_json") +LOGGER = logging.getLogger("moonclient.core.import_json") URL = None HEADERS = None + def init(consul_host, consul_port): conf_data = config.get_config_data(consul_host, consul_port) global URL, HEADERS @@ -23,7 +23,7 @@ def import_json(file_name): files = {'file': open(file_name, 'rb')} req = requests.post(URL.format("/import"), files=files) result = req.json() - if isinstance(result,dict) and "message" in result: + if isinstance(result, dict) and "message" in result: req.reason = result["message"] req.raise_for_status() - return result \ No newline at end of file + return result diff --git a/python_moonclient/python_moonclient/core/models.py b/python_moonclient/python_moonclient/core/models.py index 709b4a7a..8d3c8858 100644 --- a/python_moonclient/python_moonclient/core/models.py +++ b/python_moonclient/python_moonclient/core/models.py @@ -1,11 +1,10 @@ import logging -import requests import copy +import requests from python_moonclient.core import config from python_moonclient.core.check_tools import * -logger = logging.getLogger("moonclient.core.models") - +LOGGER = logging.getLogger("moonclient.core.models") URL = None HEADERS = None @@ -241,17 +240,17 @@ def add_meta_rule_to_model(model_id, meta_rule_id): def create_model(scenario, model_id=None): - logger.info("Creating model {}".format(scenario.model_name)) + LOGGER.info("Creating model {}".format(scenario.model_name)) if not model_id: - logger.info("Add model") + LOGGER.info("Add model") model_id = add_model(name=scenario.model_name) - logger.info("Add subject categories") + LOGGER.info("Add subject categories") for cat in scenario.subject_categories: scenario.subject_categories[cat] = add_subject_category(name=cat) - logger.info("Add object categories") + LOGGER.info("Add object categories") for cat in scenario.object_categories: scenario.object_categories[cat] = add_object_category(name=cat) - logger.info("Add action categories") + LOGGER.info("Add action categories") for cat in scenario.action_categories: scenario.action_categories[cat] = add_action_category(name=cat) sub_cat = [] @@ -272,7 +271,7 @@ def create_model(scenario, model_id=None): meta_rule_id = _meta_rule_id break else: - logger.info("Add meta rule") + LOGGER.info("Add meta rule") meta_rule_id = add_meta_rule(item_name, sub_cat, ob_cat, act_cat) item_value["id"] = meta_rule_id if meta_rule_id not in meta_rule_list: diff --git a/python_moonclient/python_moonclient/core/pdp.py b/python_moonclient/python_moonclient/core/pdp.py index 4e9e404c..f67a4d01 100644 --- a/python_moonclient/python_moonclient/core/pdp.py +++ b/python_moonclient/python_moonclient/core/pdp.py @@ -4,8 +4,7 @@ import requests from python_moonclient.core import config from python_moonclient.core.check_tools import * - -logger = logging.getLogger("python_moonclient.core.pdp") +LOGGER = logging.getLogger("python_moonclient.core.pdp") URL = None HEADERS = None @@ -14,7 +13,6 @@ KEYSTONE_PASSWORD = None KEYSTONE_PROJECT = None KEYSTONE_SERVER = None - pdp_template = { "name": "test_pdp", "security_pipeline": [], @@ -63,11 +61,11 @@ def get_keystone_projects(): } req = requests.post("{}/auth/tokens".format(KEYSTONE_SERVER), json=data_auth, headers=HEADERS) - logger.debug("{}/auth/tokens".format(KEYSTONE_SERVER)) - logger.debug(req.text) + LOGGER.debug("{}/auth/tokens".format(KEYSTONE_SERVER)) + LOGGER.debug(req.text) req.raise_for_status() - TOKEN = req.headers['X-Subject-Token'] - HEADERS['X-Auth-Token'] = TOKEN + token = req.headers['X-Subject-Token'] + HEADERS['X-Auth-Token'] = token req = requests.get("{}/projects".format(KEYSTONE_SERVER), headers=HEADERS) if req.status_code not in (200, 201): data_auth["auth"]["scope"] = { @@ -78,10 +76,11 @@ def get_keystone_projects(): } } } - req = requests.post("{}/auth/tokens".format(KEYSTONE_SERVER), json=data_auth, headers=HEADERS) + req = requests.post("{}/auth/tokens".format(KEYSTONE_SERVER), json=data_auth, + headers=HEADERS) req.raise_for_status() - TOKEN = req.headers['X-Subject-Token'] - HEADERS['X-Auth-Token'] = TOKEN + token = req.headers['X-Subject-Token'] + HEADERS['X-Auth-Token'] = token req = requests.get("{}/projects".format(KEYSTONE_SERVER), headers=HEADERS) req.raise_for_status() return req.json() @@ -94,21 +93,21 @@ def get_keystone_id(pdp_name): if pdp_name != pdp_value["name"]: continue if pdp_value['security_pipeline'] and pdp_value["keystone_project_id"]: - logger.debug("Found pdp with keystone_project_id={}".format(pdp_value["keystone_project_id"])) + LOGGER.debug( + "Found pdp with keystone_project_id={}".format(pdp_value["keystone_project_id"])) keystone_project_id = pdp_value["keystone_project_id"] if not keystone_project_id: - logger.error("Cannot find PDP with keystone project ID") + LOGGER.error("Cannot find PDP with keystone project ID") sys.exit(1) return keystone_project_id - def check_pdp(pdp_id=None, keystone_project_id=None, moon_url=None): - _URL = URL + _url = URL if moon_url: - _URL = moon_url - req = requests.get(_URL + "/pdp") + _url = moon_url + req = requests.get(_url + "/pdp") req.raise_for_status() result = req.json() check_pdp_in_result(result) @@ -124,8 +123,8 @@ def add_pdp(name="test_pdp", policy_id=None): if policy_id: pdp_template['security_pipeline'].append(policy_id) req = requests.post(URL + "/pdp", json=pdp_template, headers=HEADERS) - logger.debug(req.status_code) - logger.debug(req) + LOGGER.debug(req.status_code) + LOGGER.debug(req) req.raise_for_status() result = req.json() check_pdp_in_result(result) @@ -175,7 +174,7 @@ def delete_pdp(pdp_id): def create_pdp(scenario, policy_id=None, project_id=None): - logger.info("Creating PDP {}".format(scenario.pdp_name)) + LOGGER.info("Creating PDP {}".format(scenario.pdp_name)) projects = get_keystone_projects() # if not project_id: # for _project in projects['projects']: @@ -186,7 +185,9 @@ def create_pdp(scenario, policy_id=None, project_id=None): for pdp_id, pdp_value in pdps.items(): if scenario.pdp_name == pdp_value["name"]: update_pdp(pdp_id, policy_id=policy_id) - logger.debug("Found existing PDP named {} (will add policy {})".format(scenario.pdp_name, policy_id)) + LOGGER.debug( + "Found existing PDP named {} (will add policy {})".format(scenario.pdp_name, + policy_id)) return pdp_id _pdp_id = add_pdp(name=scenario.pdp_name, policy_id=policy_id) # map_to_keystone(pdp_id=_pdp_id, keystone_project_id=project_id) diff --git a/python_moonclient/python_moonclient/core/policies.py b/python_moonclient/python_moonclient/core/policies.py index 46d918aa..b9b05dd8 100644 --- a/python_moonclient/python_moonclient/core/policies.py +++ b/python_moonclient/python_moonclient/core/policies.py @@ -3,7 +3,7 @@ import requests from python_moonclient.core import models, config from python_moonclient.core.check_tools import * -logger = logging.getLogger("moonclient.core.policies") +LOGGER = logging.getLogger("moonclient.core.policies") URL = None HEADERS = None @@ -108,13 +108,13 @@ def delete_policy(policy_id): def add_subject(policy_id=None, name="test_subject"): subject_template['name'] = name if policy_id: - logger.debug(URL.format("/policies/{}/subjects".format(policy_id))) + LOGGER.debug(URL.format("/policies/{}/subjects".format(policy_id))) req = requests.post(URL.format("/policies/{}/subjects".format(policy_id)), json=subject_template, headers=HEADERS) else: - logger.debug(URL.format("/subjects")) + LOGGER.debug(URL.format("/subjects")) req = requests.post(URL.format("/subjects"), json=subject_template, headers=HEADERS) - logger.debug(req.text) + LOGGER.debug(req.text) req.raise_for_status() result = req.json() check_subject_in_result(result) @@ -186,11 +186,12 @@ def add_object(policy_id=None, name="test_object"): def update_object(object_id, policy_id): - req = requests.patch(URL.format("/policies/{}/objects/{}".format(policy_id, object_id)), json={}) + req = requests.patch(URL.format("/policies/{}/objects/{}".format(policy_id, object_id)), + json={}) req.raise_for_status() result = req.json() check_object_in_result(result) - check_object_name(object_template["name"] , object_id, result) + check_object_name(object_template["name"], object_id, result) check_object_policy(policy_id, result["objects"][object_id]) @@ -244,7 +245,8 @@ def add_action(policy_id=None, name="test_action"): def update_action(action_id, policy_id): - req = requests.patch(URL.format("/policies/{}/actions/{}".format(policy_id, action_id)), json={}) + req = requests.patch(URL.format("/policies/{}/actions/{}".format(policy_id, action_id)), + json={}) req.raise_for_status() result = req.json() check_action_in_result(result) @@ -310,8 +312,9 @@ def check_subject_data(policy_id, data_id, category_id): def delete_subject_data(policy_id, category_id, data_id): - req = requests.delete(URL.format("/policies/{}/subject_data/{}/{}".format(policy_id, category_id, data_id)), - headers=HEADERS) + req = requests.delete( + URL.format("/policies/{}/subject_data/{}/{}".format(policy_id, category_id, data_id)), + headers=HEADERS) req.raise_for_status() req = requests.get(URL.format("/policies/{}/subject_data/{}".format(policy_id, category_id))) req.raise_for_status() @@ -340,9 +343,11 @@ def check_object_data(policy_id, data_id, category_id): check_category_id_in_object_data_data(category_id, result) return result + def delete_object_data(policy_id, category_id, data_id): - req = requests.delete(URL.format("/policies/{}/object_data/{}/{}".format(policy_id, category_id, data_id)), - headers=HEADERS) + req = requests.delete( + URL.format("/policies/{}/object_data/{}/{}".format(policy_id, category_id, data_id)), + headers=HEADERS) req.raise_for_status() req = requests.get(URL.format("/policies/{}/object_data/{}".format(policy_id, category_id))) req.raise_for_status() @@ -372,9 +377,11 @@ def check_action_data(policy_id, data_id, category_id): check_category_id_in_action_data_data(category_id, result) return result + def delete_action_data(policy_id, category_id, data_id): - req = requests.delete(URL.format("/policies/{}/action_data/{}/{}".format(policy_id, category_id, data_id)), - headers=HEADERS) + req = requests.delete( + URL.format("/policies/{}/action_data/{}/{}".format(policy_id, category_id, data_id)), + headers=HEADERS) req.raise_for_status() req = requests.get(URL.format("/policies/{}/action_data/{}".format(policy_id, category_id))) req.raise_for_status() @@ -386,10 +393,10 @@ def delete_action_data(policy_id, category_id, data_id): def add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id): req = requests.post(URL.format("/policies/{}/subject_assignments".format(policy_id)), json={ - "id": subject_id, - "category_id": subject_cat_id, - "data_id": subject_data_id - }, headers=HEADERS) + "id": subject_id, + "category_id": subject_cat_id, + "data_id": subject_data_id + }, headers=HEADERS) req.raise_for_status() result = req.json() check_subject_assignment_in_result(result) @@ -425,10 +432,10 @@ def check_action_assignments(policy_id, action_id, action_cat_id, action_data_id def add_object_assignments(policy_id, object_id, object_cat_id, object_data_id): req = requests.post(URL.format("/policies/{}/object_assignments".format(policy_id)), json={ - "id": object_id, - "category_id": object_cat_id, - "data_id": object_data_id - }, headers=HEADERS) + "id": object_id, + "category_id": object_cat_id, + "data_id": object_data_id + }, headers=HEADERS) req.raise_for_status() result = req.json() check_object_assignment_in_result(result) @@ -437,10 +444,10 @@ def add_object_assignments(policy_id, object_id, object_cat_id, object_data_id): def add_action_assignments(policy_id, action_id, action_cat_id, action_data_id): req = requests.post(URL.format("/policies/{}/action_assignments".format(policy_id)), json={ - "id": action_id, - "category_id": action_cat_id, - "data_id": action_data_id - }, headers=HEADERS) + "id": action_id, + "category_id": action_cat_id, + "data_id": action_data_id + }, headers=HEADERS) req.raise_for_status() result = req.json() check_action_assignment_in_result(result) @@ -491,7 +498,8 @@ def delete_action_assignment(policy_id, action_id, action_cat_id, action_data_id check_not_action_assignements(action_id, action_cat_id, action_data_id, result) -def add_rule(policy_id, meta_rule_id, rule, instructions={"chain": [{"security_pipeline": "rbac"}]}): +def add_rule(policy_id, meta_rule_id, rule, + instructions={"chain": [{"security_pipeline": "rbac"}]}): req = requests.post(URL.format("/policies/{}/rules".format(policy_id)), json={ "meta_rule_id": meta_rule_id, @@ -539,8 +547,9 @@ def check_meta_rule(): print(result) return result + def create_policy(scenario, model_id, meta_rule_list): - logger.info("Creating policy {}".format(scenario.policy_name)) + LOGGER.info("Creating policy {}".format(scenario.policy_name)) _policies = check_policy() for _policy_id, _policy_value in _policies["policies"].items(): if _policy_value['name'] == scenario.policy_name: @@ -552,24 +561,24 @@ def create_policy(scenario, model_id, meta_rule_list): update_policy(policy_id, model_id) for meta_rule_id in meta_rule_list: - logger.debug("add_meta_rule_to_model {} {}".format(model_id, meta_rule_id)) + LOGGER.debug("add_meta_rule_to_model {} {}".format(model_id, meta_rule_id)) models.add_meta_rule_to_model(model_id, meta_rule_id) - logger.info("Add subject data") + LOGGER.info("Add subject data") for subject_cat_name in scenario.subject_data: for subject_data_name in scenario.subject_data[subject_cat_name]: data_id = scenario.subject_data[subject_cat_name][subject_data_name] = add_subject_data( policy_id=policy_id, category_id=scenario.subject_categories[subject_cat_name], name=subject_data_name) scenario.subject_data[subject_cat_name][subject_data_name] = data_id - logger.info("Add object data") + LOGGER.info("Add object data") for object_cat_name in scenario.object_data: for object_data_name in scenario.object_data[object_cat_name]: data_id = scenario.object_data[object_cat_name][object_data_name] = add_object_data( policy_id=policy_id, category_id=scenario.object_categories[object_cat_name], name=object_data_name) scenario.object_data[object_cat_name][object_data_name] = data_id - logger.info("Add action data") + LOGGER.info("Add action data") for action_cat_name in scenario.action_data: for action_data_name in scenario.action_data[action_cat_name]: data_id = scenario.action_data[action_cat_name][action_data_name] = add_action_data( @@ -577,17 +586,17 @@ def create_policy(scenario, model_id, meta_rule_list): category_id=scenario.action_categories[action_cat_name], name=action_data_name) scenario.action_data[action_cat_name][action_data_name] = data_id - logger.info("Add subjects") + LOGGER.info("Add subjects") for name in scenario.subjects: scenario.subjects[name] = add_subject(policy_id, name=name) - logger.info("Add objects") + LOGGER.info("Add objects") for name in scenario.objects: scenario.objects[name] = add_object(policy_id, name=name) - logger.info("Add actions") + LOGGER.info("Add actions") for name in scenario.actions: scenario.actions[name] = add_action(policy_id, name=name) - logger.info("Add subject assignments") + LOGGER.info("Add subject assignments") for subject_name in scenario.subject_assignments: if type(scenario.subject_assignments[subject_name]) in (list, tuple): for items in scenario.subject_assignments[subject_name]: @@ -595,16 +604,19 @@ def create_policy(scenario, model_id, meta_rule_list): subject_id = scenario.subjects[subject_name] subject_cat_id = scenario.subject_categories[subject_category_name] for data in scenario.subject_assignments[subject_name]: - subject_data_id = scenario.subject_data[subject_category_name][data[subject_category_name]] - add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id) + subject_data_id = scenario.subject_data[subject_category_name][ + data[subject_category_name]] + add_subject_assignments(policy_id, subject_id, subject_cat_id, + subject_data_id) else: for subject_category_name in scenario.subject_assignments[subject_name]: subject_id = scenario.subjects[subject_name] subject_cat_id = scenario.subject_categories[subject_category_name] - subject_data_id = scenario.subject_data[subject_category_name][scenario.subject_assignments[subject_name][subject_category_name]] + subject_data_id = scenario.subject_data[subject_category_name][ + scenario.subject_assignments[subject_name][subject_category_name]] add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id) - logger.info("Add object assignments") + LOGGER.info("Add object assignments") for object_name in scenario.object_assignments: if type(scenario.object_assignments[object_name]) in (list, tuple): for items in scenario.object_assignments[object_name]: @@ -612,16 +624,18 @@ def create_policy(scenario, model_id, meta_rule_list): object_id = scenario.objects[object_name] object_cat_id = scenario.object_categories[object_category_name] for data in scenario.object_assignments[object_name]: - object_data_id = scenario.object_data[object_category_name][data[object_category_name]] + object_data_id = scenario.object_data[object_category_name][ + data[object_category_name]] add_object_assignments(policy_id, object_id, object_cat_id, object_data_id) else: for object_category_name in scenario.object_assignments[object_name]: object_id = scenario.objects[object_name] object_cat_id = scenario.object_categories[object_category_name] - object_data_id = scenario.object_data[object_category_name][scenario.object_assignments[object_name][object_category_name]] + object_data_id = scenario.object_data[object_category_name][ + scenario.object_assignments[object_name][object_category_name]] add_object_assignments(policy_id, object_id, object_cat_id, object_data_id) - logger.info("Add action assignments") + LOGGER.info("Add action assignments") for action_name in scenario.action_assignments: if type(scenario.action_assignments[action_name]) in (list, tuple): for items in scenario.action_assignments[action_name]: @@ -629,16 +643,18 @@ def create_policy(scenario, model_id, meta_rule_list): action_id = scenario.actions[action_name] action_cat_id = scenario.action_categories[action_category_name] for data in scenario.action_assignments[action_name]: - action_data_id = scenario.action_data[action_category_name][data[action_category_name]] + action_data_id = scenario.action_data[action_category_name][ + data[action_category_name]] add_action_assignments(policy_id, action_id, action_cat_id, action_data_id) else: for action_category_name in scenario.action_assignments[action_name]: action_id = scenario.actions[action_name] action_cat_id = scenario.action_categories[action_category_name] - action_data_id = scenario.action_data[action_category_name][scenario.action_assignments[action_name][action_category_name]] + action_data_id = scenario.action_data[action_category_name][ + scenario.action_assignments[action_name][action_category_name]] add_action_assignments(policy_id, action_id, action_cat_id, action_data_id) - logger.info("Add rules") + LOGGER.info("Add rules") for meta_rule_name in scenario.rules: meta_rule_value = scenario.meta_rule[meta_rule_name] for rule in scenario.rules[meta_rule_name]: @@ -655,4 +671,3 @@ def create_policy(scenario, model_id, meta_rule_list): instructions = rule["instructions"] add_rule(policy_id, meta_rule_value["id"], data_list, instructions) return policy_id - diff --git a/python_moonclient/python_moonclient/core/slaves.py b/python_moonclient/python_moonclient/core/slaves.py index 112b56f3..77b127c1 100644 --- a/python_moonclient/python_moonclient/core/slaves.py +++ b/python_moonclient/python_moonclient/core/slaves.py @@ -3,8 +3,7 @@ import requests from python_moonclient.core import config from python_moonclient.core.check_tools import * -logger = logging.getLogger("moonclient.core.slaves") - +LOGGER = logging.getLogger("moonclient.core.slaves") URL = None HEADERS = None @@ -20,8 +19,6 @@ def init(consul_host, consul_port): HEADERS = {"content-type": "application/json"} - - def get_slaves(): req = requests.get(URL.format("/slaves")) req.raise_for_status() @@ -36,10 +33,10 @@ def set_slave(name): req = requests.patch(URL.format("/slaves/{}".format(name)), headers=HEADERS, json={ - "op": "replace", - "variable": "configured", - "value": True - }) + "op": "replace", + "variable": "configured", + "value": True + }) req.raise_for_status() result = req.json() check_slaves_in_result(result) @@ -52,10 +49,10 @@ def delete_slave(name): req = requests.patch(URL.format("/slaves/{}".format(name)), headers=HEADERS, json={ - "op": "replace", - "variable": "configured", - "value": False - }) + "op": "replace", + "variable": "configured", + "value": False + }) req.raise_for_status() result = req.json() check_slaves_in_result(result) diff --git a/python_moonclient/python_moonclient/moon.py b/python_moonclient/python_moonclient/moon.py index f8cf027d..0bd80921 100644 --- a/python_moonclient/python_moonclient/moon.py +++ b/python_moonclient/python_moonclient/moon.py @@ -6,14 +6,14 @@ from cliff.commandmanager import CommandManager class Moon(App): - + def __init__(self): super(Moon, self).__init__( - description='Moon client', - version=python_moonclient.__version__, - command_manager=CommandManager('moon'), - deferred_help=True, - ) + description='Moon client', + version=python_moonclient.__version__, + command_manager=CommandManager('moon'), + deferred_help=True, + ) def main(argv=sys.argv[1:]): @@ -22,20 +22,16 @@ def main(argv=sys.argv[1:]): if __name__ == '__main__': - #import python_moonclient.python_moonclient.core.import_json - #import python_moonclient.python_moonclient.core.models - #import python_moonclient.core.policies.init as init_policy - #import python_moonclient.core.pdp.init as init_pdp - #consul_host = "consul" - #consul_port = "8005" - - #init_model(consul_host, consul_port) - #init_policy.init(consul_host, consul_port) - #init_pdp.init(consul_host, consul_port) - #import_json('/home/fcellier/moon/tests/functional/scenario_available/rbac.json') - + # import python_moonclient.python_moonclient.core.import_json + # import python_moonclient.python_moonclient.core.models + # import python_moonclient.core.policies.init as init_policy + # import python_moonclient.core.pdp.init as init_pdp + # consul_host = "consul" + # consul_port = "8005" + + # init_model(consul_host, consul_port) + # init_policy.init(consul_host, consul_port) + # init_pdp.init(consul_host, consul_port) + # import_json('/home/fcellier/moon/tests/functional/scenario_available/rbac.json') sys.exit(Moon(sys.argv[1:])) - - - diff --git a/python_moondb/.gitignore b/python_moondb/.gitignore new file mode 100644 index 00000000..9c29724f --- /dev/null +++ b/python_moondb/.gitignore @@ -0,0 +1,106 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +/tests/unit_python/database.db diff --git a/python_moondb/Changelog b/python_moondb/Changelog index f4feef62..9236c260 100644 --- a/python_moondb/Changelog +++ b/python_moondb/Changelog @@ -106,3 +106,23 @@ CHANGES 1.2.16 ------ - Fix the "key length error" in meta_rule table + +1.2.17 +------ +- adding extra validation for addition and deletion dependencies + +1.2.18 +------ +- adding changelog + +1.2.19 +------ +- adding extra validation for update requests + +1.2.20 +------ +- adding extra validation of rule content +- update validation for category with meta-rule dependencies +- update validation on updating meta-rule +- applying PyLint +- fixing Jira issues related to update policy \ No newline at end of file diff --git a/python_moondb/python_moondb/__init__.py b/python_moondb/python_moondb/__init__.py index e2e16287..37c9a725 100644 --- a/python_moondb/python_moondb/__init__.py +++ b/python_moondb/python_moondb/__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__ = "1.2.16" +__version__ = "1.2.20" diff --git a/python_moondb/python_moondb/api/keystone.py b/python_moondb/python_moondb/api/keystone.py index 582ae710..57521c36 100644 --- a/python_moondb/python_moondb/api/keystone.py +++ b/python_moondb/python_moondb/api/keystone.py @@ -103,4 +103,3 @@ class KeystoneManager(Managers): _exception=exceptions.KeystoneUserError) except exceptions.KeystoneUserConflict: return True - diff --git a/python_moondb/python_moondb/api/managers.py b/python_moondb/python_moondb/api/managers.py index f500d02e..414725f6 100644 --- a/python_moondb/python_moondb/api/managers.py +++ b/python_moondb/python_moondb/api/managers.py @@ -4,6 +4,7 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. import logging + logger = logging.getLogger("moon.db.api.managers") diff --git a/python_moondb/python_moondb/api/model.py b/python_moondb/python_moondb/api/model.py index c1603b83..4f6c34cb 100644 --- a/python_moondb/python_moondb/api/model.py +++ b/python_moondb/python_moondb/api/model.py @@ -8,6 +8,7 @@ import logging from python_moonutilities import exceptions from python_moonutilities.security_functions import filter_input, enforce from python_moondb.api.managers import Managers +import copy logger = logging.getLogger("moon.db.api.model") @@ -22,10 +23,31 @@ class ModelManager(Managers): def update_model(self, user_id, model_id, value): if model_id not in self.driver.get_models(model_id=model_id): raise exceptions.ModelUnknown + + if not value['name'].strip(): + raise exceptions.ModelContentError('Model name invalid') + + if 'meta_rules' not in value: + raise exceptions.MetaRuleUnknown + + if not value['name']: + raise exceptions.ModelContentError + + model = self.get_models(user_id=user_id, model_id=model_id) + model = model[next(iter(model))] + if ((model['meta_rules'] and value['meta_rules'] and model['meta_rules'] != value[ + 'meta_rules']) \ + or (model['meta_rules'] and not value['meta_rules'])): + policies = Managers.PolicyManager.get_policies(user_id=user_id) + for policy_id in policies: + if policies[policy_id]["model_id"] == model_id: + raise exceptions.DeleteModelWithPolicy + if value and 'meta_rules' in value: for meta_rule_id in value['meta_rules']: if not self.driver.get_meta_rules(meta_rule_id=meta_rule_id): raise exceptions.MetaRuleUnknown + return self.driver.update_model(model_id=model_id, value=value) @enforce(("read", "write"), "models") @@ -41,14 +63,44 @@ class ModelManager(Managers): @enforce(("read", "write"), "models") def add_model(self, user_id, model_id=None, value=None): - if model_id in self.driver.get_models(model_id=model_id): + + if not value['name']: + raise exceptions.ModelContentError + + if not value['name'].strip(): + raise exceptions.ModelContentError('Model name invalid') + + models = self.driver.get_models() + if model_id in models: raise exceptions.ModelExisting + + for model in models: + if models[model]['name'] == value['name']: + raise exceptions.ModelExisting("Model Name Existed") + same_meta_rule_counter = 0 + for meta_rule_id in models[model]['meta_rules']: + if meta_rule_id in value['meta_rules']: + same_meta_rule_counter += 1 + if same_meta_rule_counter == len(value['meta_rules']) and \ + len(models[model]['meta_rules']) == len(value['meta_rules']): + raise exceptions.ModelExisting("Meta Rules List Existed in another Model") + if not model_id: model_id = uuid4().hex if value and 'meta_rules' in value: for meta_rule_id in value['meta_rules']: - if not self.driver.get_meta_rules(meta_rule_id=meta_rule_id): + if not meta_rule_id: raise exceptions.MetaRuleUnknown + meta_rule = self.driver.get_meta_rules(meta_rule_id=meta_rule_id) + if not meta_rule: + raise exceptions.MetaRuleUnknown + + meta_rule_content = meta_rule[next(iter(meta_rule))] + if (not meta_rule_content['subject_categories']) or ( + not meta_rule_content['object_categories']) or ( + not meta_rule_content['action_categories']): + raise exceptions.MetaRuleContentError + return self.driver.add_model(model_id=model_id, value=value) @enforce("read", "models") @@ -56,32 +108,64 @@ class ModelManager(Managers): return self.driver.get_models(model_id=model_id) @enforce(("read", "write"), "meta_rules") - def set_meta_rule(self, user_id, meta_rule_id, value): - if meta_rule_id not in self.driver.get_meta_rules(meta_rule_id=meta_rule_id): + def update_meta_rule(self, user_id, meta_rule_id, value): + meta_rules=self.driver.get_meta_rules() + if not meta_rule_id or meta_rule_id not in meta_rules: raise exceptions.MetaRuleUnknown + self.__check_meta_rule_dependencies(user_id=user_id, meta_rule_id=meta_rule_id) if value: if 'subject_categories' in value: for subject_category_id in value['subject_categories']: - if not self.driver.get_subject_categories(category_id=subject_category_id): + if not subject_category_id or not self.driver.get_subject_categories( + category_id=subject_category_id): raise exceptions.SubjectCategoryUnknown if 'object_categories' in value: for object_category_id in value['object_categories']: - if not self.driver.get_object_categories(category_id=object_category_id): + if not object_category_id or not self.driver.get_object_categories( + category_id=object_category_id): raise exceptions.ObjectCategoryUnknown if 'action_categories' in value: for action_category_id in value['action_categories']: - if not self.driver.get_action_categories(category_id=action_category_id): + if not action_category_id or not self.driver.get_action_categories( + category_id=action_category_id): raise exceptions.ActionCategoryUnknown + + for meta_rule_obj_id in meta_rules: + counter_matched_list = 0 + counter_matched_list += self.check_combination(meta_rules[meta_rule_obj_id]['subject_categories'], + value['subject_categories']) + counter_matched_list += self.check_combination(meta_rules[meta_rule_obj_id]['object_categories'], + value['object_categories']) + counter_matched_list += self.check_combination(meta_rules[meta_rule_obj_id]['action_categories'], + value['action_categories']) + if counter_matched_list == 3 and meta_rule_obj_id!=meta_rule_id: + raise exceptions.MetaRuleExisting("Same categories combination existed") + return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value) + def __check_meta_rule_dependencies(self, user_id, meta_rule_id): + policies = Managers.PolicyManager.get_policies(user_id=user_id) + for policy_id in policies: + rules = Managers.PolicyManager.get_rules(user_id=user_id, policy_id=policy_id, + meta_rule_id=meta_rule_id) + if len(rules['rules']): + raise exceptions.MetaRuleUpdateError + @enforce("read", "meta_rules") def get_meta_rules(self, user_id, meta_rule_id=None): return self.driver.get_meta_rules(meta_rule_id=meta_rule_id) @enforce(("read", "write"), "meta_rules") def add_meta_rule(self, user_id, meta_rule_id=None, value=None): - if meta_rule_id in self.driver.get_meta_rules(meta_rule_id=meta_rule_id): + + if not value['name']: + raise exceptions.MetaRuleContentError + + meta_rules = self.driver.get_meta_rules() + + if meta_rule_id in meta_rules: raise exceptions.MetaRuleExisting + if value: if 'subject_categories' in value: for subject_category_id in value['subject_categories']: @@ -95,8 +179,33 @@ class ModelManager(Managers): for action_category_id in value['action_categories']: if not self.driver.get_action_categories(category_id=action_category_id): raise exceptions.ActionCategoryUnknown + + for meta_rule_obj_id in meta_rules: + counter_matched_list = 0 + counter_matched_list += self.check_combination(meta_rules[meta_rule_obj_id]['subject_categories'], + value['subject_categories']) + counter_matched_list += self.check_combination(meta_rules[meta_rule_obj_id]['object_categories'], + value['object_categories']) + counter_matched_list += self.check_combination(meta_rules[meta_rule_obj_id]['action_categories'], + value['action_categories']) + if counter_matched_list == 3: + raise exceptions.MetaRuleExisting("Same categories combination existed") + return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value) + @enforce(("read", "write"), "meta_rules") + def check_combination(self, list_one, list_two): + counter_removed_items = 0 + temp_list_two = copy.deepcopy(list_two) + for item in list_one: + if item in temp_list_two: + temp_list_two.remove(item) + counter_removed_items += 1 + + if counter_removed_items == len(list_two) and len(list_two) == len(list_one) and len(list_two): + return 1 + return 0 + @enforce(("read", "write"), "meta_rules") def delete_meta_rule(self, user_id, meta_rule_id=None): if meta_rule_id not in self.driver.get_meta_rules(meta_rule_id=meta_rule_id): @@ -104,8 +213,9 @@ class ModelManager(Managers): # TODO (asteroide): check and/or delete data and assignments and rules linked to that meta_rule models = self.get_models(user_id=user_id) for model_id in models: - if models[model_id]['meta_rules'] == meta_rule_id: - raise exceptions.DeleteMetaRuleWithModel + for id in models[model_id]['meta_rules']: + if id == meta_rule_id: + raise exceptions.DeleteMetaRuleWithModel return self.driver.delete_meta_rule(meta_rule_id=meta_rule_id) @enforce("read", "meta_data") @@ -114,9 +224,16 @@ class ModelManager(Managers): @enforce(("read", "write"), "meta_data") def add_subject_category(self, user_id, category_id=None, value=None): - if category_id in self.driver.get_subject_categories(category_id=category_id): + subject_categories = self.driver.get_subject_categories(category_id=category_id) + + if not value['name']: + raise exceptions.CategoryNameInvalid + + if category_id in subject_categories: raise exceptions.SubjectCategoryExisting - return self.driver.add_subject_category(name=value["name"], description=value["description"], uuid=category_id) + + return self.driver.add_subject_category(name=value["name"], + description=value["description"], uuid=category_id) @enforce(("read", "write"), "meta_data") def delete_subject_category(self, user_id, category_id): @@ -127,13 +244,20 @@ class ModelManager(Managers): meta_rules = self.get_meta_rules(user_id=user_id) for meta_rule_id in meta_rules: for subject_category_id in meta_rules[meta_rule_id]['subject_categories']: - logger.info("delete_subject_category {} {}".format(subject_category_id, meta_rule_id)) + logger.info( + "delete_subject_category {} {}".format(subject_category_id, meta_rule_id)) logger.info("delete_subject_category {}".format(meta_rules[meta_rule_id])) if subject_category_id == category_id: - self.delete_meta_rule(user_id, meta_rule_id) - # raise exceptions.DeleteCategoryWithMetaRule + # has_rules = self.driver.is_meta_rule_has_rules(meta_rule_id) + # if has_rules: + raise exceptions.DeleteSubjectCategoryWithMetaRule + + if self.driver.is_subject_category_has_assignment(category_id): + raise exceptions.DeleteCategoryWithAssignment + if self.driver.is_subject_data_exist(category_id=category_id): raise exceptions.DeleteCategoryWithData + return self.driver.delete_subject_category(category_id=category_id) @enforce("read", "meta_data") @@ -142,9 +266,15 @@ class ModelManager(Managers): @enforce(("read", "write"), "meta_data") def add_object_category(self, user_id, category_id=None, value=None): - if category_id in self.driver.get_object_categories(category_id=category_id): + if not value['name']: + raise exceptions.CategoryNameInvalid + + object_categories = self.driver.get_object_categories(category_id=category_id) + if category_id in object_categories: raise exceptions.ObjectCategoryExisting - return self.driver.add_object_category(name=value["name"], description=value["description"], uuid=category_id) + + return self.driver.add_object_category(name=value["name"], description=value["description"], + uuid=category_id) @enforce(("read", "write"), "meta_data") def delete_object_category(self, user_id, category_id): @@ -156,9 +286,16 @@ class ModelManager(Managers): for meta_rule_id in meta_rules: for object_category_id in meta_rules[meta_rule_id]['object_categories']: if object_category_id == category_id: - self.delete_meta_rule(user_id, meta_rule_id) + # has_rules = self.driver.is_meta_rule_has_rules(meta_rule_id) + # if has_rules: + raise exceptions.DeleteObjectCategoryWithMetaRule + + if self.driver.is_object_category_has_assignment(category_id): + raise exceptions.DeleteCategoryWithAssignment + if self.driver.is_object_data_exist(category_id=category_id): raise exceptions.DeleteCategoryWithData + return self.driver.delete_object_category(category_id=category_id) @enforce("read", "meta_data") @@ -167,9 +304,16 @@ class ModelManager(Managers): @enforce(("read", "write"), "meta_data") def add_action_category(self, user_id, category_id=None, value=None): - if category_id in self.driver.get_action_categories(category_id=category_id): + + if not value['name']: + raise exceptions.CategoryNameInvalid + + action_categories = self.driver.get_action_categories(category_id=category_id) + if category_id in action_categories: raise exceptions.ActionCategoryExisting - return self.driver.add_action_category(name=value["name"], description=value["description"], uuid=category_id) + + return self.driver.add_action_category(name=value["name"], description=value["description"], + uuid=category_id) @enforce(("read", "write"), "meta_data") def delete_action_category(self, user_id, category_id): @@ -181,7 +325,14 @@ class ModelManager(Managers): for meta_rule_id in meta_rules: for action_category_id in meta_rules[meta_rule_id]['action_categories']: if action_category_id == category_id: - self.delete_meta_rule(user_id, meta_rule_id) + # has_rules = self.driver.is_meta_rule_has_rules(meta_rule_id) + # if has_rules: + raise exceptions.DeleteActionCategoryWithMetaRule + + if self.driver.is_action_category_has_assignment(category_id): + raise exceptions.DeleteCategoryWithAssignment + if self.driver.is_action_data_exist(category_id=category_id): raise exceptions.DeleteCategoryWithData + return self.driver.delete_action_category(category_id=category_id) diff --git a/python_moondb/python_moondb/api/policy.py b/python_moondb/python_moondb/api/policy.py index 05c2b7d5..03a93ff5 100644 --- a/python_moondb/python_moondb/api/policy.py +++ b/python_moondb/python_moondb/api/policy.py @@ -8,6 +8,7 @@ import logging from python_moonutilities.security_functions import enforce from python_moondb.api.managers import Managers from python_moonutilities import exceptions + # from python_moondb.core import PDPManager logger = logging.getLogger("moon.db.api.policy") @@ -38,11 +39,49 @@ class PolicyManager(Managers): @enforce(("read", "write"), "policies") def update_policy(self, user_id, policy_id, value): - if policy_id not in self.driver.get_policies(policy_id=policy_id): + + if not value or not value['name']: + raise exceptions.PolicyContentError + + policyList = self.driver.get_policies(policy_id=policy_id) + if not policy_id or policy_id not in policyList: raise exceptions.PolicyUnknown - if value and 'model_id' in value and value['model_id'] != "": + + policies = self.driver.get_policies(policy_name=value['name']) + if len(policies) and not (policy_id in policies): + raise exceptions.PolicyExisting("Policy name Existed") + + if 'model_id' in value and value['model_id']: if not Managers.ModelManager.get_models(user_id, model_id=value['model_id']): raise exceptions.ModelUnknown + + policy_obj = policyList[policy_id] + if (policy_obj["model_id"] and value["model_id"] != policy_obj["model_id"]): + + subjects = self.driver.get_subjects(policy_id=policy_id) + if subjects: + raise exceptions.PolicyUpdateError("Policy is used in subject") + objects = self.driver.get_objects(policy_id=policy_id) + if objects: + raise exceptions.PolicyUpdateError("Policy is used in object") + actions = self.driver.get_actions(policy_id=policy_id) + if actions: + raise exceptions.PolicyUpdateError("Policy is used in action") + + rules = self.driver.get_rules(policy_id=policy_id)["rules"] + if rules: + raise exceptions.PolicyUpdateError("Policy is used in rule") + + subject_data = self.get_subject_data(user_id, policy_id=policy_id) + if subject_data and subject_data[0]["data"]: + raise exceptions.PolicyUpdateError("Policy is used in subject_data") + object_data = self.get_object_data(user_id, policy_id=policy_id) + if object_data and object_data[0]["data"]: + raise exceptions.PolicyUpdateError("Policy is used in object_data") + action_data = self.get_action_data(user_id, policy_id=policy_id) + if action_data and action_data[0]["data"]: + raise exceptions.PolicyUpdateError("Policy is used in action_data") + return self.driver.update_policy(policy_id=policy_id, value=value) @enforce(("read", "write"), "policies") @@ -55,15 +94,46 @@ class PolicyManager(Managers): for policy_id in pdps[pdp]['security_pipeline']: if policy_id == policy_id: raise exceptions.DeletePolicyWithPdp + subjects = self.driver.get_subjects(policy_id=policy_id) + if subjects: + raise exceptions.DeletePolicyWithPerimeter + objects = self.driver.get_objects(policy_id=policy_id) + if objects: + raise exceptions.DeletePolicyWithPerimeter + actions = self.driver.get_actions(policy_id=policy_id) + if actions: + raise exceptions.DeletePolicyWithPerimeter + + rules = self.driver.get_rules(policy_id=policy_id)["rules"] + if rules: + raise exceptions.DeletePolicyWithRules + + subject_data = self.get_subject_data(user_id, policy_id=policy_id) + if subject_data and subject_data[0]["data"]: + raise exceptions.DeletePolicyWithData + object_data = self.get_object_data(user_id, policy_id=policy_id) + if object_data and object_data[0]["data"]: + raise exceptions.DeletePolicyWithData + action_data = self.get_action_data(user_id, policy_id=policy_id) + if action_data and action_data[0]["data"]: + raise exceptions.DeletePolicyWithData + return self.driver.delete_policy(policy_id=policy_id) @enforce(("read", "write"), "policies") def add_policy(self, user_id, policy_id=None, value=None): + + if not value or not value['name']: + raise exceptions.PolicyContentError if policy_id in self.driver.get_policies(policy_id=policy_id): raise exceptions.PolicyExisting + + if len(self.driver.get_policies(policy_name=value['name'])): + raise exceptions.PolicyExisting("Policy name Existed") + if not policy_id: policy_id = uuid4().hex - if value and 'model_id' in value and value['model_id'] != "": + if 'model_id' in value and value['model_id'] != "": if not Managers.ModelManager.get_models(user_id, model_id=value['model_id']): raise exceptions.ModelUnknown return self.driver.add_policy(policy_id=policy_id, value=value) @@ -74,19 +144,31 @@ class PolicyManager(Managers): @enforce("read", "perimeter") def get_subjects(self, user_id, policy_id, perimeter_id=None): - if not policy_id: - pass - elif not (policy_id and self.get_policies(user_id=user_id, policy_id=policy_id)): + # if not policy_id: + # raise exceptions.PolicyUnknown + if policy_id and (not self.get_policies(user_id=user_id, policy_id=policy_id)): raise exceptions.PolicyUnknown return self.driver.get_subjects(policy_id=policy_id, perimeter_id=perimeter_id) @enforce(("read", "write"), "perimeter") def add_subject(self, user_id, policy_id, perimeter_id=None, value=None): + if not value or "name" not in value or not value["name"].strip(): - raise exceptions.PerimeterNameInvalid - if value["name"] in map(lambda x: x['name'], - self.get_subjects(user_id, policy_id, perimeter_id).values()): - raise exceptions.SubjectExisting + raise exceptions.PerimeterContentError('invalid name') + + if not policy_id or (not self.get_policies(user_id=user_id, policy_id=policy_id)): + raise exceptions.PolicyUnknown + + if perimeter_id: + subjects = self.driver.get_subjects(policy_id=None, perimeter_id=perimeter_id) + if subjects and subjects[perimeter_id]['name'] != value['name']: + raise exceptions.PerimeterContentError + + if not perimeter_id: + subject_per = self.driver.get_subject_by_name(value['name']) + if len(subject_per): + perimeter_id = next(iter(subject_per)) + k_user = Managers.KeystoneManager.get_user_by_name(value.get('name')) if not k_user['users']: k_user = Managers.KeystoneManager.create_user(value) @@ -102,59 +184,192 @@ class PolicyManager(Managers): k_user = Managers.KeystoneManager.get_user_by_name( value.get('name')) perimeter_id = uuid4().hex + value.update(k_user['users'][0]) - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown + return self.driver.set_subject(policy_id=policy_id, perimeter_id=perimeter_id, value=value) + @enforce(("read", "write"), "perimeter") + def update_subject(self, user_id, perimeter_id, value): + logger.debug("update_subject perimeter_id = {}".format(perimeter_id)) + + if not perimeter_id: + raise exceptions.SubjectUnknown + + subjects = self.driver.get_subjects(policy_id=None, perimeter_id=perimeter_id) + if not subjects or not (perimeter_id in subjects): + raise exceptions.PerimeterContentError + + if 'policy_list' in value or ('name' in value and not value['name']): + raise exceptions.PerimeterContentError + + return self.driver.update_subject(perimeter_id=perimeter_id, value=value) + @enforce(("read", "write"), "perimeter") def delete_subject(self, user_id, policy_id, perimeter_id): - if policy_id and not self.get_policies(user_id=user_id, policy_id=policy_id): + + if not perimeter_id: + raise exceptions.SubjectUnknown + + if not policy_id: + raise exceptions.PolicyUnknown + + if not self.get_subjects(user_id=user_id, policy_id=policy_id, perimeter_id=perimeter_id): + raise exceptions.SubjectUnknown + + if not self.get_policies(user_id=user_id, policy_id=policy_id): raise exceptions.PolicyUnknown + + subj_assig = self.driver.get_subject_assignments(policy_id=policy_id, + subject_id=perimeter_id) + if subj_assig: + raise exceptions.DeletePerimeterWithAssignment + return self.driver.delete_subject(policy_id=policy_id, perimeter_id=perimeter_id) @enforce("read", "perimeter") def get_objects(self, user_id, policy_id, perimeter_id=None): - if not policy_id: - pass - elif not (policy_id and self.get_policies(user_id=user_id, policy_id=policy_id)): + # if not policy_id: + # pass + if policy_id and (not self.get_policies(user_id=user_id, policy_id=policy_id)): raise exceptions.PolicyUnknown return self.driver.get_objects(policy_id=policy_id, perimeter_id=perimeter_id) @enforce(("read", "write"), "perimeter") def add_object(self, user_id, policy_id, perimeter_id=None, value=None): - if not self.get_policies(user_id=user_id, policy_id=policy_id): + if not value or "name" not in value or not value["name"].strip(): + raise exceptions.PerimeterContentError('invalid name') + + if not policy_id or (not self.get_policies(user_id=user_id, policy_id=policy_id)): raise exceptions.PolicyUnknown + + if perimeter_id: + object_perimeter = self.driver.get_objects(policy_id=None, perimeter_id=perimeter_id) + if not object_perimeter: + raise exceptions.PerimeterContentError + + if not perimeter_id: + object_perimeter = self.driver.get_object_by_name(value['name']) + if len(object_perimeter): + perimeter_id = next(iter(object_perimeter)) + + if perimeter_id and object_perimeter[perimeter_id]['name'] != value['name']: + raise exceptions.PerimeterContentError + if not perimeter_id: perimeter_id = uuid4().hex return self.driver.set_object(policy_id=policy_id, perimeter_id=perimeter_id, value=value) + @enforce(("read", "write"), "perimeter") + def update_object(self, user_id, perimeter_id, value): + logger.debug("update_object perimeter_id = {}".format(perimeter_id)) + + if not perimeter_id: + raise exceptions.ObjectUnknown + + objects = self.driver.get_objects(policy_id=None, perimeter_id=perimeter_id) + if not objects or not (perimeter_id in objects): + raise exceptions.PerimeterContentError + + if 'policy_list' in value or ('name' in value and not value['name']): + raise exceptions.PerimeterContentError + + return self.driver.update_object(perimeter_id=perimeter_id, value=value) + @enforce(("read", "write"), "perimeter") def delete_object(self, user_id, policy_id, perimeter_id): - if policy_id and not self.get_policies(user_id=user_id, policy_id=policy_id): + + if not perimeter_id: + raise exceptions.ObjectUnknown + + if not policy_id: raise exceptions.PolicyUnknown + + if not self.get_objects(user_id=user_id, policy_id=policy_id, perimeter_id=perimeter_id): + raise exceptions.ObjectUnknown + + if not self.get_policies(user_id=user_id, policy_id=policy_id): + raise exceptions.PolicyUnknown + + obj_assig = self.driver.get_object_assignments(policy_id=policy_id, object_id=perimeter_id) + if obj_assig: + raise exceptions.DeletePerimeterWithAssignment + return self.driver.delete_object(policy_id=policy_id, perimeter_id=perimeter_id) @enforce("read", "perimeter") def get_actions(self, user_id, policy_id, perimeter_id=None): - if not policy_id: - pass - elif not (policy_id and self.get_policies(user_id=user_id, policy_id=policy_id)): + # if not policy_id: + # pass + if policy_id and (not self.get_policies(user_id=user_id, policy_id=policy_id)): raise exceptions.PolicyUnknown return self.driver.get_actions(policy_id=policy_id, perimeter_id=perimeter_id) @enforce(("read", "write"), "perimeter") def add_action(self, user_id, policy_id, perimeter_id=None, value=None): logger.debug("add_action {}".format(policy_id)) - if not self.get_policies(user_id=user_id, policy_id=policy_id): + + if not value or "name" not in value or not value["name"].strip(): + raise exceptions.PerimeterContentError('invalid name') + + if not policy_id or (not self.get_policies(user_id=user_id, policy_id=policy_id)): raise exceptions.PolicyUnknown + + if perimeter_id: + action_perimeter = self.driver.get_actions(policy_id=None, perimeter_id=perimeter_id) + if not action_perimeter: + raise exceptions.PerimeterContentError + + if not perimeter_id: + action_perimeter = self.driver.get_action_by_name(value['name']) + if len(action_perimeter): + perimeter_id = next(iter(action_perimeter)) + + if perimeter_id and action_perimeter[perimeter_id]['name'] != value['name']: + raise exceptions.PerimeterContentError + + if not perimeter_id: + perimeter_id = uuid4().hex + return self.driver.set_action(policy_id=policy_id, perimeter_id=perimeter_id, value=value) + @enforce(("read", "write"), "perimeter") + def update_action(self, user_id, perimeter_id, value): + logger.debug("update_action perimeter_id = {}".format(perimeter_id)) + + if not perimeter_id: + raise exceptions.ActionUnknown + + actions = self.driver.get_actions(policy_id=None, perimeter_id=perimeter_id) + if not actions or not (perimeter_id in actions): + raise exceptions.PerimeterContentError + + if 'policy_list' in value or ('name' in value and not value['name']): + raise exceptions.PerimeterContentError + + return self.driver.update_action(perimeter_id=perimeter_id, value=value) + @enforce(("read", "write"), "perimeter") def delete_action(self, user_id, policy_id, perimeter_id): - logger.debug("delete_action {} {} {}".format(policy_id, perimeter_id, self.get_policies(user_id=user_id, policy_id=policy_id))) - if policy_id and not self.get_policies(user_id=user_id, policy_id=policy_id): + + if not perimeter_id: + raise exceptions.ActionUnknown + + if not policy_id: + raise exceptions.PolicyUnknown + + if not self.get_actions(user_id=user_id, policy_id=policy_id, perimeter_id=perimeter_id): + raise exceptions.ActionUnknown + + logger.debug("delete_action {} {} {}".format(policy_id, perimeter_id, + self.get_policies(user_id=user_id, + policy_id=policy_id))) + if not self.get_policies(user_id=user_id, policy_id=policy_id): raise exceptions.PolicyUnknown + + act_assig = self.driver.get_action_assignments(policy_id=policy_id, action_id=perimeter_id) + if act_assig: + raise exceptions.DeletePerimeterWithAssignment return self.driver.delete_action(policy_id=policy_id, perimeter_id=perimeter_id) @enforce("read", "data") @@ -172,23 +387,27 @@ class PolicyManager(Managers): @enforce(("read", "write"), "data") def set_subject_data(self, user_id, policy_id, data_id=None, category_id=None, value=None): - if not category_id: - raise Exception('Invalid category id') - if not Managers.ModelManager.get_subject_categories(user_id=user_id, category_id=category_id): - raise exceptions.MetaDataUnknown - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown + if not category_id or ( + not Managers.ModelManager.get_subject_categories(user_id=user_id, + category_id=category_id)): + raise exceptions.SubjectCategoryUnknown + + self.__category_dependency_validation(user_id, policy_id, category_id, 'subject_categories') + if not data_id: data_id = uuid4().hex - return self.driver.set_subject_data(policy_id=policy_id, data_id=data_id, category_id=category_id, value=value) + return self.driver.set_subject_data(policy_id=policy_id, data_id=data_id, + category_id=category_id, value=value) @enforce(("read", "write"), "data") - def delete_subject_data(self, user_id, policy_id, data_id): + def delete_subject_data(self, user_id, policy_id, data_id, category_id=None): # TODO (asteroide): check and/or delete assignments linked to that data - subject_assignments = self.get_subject_assignments(user_id=user_id, policy_id=policy_id, subject_id=data_id) + subject_assignments = self.get_subject_assignments(user_id=user_id, policy_id=policy_id, + category_id=category_id) if subject_assignments: raise exceptions.DeleteData - return self.driver.delete_subject_data(policy_id=policy_id, data_id=data_id) + return self.driver.delete_subject_data(policy_id=policy_id, category_id=category_id, + data_id=data_id) @enforce("read", "data") def get_object_data(self, user_id, policy_id, data_id=None, category_id=None): @@ -205,23 +424,28 @@ class PolicyManager(Managers): @enforce(("read", "write"), "data") def add_object_data(self, user_id, policy_id, data_id=None, category_id=None, value=None): - if not category_id: - raise Exception('Invalid category id') - if not Managers.ModelManager.get_object_categories(user_id=user_id, category_id=category_id): - raise exceptions.MetaDataUnknown - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown + + if not category_id or ( + not Managers.ModelManager.get_object_categories(user_id=user_id, + category_id=category_id)): + raise exceptions.ObjectCategoryUnknown + + self.__category_dependency_validation(user_id, policy_id, category_id, 'object_categories') + if not data_id: data_id = uuid4().hex - return self.driver.set_object_data(policy_id=policy_id, data_id=data_id, category_id=category_id, value=value) + return self.driver.set_object_data(policy_id=policy_id, data_id=data_id, + category_id=category_id, value=value) @enforce(("read", "write"), "data") - def delete_object_data(self, user_id, policy_id, data_id): + def delete_object_data(self, user_id, policy_id, data_id, category_id=None): # TODO (asteroide): check and/or delete assignments linked to that data - object_assignments = self.get_object_assignments(user_id=user_id, policy_id=policy_id, object_id=data_id) + object_assignments = self.get_object_assignments(user_id=user_id, policy_id=policy_id, + category_id=category_id) if object_assignments: raise exceptions.DeleteData - return self.driver.delete_object_data(policy_id=policy_id, data_id=data_id) + return self.driver.delete_object_data(policy_id=policy_id, category_id=category_id, + data_id=data_id) @enforce("read", "data") def get_action_data(self, user_id, policy_id, data_id=None, category_id=None): @@ -238,38 +462,53 @@ class PolicyManager(Managers): @enforce(("read", "write"), "data") def add_action_data(self, user_id, policy_id, data_id=None, category_id=None, value=None): - if not category_id: - raise Exception('Invalid category id') - if not Managers.ModelManager.get_action_categories(user_id=user_id, category_id=category_id): - raise exceptions.MetaDataUnknown - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown + if not category_id or ( + not Managers.ModelManager.get_action_categories(user_id=user_id, + category_id=category_id)): + raise exceptions.ActionCategoryUnknown + + self.__category_dependency_validation(user_id, policy_id, category_id, 'action_categories') + if not data_id: data_id = uuid4().hex - return self.driver.set_action_data(policy_id=policy_id, data_id=data_id, category_id=category_id, value=value) + return self.driver.set_action_data(policy_id=policy_id, data_id=data_id, + category_id=category_id, value=value) @enforce(("read", "write"), "data") - def delete_action_data(self, user_id, policy_id, data_id): + def delete_action_data(self, user_id, policy_id, data_id, category_id=None): # TODO (asteroide): check and/or delete assignments linked to that data - action_assignments = self.get_action_assignments(user_id=user_id, policy_id=policy_id, action_id=data_id) + action_assignments = self.get_action_assignments(user_id=user_id, policy_id=policy_id, + category_id=category_id) if action_assignments: raise exceptions.DeleteData - return self.driver.delete_action_data(policy_id=policy_id, data_id=data_id) + return self.driver.delete_action_data(policy_id=policy_id, category_id=category_id, + data_id=data_id) @enforce("read", "assignments") def get_subject_assignments(self, user_id, policy_id, subject_id=None, category_id=None): - return self.driver.get_subject_assignments(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + return self.driver.get_subject_assignments(policy_id=policy_id, subject_id=subject_id, + category_id=category_id) @enforce(("read", "write"), "assignments") def add_subject_assignment(self, user_id, policy_id, subject_id, category_id, data_id): - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown - if not self.get_subjects(user_id=user_id, policy_id=policy_id, perimeter_id=subject_id): + + if not category_id or ( + not Managers.ModelManager.get_subject_categories(user_id=user_id, + category_id=category_id)): + raise exceptions.SubjectCategoryUnknown + + self.__category_dependency_validation(user_id, policy_id, category_id, 'subject_categories') + + if not subject_id or ( + not self.get_subjects(user_id=user_id, policy_id=policy_id, + perimeter_id=subject_id)): raise exceptions.SubjectUnknown - if not Managers.ModelManager.get_subject_categories(user_id=user_id, category_id=category_id): - raise exceptions.MetaDataUnknown - if not self.get_subject_data(user_id=user_id, policy_id=policy_id, data_id=data_id): + + if not data_id or ( + not self.get_subject_data(user_id=user_id, policy_id=policy_id, data_id=data_id, + category_id=category_id)): raise exceptions.DataUnknown + return self.driver.add_subject_assignment(policy_id=policy_id, subject_id=subject_id, category_id=category_id, data_id=data_id) @@ -280,18 +519,28 @@ class PolicyManager(Managers): @enforce("read", "assignments") def get_object_assignments(self, user_id, policy_id, object_id=None, category_id=None): - return self.driver.get_object_assignments(policy_id=policy_id, object_id=object_id, category_id=category_id) + return self.driver.get_object_assignments(policy_id=policy_id, object_id=object_id, + category_id=category_id) @enforce(("read", "write"), "assignments") def add_object_assignment(self, user_id, policy_id, object_id, category_id, data_id): - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown - if not self.get_objects(user_id=user_id, policy_id=policy_id, perimeter_id=object_id): + + if not category_id or ( + not Managers.ModelManager.get_object_categories(user_id=user_id, + category_id=category_id)): + raise exceptions.ObjectCategoryUnknown + + self.__category_dependency_validation(user_id, policy_id, category_id, 'object_categories') + + if not object_id or ( + not self.get_objects(user_id=user_id, policy_id=policy_id, perimeter_id=object_id)): raise exceptions.ObjectUnknown - if not Managers.ModelManager.get_object_categories(user_id=user_id, category_id=category_id): - raise exceptions.MetaDataUnknown - if not self.get_object_data(user_id=user_id, policy_id=policy_id, data_id=data_id): + + if not data_id or ( + not self.get_object_data(user_id=user_id, policy_id=policy_id, data_id=data_id, + category_id=category_id)): raise exceptions.DataUnknown + return self.driver.add_object_assignment(policy_id=policy_id, object_id=object_id, category_id=category_id, data_id=data_id) @@ -302,18 +551,28 @@ class PolicyManager(Managers): @enforce("read", "assignments") def get_action_assignments(self, user_id, policy_id, action_id=None, category_id=None): - return self.driver.get_action_assignments(policy_id=policy_id, action_id=action_id, category_id=category_id) + return self.driver.get_action_assignments(policy_id=policy_id, action_id=action_id, + category_id=category_id) @enforce(("read", "write"), "assignments") def add_action_assignment(self, user_id, policy_id, action_id, category_id, data_id): - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown - if not self.get_actions(user_id=user_id, policy_id=policy_id, perimeter_id=action_id): + + if not category_id or ( + not Managers.ModelManager.get_action_categories(user_id=user_id, + category_id=category_id)): + raise exceptions.ActionCategoryUnknown + + self.__category_dependency_validation(user_id, policy_id, category_id, 'action_categories') + + if not action_id or ( + not self.get_actions(user_id=user_id, policy_id=policy_id, perimeter_id=action_id)): raise exceptions.ActionUnknown - if not Managers.ModelManager.get_action_categories(user_id=user_id, category_id=category_id): - raise exceptions.MetaDataUnknown - if not self.get_action_data(user_id=user_id, policy_id=policy_id, data_id=data_id): + + if not data_id or ( + not self.get_action_data(user_id=user_id, policy_id=policy_id, data_id=data_id, + category_id=category_id)): raise exceptions.DataUnknown + return self.driver.add_action_assignment(policy_id=policy_id, action_id=action_id, category_id=category_id, data_id=data_id) @@ -324,17 +583,100 @@ class PolicyManager(Managers): @enforce("read", "rules") def get_rules(self, user_id, policy_id, meta_rule_id=None, rule_id=None): - return self.driver.get_rules(policy_id=policy_id, meta_rule_id=meta_rule_id, rule_id=rule_id) - logger.info("delete_subject_data: {} {}".format(policy_id, data_id)) + return self.driver.get_rules(policy_id=policy_id, meta_rule_id=meta_rule_id, + rule_id=rule_id) @enforce(("read", "write"), "rules") def add_rule(self, user_id, policy_id, meta_rule_id, value): - if not self.get_policies(user_id=user_id, policy_id=policy_id): - raise exceptions.PolicyUnknown - if not self.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id): + if not meta_rule_id or ( + not self.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id)): raise exceptions.MetaRuleUnknown + + self.__check_existing_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, user_id=user_id, + rule_value=value) + self.__dependencies_validation(user_id, policy_id, meta_rule_id) + return self.driver.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + def __check_existing_rule(self, user_id, policy_id, meta_rule_id, rule_value): + + if not meta_rule_id: + raise exceptions.MetaRuleUnknown + + meta_rule = self.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id) + if not meta_rule: + raise exceptions.MetaRuleUnknown + + if len(meta_rule[meta_rule_id]['subject_categories']) + len( + meta_rule[meta_rule_id]['object_categories']) \ + + len(meta_rule[meta_rule_id]['action_categories']) > len(rule_value['rule']): + raise exceptions.RuleContentError(message="Missing Data") + + if len(meta_rule[meta_rule_id]['subject_categories']) + len( + meta_rule[meta_rule_id]['object_categories']) \ + + len(meta_rule[meta_rule_id]['action_categories']) < len(rule_value['rule']): + raise exceptions.MetaRuleContentError(message="Missing Data") + + temp_rule_data = list( + rule_value['rule'][0:len(meta_rule[meta_rule_id]['subject_categories'])]) + found_data_counter = 0 + start_sub = len(meta_rule[meta_rule_id]['subject_categories']) + + for sub_cat_id in meta_rule[meta_rule_id]['subject_categories']: + subjects_data = self.get_subject_data(user_id=user_id, + category_id=sub_cat_id, policy_id=policy_id) + found_data_counter = self.__validate_data_id(sub_cat_id, subjects_data[0]['data'], + temp_rule_data, + "Missing Subject_category " + , found_data_counter) + + if found_data_counter != len(meta_rule[meta_rule_id]['subject_categories']): + raise exceptions.RuleContentError(message="Missing Data") + + temp_rule_data = list( + rule_value['rule'][ + start_sub:start_sub + len(meta_rule[meta_rule_id]['object_categories'])]) + found_data_counter = 0 + start_sub = start_sub + len(meta_rule[meta_rule_id]['object_categories']) + + for ob_cat_id in meta_rule[meta_rule_id]['object_categories']: + object_data = self.get_object_data(user_id=user_id, + category_id=ob_cat_id, policy_id=policy_id) + + found_data_counter = self.__validate_data_id(ob_cat_id, object_data[0]['data'], + temp_rule_data, + "Missing Object_category ", + found_data_counter) + + if found_data_counter != len(meta_rule[meta_rule_id]['object_categories']): + raise exceptions.RuleContentError(message="Missing Data") + + temp_rule_data = list( + rule_value['rule'][ + start_sub:start_sub + len(meta_rule[meta_rule_id]['action_categories'])]) + found_data_counter = 0 + + for act_cat_id in meta_rule[meta_rule_id]['action_categories']: + action_data = self.get_action_data(user_id=user_id, category_id=act_cat_id, + policy_id=policy_id) + found_data_counter = self.__validate_data_id(act_cat_id, action_data[0]['data'], + temp_rule_data, + "Missing Action_category ", + found_data_counter) + + if found_data_counter != len(meta_rule[meta_rule_id]['action_categories']): + raise exceptions.RuleContentError(message="Missing Data") + + def __validate_data_id(self, cat_id, data_ids, temp_rule_data, error_msg, found_data_counter): + for ID in data_ids: + if ID in temp_rule_data: + temp_rule_data.remove(ID) + found_data_counter += 1 + # if no data id found in the rule, so rule not valid + if found_data_counter < 1: + raise exceptions.RuleContentError(message=error_msg + cat_id) + return found_data_counter + @enforce(("read", "write"), "rules") def delete_rule(self, user_id, policy_id, rule_id): return self.driver.delete_rule(policy_id=policy_id, rule_id=rule_id) @@ -354,9 +696,56 @@ class PolicyManager(Managers): try: meta_rule_list = model[model_id]["meta_rules"] for meta_rule_id in meta_rule_list: - meta_rule = Managers.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id) + meta_rule = Managers.ModelManager.get_meta_rules(user_id=user_id, + meta_rule_id=meta_rule_id) categories["subject"].extend(meta_rule[meta_rule_id]["subject_categories"]) categories["object"].extend(meta_rule[meta_rule_id]["object_categories"]) categories["action"].extend(meta_rule[meta_rule_id]["action_categories"]) finally: return categories + + def __dependencies_validation(self, user_id, policy_id, meta_rule_id=None): + + policies = self.get_policies(user_id=user_id, policy_id=policy_id) + if not policy_id or (not policies): + raise exceptions.PolicyUnknown + + policy_content = policies[next(iter(policies))] + model_id = policy_content['model_id'] + models = Managers.ModelManager.get_models(user_id=user_id, model_id=model_id) + if not model_id or not models: + raise exceptions.ModelUnknown + + model_content = models[next(iter(models))] + if meta_rule_id: + meta_rule_exists = False + + for model_meta_rule_id in model_content['meta_rules']: + if model_meta_rule_id == meta_rule_id: + meta_rule_exists = True + break + + if not meta_rule_exists: + raise exceptions.MetaRuleNotLinkedWithPolicyModel + + meta_rule = self.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id) + meta_rule_content = meta_rule[next(iter(meta_rule))] + if (not meta_rule_content['subject_categories']) or ( + not meta_rule_content['object_categories']) or ( + not meta_rule_content['action_categories']): + raise exceptions.MetaRuleContentError + return model_content + + def __category_dependency_validation(self, user_id, policy_id, category_id, category_key): + model = self.__dependencies_validation(user_id=user_id, policy_id=policy_id) + category_found = False + for model_meta_rule_id in model['meta_rules']: + meta_rule = self.ModelManager.get_meta_rules(user_id=user_id, + meta_rule_id=model_meta_rule_id) + meta_rule_content = meta_rule[next(iter(meta_rule))] + if meta_rule_content[category_key] and category_id in meta_rule_content[category_key]: + category_found = True + break + + if not category_found: + raise exceptions.CategoryNotAssignedMetaRule diff --git a/python_moondb/python_moondb/backends/__init__.py b/python_moondb/python_moondb/backends/__init__.py index 237bdc3e..6f1cd3d5 100644 --- a/python_moondb/python_moondb/backends/__init__.py +++ b/python_moondb/python_moondb/backends/__init__.py @@ -1,4 +1,3 @@ - """ intra_extensions = { intra_extension_id1: { @@ -94,4 +93,4 @@ rules = { ...}, sub_meta_rule_id2: { }, ...} -""" \ No newline at end of file +""" diff --git a/python_moondb/python_moondb/backends/sql.py b/python_moondb/python_moondb/backends/sql.py index 7310e7f3..d25586ba 100644 --- a/python_moondb/python_moondb/backends/sql.py +++ b/python_moondb/python_moondb/backends/sql.py @@ -20,7 +20,8 @@ import sqlalchemy logger = logging.getLogger("moon.db.driver.sql") Base = declarative_base() -DEBUG = True if configuration.get_configuration("logging")['logging']['loggers']['moon']['level'] == "DEBUG" else False +DEBUG = True if configuration.get_configuration("logging")['logging']['loggers']['moon'][ + 'level'] == "DEBUG" else False class DictBase: @@ -50,7 +51,6 @@ class DictBase: class JsonBlob(sql_types.TypeDecorator): - impl = sql.Text def process_bind_param(self, value, dialect): @@ -174,6 +174,7 @@ class PerimeterDataBase(DictBase): id = sql.Column(sql.String(64), primary_key=True) name = sql.Column(sql.String(256), nullable=False) value = sql.Column(JsonBlob(), nullable=True) + @declared_attr def policy_id(cls): return sql.Column(sql.ForeignKey("policies.id"), nullable=False) @@ -254,10 +255,11 @@ class ActionAssignment(Base, PerimeterAssignmentBase): class MetaRule(Base, DictBase): __tablename__ = 'meta_rules' - attributes = ['id', 'name', 'subject_categories', 'object_categories', 'action_categories', 'value'] + attributes = ['id', 'name', 'subject_categories', 'object_categories', 'action_categories', + 'value'] id = sql.Column(sql.String(64), primary_key=True) name = sql.Column(sql.String(256), nullable=False) - subject_categories = sql.Column(JsonBlob(), nullable=True) + subject_categories = sql.Column(JsonBlob(), nullable=True) object_categories = sql.Column(JsonBlob(), nullable=True) action_categories = sql.Column(JsonBlob(), nullable=True) value = sql.Column(JsonBlob(), nullable=True) @@ -353,8 +355,10 @@ class PDPConnector(BaseConnector, PDPDriver): d.update(value_wo_name) setattr(ref, "value", d) return {ref.id: ref.to_dict()} - except sqlalchemy.exc.IntegrityError: - raise exceptions.PdpExisting + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.PdpExisting + raise error def delete_pdp(self, pdp_id): with self.get_session_for_write() as session: @@ -375,8 +379,10 @@ class PDPConnector(BaseConnector, PDPDriver): }) session.add(new) return {new.id: new.to_dict()} - except sqlalchemy.exc.IntegrityError: - raise exceptions.PdpExisting + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.PdpExisting + raise error def get_pdp(self, pdp_id=None): with self.get_session_for_read() as session: @@ -390,20 +396,27 @@ class PDPConnector(BaseConnector, PDPDriver): class PolicyConnector(BaseConnector, PolicyDriver): def update_policy(self, policy_id, value): - with self.get_session_for_write() as session: - query = session.query(Policy) - query = query.filter_by(id=policy_id) - ref = query.first() - if ref: - value_wo_other_info = copy.deepcopy(value) - value_wo_other_info.pop("name", None) - value_wo_other_info.pop("model_id", None) - ref.name = value["name"] - ref.model_id= value["model_id"] - d = dict(ref.value) - d.update(value_wo_other_info) - setattr(ref, "value", d) - return {ref.id: ref.to_dict()} + try: + with self.get_session_for_write() as session: + query = session.query(Policy) + query = query.filter_by(id=policy_id) + ref = query.first() + + if ref: + value_wo_other_info = copy.deepcopy(value) + value_wo_other_info.pop("name", None) + value_wo_other_info.pop("model_id", None) + ref.name = value["name"] + ref.model_id = value["model_id"] + d = dict(ref.value) + d.update(value_wo_other_info) + setattr(ref, "value", d) + return {ref.id: ref.to_dict()} + + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.PolicyExisting + raise error def delete_policy(self, policy_id): with self.get_session_for_write() as session: @@ -411,40 +424,49 @@ class PolicyConnector(BaseConnector, PolicyDriver): session.delete(ref) def add_policy(self, policy_id=None, value=None): - with self.get_session_for_write() as session: - value_wo_other_info = copy.deepcopy(value) - value_wo_other_info.pop("name", None) - value_wo_other_info.pop("model_id", None) - new = Policy.from_dict({ - "id": policy_id if policy_id else uuid4().hex, - "name": value["name"], - "model_id": value.get("model_id", ""), - "value": value_wo_other_info - }) - session.add(new) - return {new.id: new.to_dict()} + try: + with self.get_session_for_write() as session: + value_wo_other_info = copy.deepcopy(value) + value_wo_other_info.pop("name", None) + value_wo_other_info.pop("model_id", None) + new = Policy.from_dict({ + "id": policy_id if policy_id else uuid4().hex, + "name": value["name"], + "model_id": value.get("model_id", ""), + "value": value_wo_other_info + }) + session.add(new) + return {new.id: new.to_dict()} - def get_policies(self, policy_id=None): + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.PolicyExisting + raise error + + def get_policies(self, policy_id=None, policy_name=None): with self.get_session_for_read() as session: query = session.query(Policy) if policy_id: query = query.filter_by(id=policy_id) + elif policy_name: + query = query.filter_by(name=policy_name) + ref_list = query.all() return {_ref.id: _ref.to_dict() for _ref in ref_list} def __get_perimeters(self, ClassType, policy_id, perimeter_id=None): + # if not policy_id: + # raise exceptions.PolicyUnknown + with self.get_session_for_read() as session: query = session.query(ClassType) - ref_list = copy.deepcopy(query.all()) + if perimeter_id: - for _ref in ref_list: - _ref_value = _ref.to_return() - if perimeter_id == _ref.id: - if policy_id and policy_id in _ref_value["policy_list"]: - return {_ref.id: _ref_value} - else: - return {} - elif policy_id: + query = query.filter_by(id=perimeter_id) + + ref_list = copy.deepcopy(query.all()) + + if policy_id: results = [] for _ref in ref_list: _ref_value = _ref.to_return() @@ -453,9 +475,48 @@ class PolicyConnector(BaseConnector, PolicyDriver): return {_ref.id: _ref.to_return() for _ref in results} return {_ref.id: _ref.to_return() for _ref in ref_list} - def __set_perimeter(self, ClassType, ClassTypeException, policy_id, perimeter_id=None, value=None): + def __get_perimeter_by_name(self, ClassType, perimeter_name): + # if not policy_id: + # raise exceptions.PolicyUnknown + with self.get_session_for_read() as session: + query = session.query(ClassType) + if not perimeter_name or not perimeter_name.strip(): + raise exceptions.PerimeterContentError('invalid name') + query = query.filter_by(name=perimeter_name) + ref_list = copy.deepcopy(query.all()) + return {_ref.id: _ref.to_return() for _ref in ref_list} + + def __update_perimeter(self, class_type, class_type_exception, perimeter_id, value): + if not perimeter_id: + return exceptions.PerimeterContentError + with self.get_session_for_write() as session: + query = session.query(class_type) + query = query.filter_by(id=perimeter_id) + _perimeter = query.first() + if not _perimeter: + raise class_type_exception + temp_perimeter = copy.deepcopy(_perimeter.to_dict()) + if 'name' in value: + temp_perimeter['value']['name'] = value['name'] + if 'description' in value: + temp_perimeter['value']['description'] = value['description'] + if 'extra' in value: + temp_perimeter['value']['extra'] = value['extra'] + name = temp_perimeter['value']['name'] + temp_perimeter['value'].pop("name", None) + new_perimeter = class_type.from_dict({ + "id": temp_perimeter["id"], + "name": name, + "value": temp_perimeter["value"] + }) + _perimeter.value = new_perimeter.value + _perimeter.name = new_perimeter.name + return {_perimeter.id: _perimeter.to_return()} + + def __set_perimeter(self, ClassType, ClassTypeException, policy_id, perimeter_id=None, + value=None): if not value or "name" not in value or not value["name"].strip(): - raise exceptions.PerimeterNameInvalid + raise exceptions.PerimeterContentError('invalid name') with self.get_session_for_write() as session: _perimeter = None if perimeter_id: @@ -485,10 +546,16 @@ class PolicyConnector(BaseConnector, PolicyDriver): return {new.id: new.to_return()} else: _value = copy.deepcopy(_perimeter.to_dict()) - if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list: + if "policy_list" not in _value["value"] or type( + _value["value"]["policy_list"]) is not list: _value["value"]["policy_list"] = [] if policy_id and policy_id not in _value["value"]["policy_list"]: _value["value"]["policy_list"].append(policy_id) + else: + if policy_id: + raise exceptions.PolicyExisting + raise exceptions.PerimeterContentError + _value["value"].update(value) name = _value["value"]["name"] @@ -513,7 +580,10 @@ class PolicyConnector(BaseConnector, PolicyDriver): try: old_perimeter["value"]["policy_list"].remove(policy_id) new_perimeter = ClassType.from_dict(old_perimeter) - setattr(_perimeter, "value", getattr(new_perimeter, "value")) + if not new_perimeter.value["policy_list"]: + session.delete(_perimeter) + else: + setattr(_perimeter, "value", getattr(new_perimeter, "value")) except ValueError: if not _perimeter.value["policy_list"]: session.delete(_perimeter) @@ -521,11 +591,25 @@ class PolicyConnector(BaseConnector, PolicyDriver): def get_subjects(self, policy_id, perimeter_id=None): return self.__get_perimeters(Subject, policy_id, perimeter_id) + def get_subject_by_name(self, perimeter_name): + return self.__get_perimeter_by_name(Subject, perimeter_name) + def set_subject(self, policy_id, perimeter_id=None, value=None): try: - return self.__set_perimeter(Subject, exceptions.SubjectExisting, policy_id, perimeter_id=perimeter_id, value=value) - except sqlalchemy.exc.IntegrityError: - raise exceptions.SubjectExisting + return self.__set_perimeter(Subject, exceptions.SubjectExisting, policy_id, + perimeter_id=perimeter_id, value=value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.SubjectExisting + raise error + + def update_subject(self, perimeter_id, value): + try: + return self.__update_perimeter(Subject, exceptions.SubjectExisting, perimeter_id, value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.SubjectExisting + raise error def delete_subject(self, policy_id, perimeter_id): self.__delete_perimeter(Subject, exceptions.SubjectUnknown, policy_id, perimeter_id) @@ -533,12 +617,26 @@ class PolicyConnector(BaseConnector, PolicyDriver): def get_objects(self, policy_id, perimeter_id=None): return self.__get_perimeters(Object, policy_id, perimeter_id) + def get_object_by_name(self, perimeter_name): + return self.__get_perimeter_by_name(Object, perimeter_name) + def set_object(self, policy_id, perimeter_id=None, value=None): try: - return self.__set_perimeter(Object, exceptions.ObjectExisting, policy_id, perimeter_id=perimeter_id, value=value) - except sqlalchemy.exc.IntegrityError as e: - logger.exception("IntegrityError {}".format(e)) - raise exceptions.ObjectExisting + return self.__set_perimeter(Object, exceptions.ObjectExisting, policy_id, + perimeter_id=perimeter_id, value=value) + except sqlalchemy.exc.IntegrityError as error: + logger.exception("IntegrityError {}".format(error)) + if 'UNIQUE constraint' in str(error): + raise exceptions.ObjectExisting + raise error + + def update_object(self, perimeter_id, value): + try: + return self.__update_perimeter(Object, exceptions.ObjectExisting, perimeter_id, value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ObjectExisting + raise error def delete_object(self, policy_id, perimeter_id): self.__delete_perimeter(Object, exceptions.ObjectUnknown, policy_id, perimeter_id) @@ -546,18 +644,31 @@ class PolicyConnector(BaseConnector, PolicyDriver): def get_actions(self, policy_id, perimeter_id=None): return self.__get_perimeters(Action, policy_id, perimeter_id) + def get_action_by_name(self, perimeter_name): + return self.__get_perimeter_by_name(Action, perimeter_name) + def set_action(self, policy_id, perimeter_id=None, value=None): try: - return self.__set_perimeter(Action, exceptions.ActionExisting, policy_id, perimeter_id=perimeter_id, value=value) - except sqlalchemy.exc.IntegrityError: - raise exceptions.ActionExisting + return self.__set_perimeter(Action, exceptions.ActionExisting, policy_id, + perimeter_id=perimeter_id, value=value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ActionExisting + raise error + + def update_action(self, perimeter_id, value): + try: + return self.__update_perimeter(Action, exceptions.ActionExisting, perimeter_id, value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ActionExisting + raise error def delete_action(self, policy_id, perimeter_id): self.__delete_perimeter(Action, exceptions.ActionUnknown, policy_id, perimeter_id) - def __is_data_exist(self, ClassType, data_id=None, category_id=None): - if not data_id: - return False + def __is_data_exist(self, ClassType, category_id=None): + with self.get_session_for_read() as session: query = session.query(ClassType) query = query.filter_by(category_id=category_id) @@ -573,8 +684,13 @@ class PolicyConnector(BaseConnector, PolicyDriver): query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) elif policy_id and category_id: query = query.filter_by(policy_id=policy_id, category_id=category_id) - else: + elif category_id: query = query.filter_by(category_id=category_id) + elif policy_id: + query = query.filter_by(policy_id=policy_id) + else: + raise exceptions.PolicyUnknown + ref_list = query.all() return { "policy_id": policy_id, @@ -582,7 +698,8 @@ class PolicyConnector(BaseConnector, PolicyDriver): "data": {_ref.id: _ref.to_dict() for _ref in ref_list} } - def __set_data(self, ClassType, ClassTypeData, policy_id, data_id=None, category_id=None, value=None): + def __set_data(self, ClassType, ClassTypeData, policy_id, data_id=None, category_id=None, + value=None): with self.get_session_for_write() as session: query = session.query(ClassTypeData) query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) @@ -612,65 +729,81 @@ class PolicyConnector(BaseConnector, PolicyDriver): "data": {ref.id: ref.to_dict()} } - def __delete_data(self, ClassType, policy_id, data_id): + def __delete_data(self, ClassType, policy_id, category_id, data_id): + + if not data_id: + raise exceptions.DataUnknown with self.get_session_for_write() as session: query = session.query(ClassType) - query = query.filter_by(policy_id=policy_id, id=data_id) + if category_id: + query = query.filter_by(policy_id=policy_id, category_id=category_id, id=data_id) + else: + query = query.filter_by(policy_id=policy_id, id=data_id) ref = query.first() if ref: session.delete(ref) - def is_subject_data_exist(self, data_id=None, category_id=None): - return self.__is_data_exist(SubjectData, data_id=data_id, category_id=category_id) + def is_subject_data_exist(self, category_id=None): + return self.__is_data_exist(SubjectData, category_id=category_id) def get_subject_data(self, policy_id, data_id=None, category_id=None): return self.__get_data(SubjectData, policy_id, data_id=data_id, category_id=category_id) def set_subject_data(self, policy_id, data_id=None, category_id=None, value=None): try: - return self.__set_data(Subject, SubjectData, policy_id, data_id=data_id, category_id=category_id, value=value) - except sqlalchemy.exc.IntegrityError: - raise exceptions.SubjectScopeExisting + return self.__set_data(Subject, SubjectData, policy_id, data_id=data_id, + category_id=category_id, value=value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.SubjectScopeExisting + raise error - def delete_subject_data(self, policy_id, data_id): - return self.__delete_data(SubjectData, policy_id, data_id) + def delete_subject_data(self, policy_id, category_id, data_id): + return self.__delete_data(SubjectData, policy_id, category_id, data_id) - def is_object_data_exist(self, data_id=None, category_id=None): - return self.__is_data_exist(ObjectData, data_id=data_id, category_id=category_id) + def is_object_data_exist(self, category_id=None): + return self.__is_data_exist(ObjectData, category_id=category_id) def get_object_data(self, policy_id, data_id=None, category_id=None): return self.__get_data(ObjectData, policy_id, data_id=data_id, category_id=category_id) def set_object_data(self, policy_id, data_id=None, category_id=None, value=None): try: - return self.__set_data(Object, ObjectData, policy_id, data_id=data_id, category_id=category_id, value=value) - except sqlalchemy.exc.IntegrityError: - raise exceptions.ObjectScopeExisting + return self.__set_data(Object, ObjectData, policy_id, data_id=data_id, + category_id=category_id, value=value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ObjectScopeExisting + raise error - def delete_object_data(self, policy_id, data_id): - return self.__delete_data(ObjectData, policy_id, data_id) + def delete_object_data(self, policy_id, category_id, data_id): + return self.__delete_data(ObjectData, policy_id, category_id, data_id) - def is_action_data_exist(self, data_id=None,category_id=None): - return self.__is_data_exist(ActionData, data_id=data_id, category_id=category_id) + def is_action_data_exist(self, category_id=None): + return self.__is_data_exist(ActionData, category_id=category_id) def get_action_data(self, policy_id, data_id=None, category_id=None): return self.__get_data(ActionData, policy_id, data_id=data_id, category_id=category_id) def set_action_data(self, policy_id, data_id=None, category_id=None, value=None): try: - return self.__set_data(Action, ActionData, policy_id, data_id=data_id, category_id=category_id, value=value) - except sqlalchemy.exc.IntegrityError: - raise exceptions.ActionScopeExisting + return self.__set_data(Action, ActionData, policy_id, data_id=data_id, + category_id=category_id, value=value) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ActionScopeExisting + raise error - def delete_action_data(self, policy_id, data_id): - return self.__delete_data(ActionData, policy_id, data_id) + def delete_action_data(self, policy_id, category_id, data_id): + return self.__delete_data(ActionData, policy_id, category_id, data_id) def get_subject_assignments(self, policy_id, subject_id=None, category_id=None): with self.get_session_for_write() as session: query = session.query(SubjectAssignment) if subject_id and category_id: - #TODO change the subject_id to perimeter_id to allow code refactoring - query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + # TODO change the subject_id to perimeter_id to allow code refactoring + query = query.filter_by(policy_id=policy_id, subject_id=subject_id, + category_id=category_id) elif subject_id: query = query.filter_by(policy_id=policy_id, subject_id=subject_id) else: @@ -681,7 +814,8 @@ class PolicyConnector(BaseConnector, PolicyDriver): def add_subject_assignment(self, policy_id, subject_id, category_id, data_id): with self.get_session_for_write() as session: query = session.query(SubjectAssignment) - query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, subject_id=subject_id, + category_id=category_id) ref = query.first() if ref: old_ref = copy.deepcopy(ref.to_dict()) @@ -704,10 +838,27 @@ class PolicyConnector(BaseConnector, PolicyDriver): session.add(ref) return {ref.id: ref.to_dict()} + def is_subject_category_has_assignment(self, category_id): + return self.__is_category_has_assignment(SubjectAssignment, category_id) + + def is_object_category_has_assignment(self, category_id): + return self.__is_category_has_assignment(ObjectAssignment, category_id) + + def is_action_category_has_assignment(self, category_id): + return self.__is_category_has_assignment(ActionAssignment, category_id) + + def __is_category_has_assignment(self, ClassType, category_id): + with self.get_session_for_write() as session: + query = session.query(ClassType) + query = query.filter_by(category_id=category_id) + count = query.count() + return count > 0 + def delete_subject_assignment(self, policy_id, subject_id, category_id, data_id): with self.get_session_for_write() as session: query = session.query(SubjectAssignment) - query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, subject_id=subject_id, + category_id=category_id) ref = query.first() if ref: old_ref = copy.deepcopy(ref.to_dict()) @@ -724,8 +875,9 @@ class PolicyConnector(BaseConnector, PolicyDriver): with self.get_session_for_write() as session: query = session.query(ObjectAssignment) if object_id and category_id: - #TODO change the object_id to perimeter_id to allow code refactoring - query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id) + # TODO change the object_id to perimeter_id to allow code refactoring + query = query.filter_by(policy_id=policy_id, object_id=object_id, + category_id=category_id) elif object_id: query = query.filter_by(policy_id=policy_id, object_id=object_id) else: @@ -736,7 +888,8 @@ class PolicyConnector(BaseConnector, PolicyDriver): def add_object_assignment(self, policy_id, object_id, category_id, data_id): with self.get_session_for_write() as session: query = session.query(ObjectAssignment) - query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, object_id=object_id, + category_id=category_id) ref = query.first() if ref: old_ref = copy.deepcopy(ref.to_dict()) @@ -762,7 +915,8 @@ class PolicyConnector(BaseConnector, PolicyDriver): def delete_object_assignment(self, policy_id, object_id, category_id, data_id): with self.get_session_for_write() as session: query = session.query(ObjectAssignment) - query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, object_id=object_id, + category_id=category_id) ref = query.first() if ref: old_ref = copy.deepcopy(ref.to_dict()) @@ -777,12 +931,17 @@ class PolicyConnector(BaseConnector, PolicyDriver): def get_action_assignments(self, policy_id, action_id=None, category_id=None): with self.get_session_for_write() as session: + if not policy_id: + return exceptions.PolicyUnknown query = session.query(ActionAssignment) if action_id and category_id: # TODO change the action_id to perimeter_id to allow code refactoring - query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, action_id=action_id, + category_id=category_id) elif action_id: query = query.filter_by(policy_id=policy_id, action_id=action_id) + elif category_id: + query = query.filter_by(policy_id=policy_id, category_id=category_id) else: query = query.filter_by(policy_id=policy_id) ref_list = query.all() @@ -791,7 +950,8 @@ class PolicyConnector(BaseConnector, PolicyDriver): def add_action_assignment(self, policy_id, action_id, category_id, data_id): with self.get_session_for_write() as session: query = session.query(ActionAssignment) - query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, action_id=action_id, + category_id=category_id) ref = query.first() if ref: old_ref = copy.deepcopy(ref.to_dict()) @@ -817,7 +977,8 @@ class PolicyConnector(BaseConnector, PolicyDriver): def delete_action_assignment(self, policy_id, action_id, category_id, data_id): with self.get_session_for_write() as session: query = session.query(ActionAssignment) - query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id) + query = query.filter_by(policy_id=policy_id, action_id=action_id, + category_id=category_id) ref = query.first() if ref: old_ref = copy.deepcopy(ref.to_dict()) @@ -837,7 +998,7 @@ class PolicyConnector(BaseConnector, PolicyDriver): query = query.filter_by(policy_id=policy_id, rule_id=rule_id) ref = query.first() return {ref.id: ref.to_dict()} - elif meta_rule_id: + elif meta_rule_id and policy_id: query = query.filter_by(policy_id=policy_id, meta_rule_id=meta_rule_id) ref_list = query.all() return { @@ -853,6 +1014,14 @@ class PolicyConnector(BaseConnector, PolicyDriver): "rules": list(map(lambda x: x.to_dict(), ref_list)) } + def is_meta_rule_has_rules(self, meta_rule_id): + with self.get_session_for_read() as session: + query = session.query(Rule) + + query = query.filter_by(meta_rule_id=meta_rule_id) + count = query.count() + return count > 0 + def add_rule(self, policy_id, meta_rule_id, value): try: rules = self.get_rules(policy_id, meta_rule_id=meta_rule_id) @@ -870,8 +1039,10 @@ class PolicyConnector(BaseConnector, PolicyDriver): ) session.add(ref) return {ref.id: ref.to_dict()} - except sqlalchemy.exc.IntegrityError: - raise exceptions.RuleExisting + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.RuleExisting + raise error def delete_rule(self, policy_id, rule_id): with self.get_session_for_write() as session: @@ -885,19 +1056,24 @@ class PolicyConnector(BaseConnector, PolicyDriver): class ModelConnector(BaseConnector, ModelDriver): def update_model(self, model_id, value): - with self.get_session_for_write() as session: - query = session.query(Model) - if model_id: - query = query.filter_by(id=model_id) - ref = query.first() - if ref: - value_wo_name = copy.deepcopy(value) - value_wo_name.pop("name", None) - setattr(ref, "name", value["name"]) - d = dict(ref.value) - d.update(value_wo_name) - setattr(ref, "value", d) - return {ref.id: ref.to_dict()} + try: + with self.get_session_for_write() as session: + query = session.query(Model) + if model_id: + query = query.filter_by(id=model_id) + ref = query.first() + if ref: + value_wo_name = copy.deepcopy(value) + value_wo_name.pop("name", None) + setattr(ref, "name", value["name"]) + d = dict(ref.value) + d.update(value_wo_name) + setattr(ref, "value", d) + return {ref.id: ref.to_dict()} + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ModelExisting + raise error def delete_model(self, model_id): with self.get_session_for_write() as session: @@ -916,8 +1092,9 @@ class ModelConnector(BaseConnector, ModelDriver): }) session.add(new) return {new.id: new.to_dict()} - except sqlalchemy.exc.IntegrityError as e: - raise exceptions.ModelExisting + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ModelExisting def get_models(self, model_id=None): with self.get_session_for_read() as session: @@ -931,37 +1108,44 @@ class ModelConnector(BaseConnector, ModelDriver): return r def set_meta_rule(self, meta_rule_id, value): - with self.get_session_for_write() as session: - value_wo_other_data = copy.deepcopy(value) - value_wo_other_data.pop("name", None) - value_wo_other_data.pop("subject_categories", None) - value_wo_other_data.pop("object_categories", None) - value_wo_other_data.pop("action_categories", None) - if meta_rule_id is None: - try: - ref = MetaRule.from_dict( - { - "id": uuid4().hex, - "name": value["name"], - "subject_categories": value["subject_categories"], - "object_categories": value["object_categories"], - "action_categories": value["action_categories"], - "value": value_wo_other_data - } - ) - session.add(ref) - except sqlalchemy.exc.IntegrityError as e: - raise exceptions.MetaRuleExisting - else: - query = session.query(MetaRule) - query = query.filter_by(id=meta_rule_id) - ref = query.first() - setattr(ref, "name", value["name"]) - setattr(ref, "subject_categories", value["subject_categories"]) - setattr(ref, "object_categories", value["object_categories"]) - setattr(ref, "action_categories", value["action_categories"]) - setattr(ref, "value", value_wo_other_data) - return {ref.id: ref.to_dict()} + try: + with self.get_session_for_write() as session: + value_wo_other_data = copy.deepcopy(value) + value_wo_other_data.pop("name", None) + value_wo_other_data.pop("subject_categories", None) + value_wo_other_data.pop("object_categories", None) + value_wo_other_data.pop("action_categories", None) + if meta_rule_id is None: + try: + ref = MetaRule.from_dict( + { + "id": uuid4().hex, + "name": value["name"], + "subject_categories": value["subject_categories"], + "object_categories": value["object_categories"], + "action_categories": value["action_categories"], + "value": value_wo_other_data + } + ) + session.add(ref) + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.MetaRuleExisting + raise error + else: + query = session.query(MetaRule) + query = query.filter_by(id=meta_rule_id) + ref = query.first() + setattr(ref, "name", value["name"]) + setattr(ref, "subject_categories", value["subject_categories"]) + setattr(ref, "object_categories", value["object_categories"]) + setattr(ref, "action_categories", value["action_categories"]) + setattr(ref, "value", value_wo_other_data) + return {ref.id: ref.to_dict()} + except sqlalchemy.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.MetaRuleExisting + raise error def get_meta_rules(self, meta_rule_id=None): with self.get_session_for_read() as session: @@ -988,7 +1172,7 @@ class ModelConnector(BaseConnector, ModelDriver): return {_ref.id: _ref.to_dict() for _ref in ref_list} def __add_perimeter_category(self, ClassType, name, description, uuid=None): - if not name.strip(): + if not name or not name.strip(): raise exceptions.CategoryNameInvalid with self.get_session_for_write() as session: ref = ClassType.from_dict( @@ -1015,8 +1199,10 @@ class ModelConnector(BaseConnector, ModelDriver): def add_subject_category(self, name, description, uuid=None): try: return self.__add_perimeter_category(SubjectCategory, name, description, uuid=uuid) - except sql.exc.IntegrityError as e: - raise exceptions.SubjectCategoryExisting() + except sql.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.SubjectCategoryExisting + raise error def delete_subject_category(self, category_id): self.__delete_perimeter_category(SubjectCategory, category_id) @@ -1027,8 +1213,10 @@ class ModelConnector(BaseConnector, ModelDriver): def add_object_category(self, name, description, uuid=None): try: return self.__add_perimeter_category(ObjectCategory, name, description, uuid=uuid) - except sql.exc.IntegrityError as e: - raise exceptions.ObjectCategoryExisting() + except sql.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ObjectCategoryExisting + raise error def delete_object_category(self, category_id): self.__delete_perimeter_category(ObjectCategory, category_id) @@ -1040,8 +1228,10 @@ class ModelConnector(BaseConnector, ModelDriver): def add_action_category(self, name, description, uuid=None): try: return self.__add_perimeter_category(ActionCategory, name, description, uuid=uuid) - except sql.exc.IntegrityError as e: - raise exceptions.ActionCategoryExisting() + except sql.exc.IntegrityError as error: + if 'UNIQUE constraint' in str(error): + raise exceptions.ActionCategoryExisting + raise error def delete_action_category(self, category_id): self.__delete_perimeter_category(ActionCategory, category_id) diff --git a/python_moondb/python_moondb/core.py b/python_moondb/python_moondb/core.py index 984b81a7..3fee146b 100644 --- a/python_moondb/python_moondb/core.py +++ b/python_moondb/python_moondb/core.py @@ -19,7 +19,7 @@ class Driver(DriverManager): namespace='moon_db.driver', name=driver_name, invoke_on_load=True, - invoke_args=(engine_name, ), + invoke_args=(engine_name,), ) diff --git a/python_moondb/python_moondb/migrate_repo/versions/001_moon.py b/python_moondb/python_moondb/migrate_repo/versions/001_moon.py index 1bfb2ffa..13670b91 100644 --- a/python_moondb/python_moondb/migrate_repo/versions/001_moon.py +++ b/python_moondb/python_moondb/migrate_repo/versions/001_moon.py @@ -7,8 +7,8 @@ import json import sqlalchemy as sql from sqlalchemy import types as sql_types -class JsonBlob(sql_types.TypeDecorator): +class JsonBlob(sql_types.TypeDecorator): impl = sql.Text def process_bind_param(self, value, dialect): @@ -134,7 +134,8 @@ def upgrade(migrate_engine): sql.Column('value', JsonBlob(), nullable=True), sql.Column('category_id', sql.ForeignKey("subject_categories.id"), nullable=False), sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), - sql.UniqueConstraint('name', 'category_id', 'policy_id', name='unique_constraint_subject_data'), + sql.UniqueConstraint('name', 'category_id', 'policy_id', + name='unique_constraint_subject_data'), mysql_engine='InnoDB', mysql_charset='utf8') subject_data_table.create(migrate_engine, checkfirst=True) @@ -147,7 +148,8 @@ def upgrade(migrate_engine): sql.Column('value', JsonBlob(), nullable=True), sql.Column('category_id', sql.ForeignKey("object_categories.id"), nullable=False), sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), - sql.UniqueConstraint('name', 'category_id', 'policy_id', name='unique_constraint_object_data'), + sql.UniqueConstraint('name', 'category_id', 'policy_id', + name='unique_constraint_object_data'), mysql_engine='InnoDB', mysql_charset='utf8') object_data_table.create(migrate_engine, checkfirst=True) @@ -160,7 +162,8 @@ def upgrade(migrate_engine): sql.Column('value', JsonBlob(), nullable=True), sql.Column('category_id', sql.ForeignKey("action_categories.id"), nullable=False), sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), - sql.UniqueConstraint('name', 'category_id', 'policy_id', name='unique_constraint_action_data'), + sql.UniqueConstraint('name', 'category_id', 'policy_id', + name='unique_constraint_action_data'), mysql_engine='InnoDB', mysql_charset='utf8') action_data_table.create(migrate_engine, checkfirst=True) @@ -173,7 +176,8 @@ def upgrade(migrate_engine): sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), sql.Column('subject_id', sql.ForeignKey("subjects.id"), nullable=False), sql.Column('category_id', sql.ForeignKey("subject_categories.id"), nullable=False), - sql.UniqueConstraint('policy_id', 'subject_id', 'category_id', name='unique_constraint_subject_assignment'), + sql.UniqueConstraint('policy_id', 'subject_id', 'category_id', + name='unique_constraint_subject_assignment'), mysql_engine='InnoDB', mysql_charset='utf8') subject_assignments_table.create(migrate_engine, checkfirst=True) @@ -186,7 +190,8 @@ def upgrade(migrate_engine): sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), sql.Column('object_id', sql.ForeignKey("objects.id"), nullable=False), sql.Column('category_id', sql.ForeignKey("object_categories.id"), nullable=False), - sql.UniqueConstraint('policy_id', 'object_id', 'category_id', name='unique_constraint_object_assignment'), + sql.UniqueConstraint('policy_id', 'object_id', 'category_id', + name='unique_constraint_object_assignment'), mysql_engine='InnoDB', mysql_charset='utf8') object_assignments_table.create(migrate_engine, checkfirst=True) @@ -199,7 +204,8 @@ def upgrade(migrate_engine): sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), sql.Column('action_id', sql.ForeignKey("actions.id"), nullable=False), sql.Column('category_id', sql.ForeignKey("action_categories.id"), nullable=False), - sql.UniqueConstraint('policy_id', 'action_id', 'category_id', name='unique_constraint_action_assignment'), + sql.UniqueConstraint('policy_id', 'action_id', 'category_id', + name='unique_constraint_action_assignment'), mysql_engine='InnoDB', mysql_charset='utf8') action_assignments_table.create(migrate_engine, checkfirst=True) @@ -236,28 +242,26 @@ def downgrade(migrate_engine): meta.bind = migrate_engine for _table in ( - 'rules', - 'meta_rules', - 'action_assignments', - 'object_assignments', - 'subject_assignments', - 'action_data', - 'object_data', - 'subject_data', - 'actions', - 'objects', - 'subjects', - 'action_categories', - 'object_categories', - 'subject_categories', - 'models', - 'policies', - 'pdp' + 'rules', + 'meta_rules', + 'action_assignments', + 'object_assignments', + 'subject_assignments', + 'action_data', + 'object_data', + 'subject_data', + 'actions', + 'objects', + 'subjects', + 'action_categories', + 'object_categories', + 'subject_categories', + 'models', + 'policies', + 'pdp' ): try: table = sql.Table(_table, meta, autoload=True) table.drop(migrate_engine, checkfirst=True) except Exception as e: print(e) - - diff --git a/python_moondb/tests/unit_python/helpers/data_helper.py b/python_moondb/tests/unit_python/helpers/data_helper.py index 20d9ae9a..8a8238f5 100644 --- a/python_moondb/tests/unit_python/helpers/data_helper.py +++ b/python_moondb/tests/unit_python/helpers/data_helper.py @@ -15,7 +15,7 @@ def add_action_data(policy_id, data_id=None, category_id=None, value=None): def delete_action_data(policy_id, data_id): from python_moondb.core import PolicyManager - PolicyManager.delete_action_data("", policy_id, data_id) + PolicyManager.delete_action_data("",policy_id=policy_id, data_id=data_id) def get_object_data(policy_id, data_id=None, category_id=None): @@ -30,7 +30,7 @@ def add_object_data(policy_id, data_id=None, category_id=None, value=None): def delete_object_data(policy_id, data_id): from python_moondb.core import PolicyManager - PolicyManager.delete_object_data("", policy_id, data_id) + PolicyManager.delete_object_data("", policy_id=policy_id, data_id=data_id) def get_subject_data(policy_id, data_id=None, category_id=None): @@ -45,7 +45,7 @@ def add_subject_data(policy_id, data_id=None, category_id=None, value=None): def delete_subject_data(policy_id, data_id): from python_moondb.core import PolicyManager - PolicyManager.delete_subject_data("", policy_id, data_id) + PolicyManager.delete_subject_data("", policy_id=policy_id, data_id=data_id) def get_actions(policy_id, perimeter_id=None): diff --git a/python_moondb/tests/unit_python/helpers/meta_rule_helper.py b/python_moondb/tests/unit_python/helpers/meta_rule_helper.py index 80d138c6..87af250a 100644 --- a/python_moondb/tests/unit_python/helpers/meta_rule_helper.py +++ b/python_moondb/tests/unit_python/helpers/meta_rule_helper.py @@ -6,7 +6,7 @@ from helpers import mock_data -def set_meta_rule(meta_rule_id, value=None): +def update_meta_rule(meta_rule_id, value=None): from python_moondb.core import ModelManager if not value: action_category_id = mock_data.create_action_category("action_category_id1") @@ -19,7 +19,7 @@ def set_meta_rule(meta_rule_id, value=None): "object_categories": [object_category_id], "action_categories": [action_category_id] } - return ModelManager.set_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value) + return ModelManager.update_meta_rule(user_id=None, meta_rule_id=meta_rule_id, value=value) def add_meta_rule(meta_rule_id=None, value=None): diff --git a/python_moondb/tests/unit_python/helpers/mock_data.py b/python_moondb/tests/unit_python/helpers/mock_data.py index 82eebe88..0d65ea02 100644 --- a/python_moondb/tests/unit_python/helpers/mock_data.py +++ b/python_moondb/tests/unit_python/helpers/mock_data.py @@ -8,6 +8,7 @@ from .policy_helper import * from .data_helper import * from .model_helper import * from .meta_rule_helper import * +from uuid import uuid4 def create_subject_category(name): @@ -58,12 +59,19 @@ def create_pdp(policies_ids): return value -def create_new_policy(subject_category_name=None, object_category_name=None, action_category_name=None, - model_name="test_model", policy_name="policy_1", meta_rule_name="meta_rule1"): +def create_new_policy(subject_category_name="subjectCategory", object_category_name="objectCategory", + action_category_name="actionCategory", + model_name="test_model", policy_name="policy_name", + meta_rule_name="meta_rule_"): + if policy_name == "policy_name": + policy_name = "policy_name_" + uuid4().hex + subject_category_id, object_category_id, action_category_id, meta_rule_id = create_new_meta_rule( - subject_category_name=subject_category_name, - object_category_name=object_category_name, - action_category_name=action_category_name, meta_rule_name=meta_rule_name) + subject_category_name=subject_category_name + uuid4().hex, + object_category_name=object_category_name + uuid4().hex, + action_category_name=action_category_name + uuid4().hex, + meta_rule_name=meta_rule_name + uuid4().hex + ) model = add_model(value=create_model(meta_rule_id, model_name)) model_id = list(model.keys())[0] value = create_policy(model_id, policy_name) @@ -73,8 +81,12 @@ def create_new_policy(subject_category_name=None, object_category_name=None, act return subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id -def create_new_meta_rule(subject_category_name=None, object_category_name=None, action_category_name=None, - meta_rule_name="meta_rule1"): +def create_new_meta_rule(subject_category_name="subject_category" + uuid4().hex, + object_category_name="object_category" + uuid4().hex, + action_category_name="action_category" + uuid4().hex, + meta_rule_name="meta_rule" + uuid4().hex): + from python_moondb.core import ModelManager + subject_category_id = create_subject_category(subject_category_name) object_category_id = create_object_category(object_category_name) action_category_id = create_action_category(action_category_name) @@ -84,7 +96,8 @@ def create_new_meta_rule(subject_category_name=None, object_category_name=None, "object_categories": [object_category_id], "action_categories": [action_category_id] } - meta_rule = add_meta_rule(value=value) + # meta_rule = add_meta_rule(value=value) + meta_rule = ModelManager.add_meta_rule(user_id=None, meta_rule_id=None, value=value) return subject_category_id, object_category_id, action_category_id, list(meta_rule.keys())[0] @@ -117,8 +130,8 @@ def create_action(policy_id): def create_subject_data(policy_id, category_id): value = { - "name": "subject-security-level", - "description": {"low": "", "medium": "", "high": ""}, + "name": uuid4().hex, + "description": {uuid4().hex: "", uuid4().hex: "", uuid4().hex: ""}, } subject_data = add_subject_data(policy_id=policy_id, category_id=category_id, value=value).get('data') assert subject_data @@ -127,8 +140,8 @@ def create_subject_data(policy_id, category_id): def create_object_data(policy_id, category_id): value = { - "name": "object-security-level", - "description": {"low": "", "medium": "", "high": ""}, + "name": uuid4().hex, + "description": {uuid4().hex: "", uuid4().hex: "", uuid4().hex: ""}, } object_data = add_object_data(policy_id=policy_id, category_id=category_id, value=value).get('data') return list(object_data.keys())[0] @@ -136,9 +149,8 @@ def create_object_data(policy_id, category_id): def create_action_data(policy_id, category_id): value = { - "name": "action-type", - "description": {"vm-action": "", "storage-action": "", }, + "name": uuid4().hex, + "description": {uuid4().hex: "", uuid4().hex: "", uuid4().hex: ""}, } action_data = add_action_data(policy_id=policy_id, category_id=category_id, value=value).get('data') return list(action_data.keys())[0] - diff --git a/python_moondb/tests/unit_python/helpers/model_helper.py b/python_moondb/tests/unit_python/helpers/model_helper.py index 58946a99..98a6271d 100644 --- a/python_moondb/tests/unit_python/helpers/model_helper.py +++ b/python_moondb/tests/unit_python/helpers/model_helper.py @@ -4,7 +4,7 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. from helpers import mock_data - +from uuid import uuid4 def get_models(model_id=None): from python_moondb.core import ModelManager @@ -14,10 +14,7 @@ def get_models(model_id=None): def add_model(model_id=None, value=None): from python_moondb.core import ModelManager if not value: - subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule( - subject_category_name="subject_category1", - object_category_name="object_category1", - action_category_name="action_category1") + subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule() name = "MLS" if model_id is None else "MLS " + model_id value = { "name": name, diff --git a/python_moondb/tests/unit_python/helpers/policy_helper.py b/python_moondb/tests/unit_python/helpers/policy_helper.py index c932ee3a..93d81c62 100644 --- a/python_moondb/tests/unit_python/helpers/policy_helper.py +++ b/python_moondb/tests/unit_python/helpers/policy_helper.py @@ -2,6 +2,8 @@ # This software is distributed under the terms and conditions of the 'Apache-2.0' # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. +from helpers import mock_data as mock_data +from helpers import meta_rule_helper def get_policies(): from python_moondb.core import PolicyManager @@ -45,11 +47,20 @@ def get_rules(policy_id=None, meta_rule_id=None, rule_id=None): return PolicyManager.get_rules("", policy_id, meta_rule_id, rule_id) -def add_rule(policy_id=None, meta_rule_id=None, value=None): +def add_rule(policy_id, meta_rule_id, value=None): from python_moondb.core import PolicyManager if not value: + meta_rule = meta_rule_helper.get_meta_rules(meta_rule_id) + sub_cat_id = meta_rule[meta_rule_id]['subject_categories'][0] + ob_cat_id = meta_rule[meta_rule_id]['object_categories'][0] + act_cat_id = meta_rule[meta_rule_id]['action_categories'][0] + + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=sub_cat_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, category_id=ob_cat_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, category_id=act_cat_id) + value = { - "rule": ("high", "medium", "vm-action"), + "rule": (subject_data_id, object_data_id, action_data_id), "instructions": ({"decision": "grant"}), "enabled": "", } diff --git a/python_moondb/tests/unit_python/models/test_categories.py b/python_moondb/tests/unit_python/models/test_categories.py index f87d0e12..39dc4c71 100644 --- a/python_moondb/tests/unit_python/models/test_categories.py +++ b/python_moondb/tests/unit_python/models/test_categories.py @@ -10,13 +10,24 @@ from helpers import category_helper logger = logging.getLogger("moon.db.tests.models.test_categories") + def test_add_subject_category_twice(): - category = category_helper.add_subject_category(value={"name": "category name", "description": "description 1"}) + category = category_helper.add_subject_category( + value={"name": "category name", "description": "description 1"}) category_id = list(category.keys())[0] assert category is not None with pytest.raises(SubjectCategoryExisting): category_helper.add_subject_category(category_id, - value={"name": "category name", "description": "description 2"}) + value={"name": "category name", + "description": "description 2"}) + + +def test_add_subject_category_name_space(): + with pytest.raises(CategoryNameInvalid) as exp: + category = category_helper.add_subject_category(value={"name": " ", "description": + "description 1"}) + assert exp.value.code == 400 + assert exp.value.description == 'The given category name is invalid.' def test_get_subject_categories(): @@ -34,12 +45,22 @@ def test_get_subject_categories_with_invalid_id(): def test_add_object_category_twice(): - category = category_helper.add_object_category(value={"name": "category name", "description": "description 1"}) + category = category_helper.add_object_category( + value={"name": "category name", "description": "description 1"}) category_id = list(category.keys())[0] assert category is not None with pytest.raises(ObjectCategoryExisting): category_helper.add_object_category(category_id, - value={"name": "category name", "description": "description 2"}) + value={"name": "category name", + "description": "description 2"}) + + +def test_add_object_category_name_space(): + with pytest.raises(CategoryNameInvalid) as exp: + category = category_helper.add_object_category(value={"name": " ", "description": + "description 1"}) + assert exp.value.code == 400 + assert exp.value.description == 'The given category name is invalid.' def test_get_object_categories(): @@ -57,12 +78,23 @@ def test_get_object_categories_with_invalid_id(): def test_add_action_category_twice(): - category = category_helper.add_action_category(value={"name": "category name", "description": "description 1"}) + category = category_helper.add_action_category( + value={"name": "category name", "description": "description 1"}) category_id = list(category.keys())[0] assert category is not None - with pytest.raises(ActionCategoryExisting): + with pytest.raises(ActionCategoryExisting) as exp_info: category_helper.add_action_category(category_id, - value={"name": "category name", "description": "description 2"}) + value={"name": "category name", + "description": "description 2"}) + assert str(exp_info.value)=='409: Action Category Existing' + + +def test_add_action_category_name_space(): + with pytest.raises(CategoryNameInvalid) as exp: + category = category_helper.add_action_category(value={"name": " ", "description": + "description 1"}) + assert exp.value.code == 400 + assert exp.value.description == 'The given category name is invalid.' def test_get_action_categories(): diff --git a/python_moondb/tests/unit_python/models/test_meta_rules.py b/python_moondb/tests/unit_python/models/test_meta_rules.py index 102cd724..3b2b5b0e 100644 --- a/python_moondb/tests/unit_python/models/test_meta_rules.py +++ b/python_moondb/tests/unit_python/models/test_meta_rules.py @@ -5,16 +5,88 @@ import pytest from helpers import meta_rule_helper +from helpers import policy_helper import helpers.mock_data as mock_data +import helpers.model_helper as model_helper +from python_moonutilities.exceptions import * +from uuid import uuid4 -def test_set_not_exist_meta_rule_error(db): +def test_update_not_exist_meta_rule_error(db): # set not existing meta rule and expect to raise and error - with pytest.raises(Exception) as exception_info: - meta_rule_helper.set_meta_rule(meta_rule_id=None) + with pytest.raises(MetaRuleUnknown) as exception_info: + meta_rule_helper.update_meta_rule(meta_rule_id=None) assert str(exception_info.value) == '400: Meta Rule Unknown' +def test_update_meta_rule_connected_with_policy_and_rule(): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + + value = { + "rule": (subject_data_id, object_data_id, action_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + rules = policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert rules + assert len(rules) == 1 + + action_category_id = mock_data.create_action_category("action_category_id2") + subject_category_id = mock_data.create_subject_category("subject_category_id2") + object_category_id = mock_data.create_object_category("object_category_id2") + + updated_value = { + "name": "MLS_meta_rule", + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + with pytest.raises(MetaRuleUpdateError) as exception_info: + updated_meta_rule = meta_rule_helper.update_meta_rule(meta_rule_id, updated_value) + assert str(exception_info.value) == '400: Meta_Rule Update Error' + + +def test_update_meta_rule_connected_with_policy(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + action_category_id = mock_data.create_action_category("action_category_id2") + subject_category_id = mock_data.create_subject_category("subject_category_id2") + object_category_id = mock_data.create_object_category("object_category_id2") + value = { + "name": "MLS_meta_rule", + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + meta_rules = meta_rule_helper.add_meta_rule(value=value) + assert isinstance(meta_rules, dict) + assert meta_rules + assert len(meta_rules) is 1 + meta_rule_id = list(meta_rules.keys())[0] + for key in ( + "name", "description", "subject_categories", "object_categories", "action_categories"): + assert key in meta_rules[meta_rule_id] + assert meta_rules[meta_rule_id][key] == value[key] + + def test_add_new_meta_rule_success(db): action_category_id = mock_data.create_action_category("action_category_id1") subject_category_id = mock_data.create_subject_category("subject_category_id1") @@ -31,12 +103,29 @@ def test_add_new_meta_rule_success(db): assert meta_rules assert len(meta_rules) is 1 meta_rule_id = list(meta_rules.keys())[0] - for key in ("name", "description", "subject_categories", "object_categories", "action_categories"): + for key in ( + "name", "description", "subject_categories", "object_categories", "action_categories"): assert key in meta_rules[meta_rule_id] assert meta_rules[meta_rule_id][key] == value[key] -def test_set_meta_rule_success(db): +def test_meta_rule_with_blank_name(db): + action_category_id = mock_data.create_action_category(uuid4().hex) + subject_category_id = mock_data.create_subject_category(uuid4().hex) + object_category_id = mock_data.create_object_category(uuid4().hex) + value = { + "name": "", + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + with pytest.raises(MetaRuleContentError) as exception_info: + meta_rule_helper.add_meta_rule(value=value) + assert str(exception_info.value) == '400: Meta Rule Error' + + +def test_update_meta_rule_success(db): # arrange meta_rules = meta_rule_helper.add_meta_rule() meta_rule_id = list(meta_rules.keys())[0] @@ -51,11 +140,79 @@ def test_set_meta_rule_success(db): "action_categories": [action_category_id] } # action - updated_meta_rule = meta_rule_helper.set_meta_rule(meta_rule_id, updated_value) + updated_meta_rule = meta_rule_helper.update_meta_rule(meta_rule_id, updated_value) # assert updated_meta_rule_id = list(updated_meta_rule.keys())[0] assert updated_meta_rule_id == meta_rule_id - assert updated_meta_rule[updated_meta_rule_id]["subject_categories"] == updated_value["subject_categories"] + assert updated_meta_rule[updated_meta_rule_id]["subject_categories"] == updated_value[ + "subject_categories"] + + +def test_update_meta_rule_with_existed_categories_combination(db): + action_category_id1 = mock_data.create_action_category(uuid4().hex) + subject_category_id1 = mock_data.create_subject_category(uuid4().hex) + object_category_id1 = mock_data.create_object_category(uuid4().hex) + meta_rule_name1=uuid4().hex + value1 = { + "name": meta_rule_name1, + "description": "test", + "subject_categories": [subject_category_id1], + "object_categories": [object_category_id1], + "action_categories": [action_category_id1] + } + meta_rules = meta_rule_helper.add_meta_rule(value=value1) + + action_category_id2 = mock_data.create_action_category(uuid4().hex) + subject_category_id2 = mock_data.create_subject_category(uuid4().hex) + object_category_id2 = mock_data.create_object_category(uuid4().hex) + meta_rule_name2 = uuid4().hex + value2 = { + "name": meta_rule_name2, + "description": "test", + "subject_categories": [subject_category_id2], + "object_categories": [object_category_id2], + "action_categories": [action_category_id2] + } + meta_rules = meta_rule_helper.add_meta_rule(value=value2) + meta_rule_id2 = list(meta_rules.keys())[0] + value1['name']=value2['name'] + with pytest.raises(MetaRuleExisting) as exception_info: + updated_meta_rule = meta_rule_helper.update_meta_rule(meta_rule_id2, value1) + assert str(exception_info.value) == '409: Meta Rule Existing' + assert exception_info.value.description=="Same categories combination existed" + + +def test_update_meta_rule_with_different_categories_combination_but_same_data(db): + action_category_id1 = mock_data.create_action_category(uuid4().hex) + subject_category_id1 = mock_data.create_subject_category(uuid4().hex) + object_category_id1 = mock_data.create_object_category(uuid4().hex) + meta_rule_name1=uuid4().hex + value1 = { + "name": meta_rule_name1, + "description": "test", + "subject_categories": [subject_category_id1], + "object_categories": [object_category_id1], + "action_categories": [action_category_id1] + } + meta_rules = meta_rule_helper.add_meta_rule(value=value1) + + action_category_id2 = mock_data.create_action_category(uuid4().hex) + subject_category_id2 = mock_data.create_subject_category(uuid4().hex) + object_category_id2 = mock_data.create_object_category(uuid4().hex) + meta_rule_name2 = uuid4().hex + value2 = { + "name": meta_rule_name2, + "description": "test", + "subject_categories": [subject_category_id2], + "object_categories": [object_category_id2], + "action_categories": [action_category_id2] + } + meta_rules = meta_rule_helper.add_meta_rule(value=value2) + meta_rule_id2 = list(meta_rules.keys())[0] + value1['name']=value2['name'] + value1['object_categories']+=[object_category_id1] + updated_meta_rule = meta_rule_helper.update_meta_rule(meta_rule_id2, value1) + assert meta_rule_id2 in updated_meta_rule def test_add_existing_meta_rule_error(db): @@ -71,9 +228,85 @@ def test_add_existing_meta_rule_error(db): } meta_rules = meta_rule_helper.add_meta_rule(value=value) meta_rule_id = list(meta_rules.keys())[0] - with pytest.raises(Exception) as exception_info: + with pytest.raises(MetaRuleExisting) as exception_info: meta_rule_helper.add_meta_rule(meta_rule_id=meta_rule_id) - assert str(exception_info.value) == '400: Sub Meta Rule Existing' + assert str(exception_info.value) == '409: Meta Rule Existing' + + +def test_add_meta_rule_with_existing_name_error(db): + action_category_id = mock_data.create_action_category(uuid4().hex) + subject_category_id = mock_data.create_subject_category(uuid4().hex) + object_category_id = mock_data.create_object_category(uuid4().hex) + name = uuid4().hex + value = { + "name": name, + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + meta_rule_helper.add_meta_rule(value=value) + action_category_id = mock_data.create_action_category(uuid4().hex) + subject_category_id = mock_data.create_subject_category(uuid4().hex) + object_category_id = mock_data.create_object_category(uuid4().hex) + value = { + "name": name, + "description": 'test', + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + with pytest.raises(MetaRuleExisting) as exception_info: + meta_rule_helper.add_meta_rule(value=value) + assert str(exception_info.value) == '409: Meta Rule Existing' + assert exception_info.value.description == 'The meta rule already exists.' + + +def test_add_meta_rule_with_existing_categories_combination(db): + action_category_id = mock_data.create_action_category(uuid4().hex) + subject_category_id = mock_data.create_subject_category(uuid4().hex) + object_category_id = mock_data.create_object_category(uuid4().hex) + name = uuid4().hex + value = { + "name": name, + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id], + "action_categories": [action_category_id] + } + meta_rule_helper.add_meta_rule(value=value) + value['name'] = uuid4().hex + with pytest.raises(MetaRuleExisting) as exception_info: + meta_rule_helper.add_meta_rule(value=value) + assert str(exception_info.value) == '409: Meta Rule Existing' + assert exception_info.value.description == "Same categories combination existed" + + +def test_add_meta_rule_with_different_categories_combination_but_same_data(db): + action_category_id = mock_data.create_action_category(uuid4().hex) + subject_category_id = mock_data.create_subject_category(uuid4().hex) + object_category_id1 = mock_data.create_object_category(uuid4().hex) + object_category_id2 = mock_data.create_object_category(uuid4().hex) + + name1 = uuid4().hex + value = { + "name": name1, + "description": "test", + "subject_categories": [subject_category_id], + "object_categories": [object_category_id1], + "action_categories": [action_category_id] + } + meta_rule_helper.add_meta_rule(value=value) + name2 = uuid4().hex + value['name'] = name2 + value['object_categories'] += [object_category_id2] + meta_rules = meta_rule_helper.add_meta_rule(value=value) + bool_found_meta_rule = 0 + for meta_rule_id in meta_rules: + if meta_rules[meta_rule_id]['name'] == name2: + bool_found_meta_rule = 1 + break + assert bool_found_meta_rule def test_get_meta_rule_success(db): @@ -113,7 +346,8 @@ def test_get_meta_rule_success(db): assert meta_rules assert len(meta_rules) is 2 for meta_rule_id in meta_rules: - for key in ("name", "description", "subject_categories", "object_categories", "action_categories"): + for key in ( + "name", "description", "subject_categories", "object_categories", "action_categories"): assert key in meta_rules[meta_rule_id] assert meta_rules[meta_rule_id][key] == values[meta_rule_id][key] @@ -127,7 +361,8 @@ def test_get_specific_meta_rule_success(db): meta_rule_id = list(meta_rules.keys())[0] # assert assert meta_rule_id == added_meta_rule_id - for key in ("name", "description", "subject_categories", "object_categories", "action_categories"): + for key in ( + "name", "description", "subject_categories", "object_categories", "action_categories"): assert key in meta_rules[meta_rule_id] assert meta_rules[meta_rule_id][key] == added_meta_rules[added_meta_rule_id][key] @@ -154,7 +389,15 @@ def test_delete_meta_rules_success(db): assert meta_rule_id1 not in meta_rules +def test_delete_meta_rules_with_model(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + with pytest.raises(DeleteMetaRuleWithModel) as exception_info: + meta_rule_helper.delete_meta_rules(meta_rule_id) + assert str(exception_info.value) == '400: Meta rule With Model Error' + + def test_delete_invalid_meta_rules_error(db): - with pytest.raises(Exception) as exception_info: + with pytest.raises(MetaRuleUnknown) as exception_info: meta_rule_helper.delete_meta_rules("INVALID_META_RULE_ID") assert str(exception_info.value) == '400: Meta Rule Unknown' diff --git a/python_moondb/tests/unit_python/models/test_models.py b/python_moondb/tests/unit_python/models/test_models.py index 0026345c..1b171069 100644 --- a/python_moondb/tests/unit_python/models/test_models.py +++ b/python_moondb/tests/unit_python/models/test_models.py @@ -10,6 +10,8 @@ import helpers.mock_data as mock_data import helpers.model_helper as model_helper import helpers.category_helper as category_helper import helpers.policy_helper as policy_helper +import helpers.assignment_helper as assignment_helper +from uuid import uuid4 logger = logging.getLogger("moon.db.tests.test_model") @@ -83,7 +85,7 @@ def test_add_same_model_twice(db): with pytest.raises(ModelExisting) as exception_info: model_helper.add_model(model_id="model_1", value=value) model_helper.delete_all_models() - # assert str(exception_info.value) == '409: Model Error' + assert str(exception_info.value) == '409: Model Error' def test_add_model_generate_new_uuid(db): @@ -148,9 +150,34 @@ def test_add_models_with_same_name_twice(db): models = model_helper.add_model(value=model_value1) assert isinstance(models, dict) assert models - with pytest.raises(Exception) as exc_info: + with pytest.raises(Exception) as exception_info: model_helper.add_model(value=model_value1) model_helper.delete_all_models() + assert str(exception_info.value) == '409: Model Error' + +def test_add_model_with_existed_meta_rules_list(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id = mock_data.create_new_meta_rule( + subject_category_name=uuid4().hex, + object_category_name=uuid4().hex, + action_category_name=uuid4().hex) + model_value1 = { + "name": uuid4().hex, + "description": "test", + "meta_rules": [meta_rule_id] + } + models = model_helper.add_model(value=model_value1) + assert isinstance(models, dict) + assert models + model_value1 = { + "name": uuid4().hex, + "description": "test", + "meta_rules": [meta_rule_id] + } + with pytest.raises(Exception) as exception_info: + model_helper.add_model(value=model_value1) + model_helper.delete_all_models() + assert str(exception_info.value) == '409: Model Error' + assert str(exception_info.value.description)=='Meta Rules List Existed in another Model' def test_delete_models(db): @@ -240,6 +267,7 @@ def test_delete_model_assigned_to_policy(db): policy_helper.add_policies(value=value) with pytest.raises(DeleteModelWithPolicy) as exception_info: model_helper.delete_models(uuid=model_id) + assert str(exception_info.value) == '400: Model With Policy Error' def test_add_subject_category(db): @@ -253,13 +281,32 @@ def test_add_subject_category(db): assert len(subject_category) == 1 +def test_add_subject_categories_with_existed_name(db): + name = uuid4().hex + value = { + "name": name, + "description": "description subject_category" + } + subject_category = category_helper.add_subject_category(value=value) + assert subject_category + assert len(subject_category) == 1 + + value = { + "name": name, + "description": "description subject_category" + } + with pytest.raises(SubjectCategoryExisting) as exception_info: + category_helper.add_subject_category(value=value) + assert str(exception_info.value) == '409: Subject Category Existing' + + def test_add_subject_category_with_empty_name(db): category_id = "category_id1" value = { "name": "", "description": "description subject_category" } - with pytest.raises(Exception) as exception_info: + with pytest.raises(CategoryNameInvalid) as exception_info: category_helper.add_subject_category(category_id, value) assert str(exception_info.value) == '400: Category Name Invalid' @@ -271,7 +318,7 @@ def test_add_subject_category_with_same_category_id(db): "description": "description subject_category" } category_helper.add_subject_category(category_id, value) - with pytest.raises(Exception) as exception_info: + with pytest.raises(SubjectCategoryExisting) as exception_info: category_helper.add_subject_category(category_id, value) assert str(exception_info.value) == '409: Subject Category Existing' @@ -299,10 +346,41 @@ def test_delete_subject_category(db): assert not subject_category +def test_delete_subject_category_with_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + mock_data.create_subject_data(policy_id, subject_category_id) + + with pytest.raises(DeleteSubjectCategoryWithMetaRule) as exception_info: + category_helper.delete_subject_category(subject_category_id) + assert str(exception_info.value) == '400: Subject Category With Meta Rule Error' + + +def test_delete_subject_category_with_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + subject_id = mock_data.create_subject(policy_id) + data_id = mock_data.create_subject_data(policy_id, subject_category_id) + assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id) + + with pytest.raises(DeleteSubjectCategoryWithMetaRule) as exception_info: + category_helper.delete_subject_category(subject_category_id) + assert str(exception_info.value) == '400: Subject Category With Meta Rule Error' + + +def test_delete_subject_category_with_rule(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id) + + with pytest.raises(DeleteSubjectCategoryWithMetaRule) as exception_info: + category_helper.delete_subject_category(subject_category_id) + assert str(exception_info.value) == '400: Subject Category With Meta Rule Error' + + def test_delete_subject_category_with_unkown_category_id(db): category_id = "invalid_category_id" - with pytest.raises(Exception) as exception_info: + with pytest.raises(SubjectCategoryUnknown) as exception_info: category_helper.delete_subject_category(category_id) assert str(exception_info.value) == '400: Subject Category Unknown' @@ -318,6 +396,20 @@ def test_add_object_category(db): assert len(object_category) == 1 +def test_add_object_categories_with_existed_name(db): + name = uuid4().hex + value = { + "name": name, + "description": "description object_category" + } + object_category = category_helper.add_object_category(value=value) + assert object_category + assert len(object_category) == 1 + with pytest.raises(ObjectCategoryExisting) as exception_info: + category_helper.add_object_category(value=value) + assert str(exception_info.value) == '409: Object Category Existing' + + def test_add_object_category_with_same_category_id(db): category_id = "category_id1" value = { @@ -325,7 +417,7 @@ def test_add_object_category_with_same_category_id(db): "description": "description object_category" } category_helper.add_object_category(category_id, value) - with pytest.raises(Exception) as exception_info: + with pytest.raises(ObjectCategoryExisting) as exception_info: category_helper.add_object_category(category_id, value) assert str(exception_info.value) == '409: Object Category Existing' @@ -336,7 +428,7 @@ def test_add_object_category_with_empty_name(db): "name": "", "description": "description object_category" } - with pytest.raises(Exception) as exception_info: + with pytest.raises(CategoryNameInvalid) as exception_info: category_helper.add_object_category(category_id, value) assert str(exception_info.value) == '400: Category Name Invalid' @@ -364,10 +456,42 @@ def test_delete_object_category(db): assert not object_category +def test_delete_object_category_with_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + mock_data.create_subject_data(policy_id, subject_category_id) + + mock_data.create_object_data(policy_id, object_category_id) + + with pytest.raises(DeleteObjectCategoryWithMetaRule) as exception_info: + category_helper.delete_object_category(object_category_id) + assert str(exception_info.value) == '400: Object Category With Meta Rule Error' + + +def test_delete_object_category_with_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + object_id = mock_data.create_object(policy_id) + data_id = mock_data.create_object_data(policy_id, object_category_id) + assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) + + with pytest.raises(DeleteObjectCategoryWithMetaRule) as exception_info: + category_helper.delete_object_category(object_category_id) + assert str(exception_info.value) == '400: Object Category With Meta Rule Error' + + +def test_delete_object_category_with_rule(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id) + + with pytest.raises(DeleteObjectCategoryWithMetaRule) as exception_info: + category_helper.delete_object_category(object_category_id) + assert str(exception_info.value) == '400: Object Category With Meta Rule Error' + + def test_delete_object_category_with_unkown_category_id(db): category_id = "invalid_category_id" - with pytest.raises(Exception) as exception_info: + with pytest.raises(ObjectCategoryUnknown) as exception_info: category_helper.delete_object_category(category_id) assert str(exception_info.value) == '400: Object Category Unknown' @@ -383,6 +507,20 @@ def test_add_action_category(db): assert len(action_category) == 1 +def test_add_action_categories_with_existed_name(db): + name = uuid4().hex + value = { + "name": name, + "description": "description action_category" + } + action_category = category_helper.add_action_category(value=value) + assert action_category + assert len(action_category) == 1 + with pytest.raises(ActionCategoryExisting) as exception_info: + category_helper.add_action_category(value=value) + assert str(exception_info.value) == '409: Action Category Existing' + + def test_add_action_category_with_same_category_id(db): category_id = "category_id1" value = { @@ -390,7 +528,7 @@ def test_add_action_category_with_same_category_id(db): "description": "description action_category" } category_helper.add_action_category(category_id, value) - with pytest.raises(Exception) as exception_info: + with pytest.raises(ActionCategoryExisting) as exception_info: category_helper.add_action_category(category_id, value) assert str(exception_info.value) == '409: Action Category Existing' @@ -401,7 +539,7 @@ def test_add_action_category_with_empty_name(db): "name": "", "description": "description action_category" } - with pytest.raises(Exception) as exception_info: + with pytest.raises(CategoryNameInvalid) as exception_info: category_helper.add_action_category(category_id, value) assert str(exception_info.value) == '400: Category Name Invalid' @@ -429,9 +567,56 @@ def test_delete_action_category(db): assert not action_category +def test_delete_action_category_with_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + mock_data.create_subject_data(policy_id, subject_category_id) + + mock_data.create_action_data(policy_id, action_category_id) + + with pytest.raises(DeleteActionCategoryWithMetaRule) as exception_info: + category_helper.delete_action_category(action_category_id) + assert str(exception_info.value) == '400: Action Category With Meta Rule Error' + + +def test_delete_action_category_with_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + action_id = mock_data.create_action(policy_id) + data_id = mock_data.create_action_data(policy_id, action_category_id) + assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id) + + with pytest.raises(DeleteActionCategoryWithMetaRule) as exception_info: + category_helper.delete_action_category(action_category_id) + assert str(exception_info.value) == '400: Action Category With Meta Rule Error' + + +def test_delete_action_category_with_rule(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id) + + with pytest.raises(DeleteActionCategoryWithMetaRule) as exception_info: + category_helper.delete_action_category(action_category_id) + assert str(exception_info.value) == '400: Action Category With Meta Rule Error' + + def test_delete_action_category_with_unkown_category_id(db): category_id = "invalid_category_id" - with pytest.raises(Exception) as exception_info: + with pytest.raises(ActionCategoryUnknown) as exception_info: category_helper.delete_action_category(category_id) assert str(exception_info.value) == '400: Action Category Unknown' + + +def test_delete_data_categories_connected_to_meta_rule(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + with pytest.raises(DeleteSubjectCategoryWithMetaRule) as exception_info: + category_helper.delete_subject_category(subject_category_id) + assert str(exception_info.value) == '400: Subject Category With Meta Rule Error' + + with pytest.raises(DeleteObjectCategoryWithMetaRule) as exception_info: + category_helper.delete_object_category(object_category_id) + assert str(exception_info.value) == '400: Object Category With Meta Rule Error' + + with pytest.raises(DeleteActionCategoryWithMetaRule) as exception_info: + category_helper.delete_action_category(action_category_id) + assert str(exception_info.value) == '400: Action Category With Meta Rule Error' diff --git a/python_moondb/tests/unit_python/policies/test_assignments.py b/python_moondb/tests/unit_python/policies/test_assignments.py index 675c2ff9..24a3a7b0 100755 --- a/python_moondb/tests/unit_python/policies/test_assignments.py +++ b/python_moondb/tests/unit_python/policies/test_assignments.py @@ -19,7 +19,8 @@ def test_get_action_assignments(db): data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id) assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id) - act_assignments = assignment_helper.get_action_assignments(policy_id, action_id, action_category_id) + act_assignments = assignment_helper.get_action_assignments(policy_id, action_id, + action_category_id) action_id_1 = list(act_assignments.keys())[0] assert act_assignments[action_id_1]["policy_id"] == policy_id assert act_assignments[action_id_1]["action_id"] == action_id @@ -36,7 +37,8 @@ def test_add_action_assignments(db): meta_rule_name="meta_rule_1") action_id = mock_data.create_action(policy_id) data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id) - action_assignments = assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id) + action_assignments = assignment_helper.add_action_assignment(policy_id, action_id, + action_category_id, data_id) assert action_assignments action_id_1 = list(action_assignments.keys())[0] assert action_assignments[action_id_1]["policy_id"] == policy_id @@ -47,6 +49,8 @@ def test_add_action_assignments(db): with pytest.raises(ActionAssignmentExisting) as exception_info: assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id) + assert str(exception_info.value) == '409: Action Assignment Existing' + assert str(exception_info.value.description) == 'The given action assignment value is existing.' def test_delete_action_assignment(db): @@ -79,7 +83,8 @@ def test_get_object_assignments(db): object_id = mock_data.create_object(policy_id) data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id) assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) - obj_assignments = assignment_helper.get_object_assignments(policy_id, object_id, object_category_id) + obj_assignments = assignment_helper.get_object_assignments(policy_id, object_id, + object_category_id) object_id_1 = list(obj_assignments.keys())[0] assert obj_assignments[object_id_1]["policy_id"] == policy_id assert obj_assignments[object_id_1]["object_id"] == object_id @@ -109,7 +114,8 @@ def test_add_object_assignments(db): meta_rule_name="meta_rule_1") object_id = mock_data.create_object(policy_id) data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id) - object_assignments = assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) + object_assignments = assignment_helper.add_object_assignment(policy_id, object_id, + object_category_id, data_id) assert object_assignments object_id_1 = list(object_assignments.keys())[0] assert object_assignments[object_id_1]["policy_id"] == policy_id @@ -118,8 +124,10 @@ def test_add_object_assignments(db): assert len(object_assignments[object_id_1].get("assignments")) == 1 assert data_id in object_assignments[object_id_1].get("assignments") - with pytest.raises(ObjectAssignmentExisting): + with pytest.raises(ObjectAssignmentExisting) as exception_info: assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) + assert str(exception_info.value) == '409: Object Assignment Existing' + assert str(exception_info.value.description) == 'The given object assignment value is existing.' def test_delete_object_assignment(db): @@ -132,7 +140,8 @@ def test_delete_object_assignment(db): data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id) assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) - assignment_helper.delete_object_assignment(policy_id, object_id, object_category_id, data_id=data_id) + assignment_helper.delete_object_assignment(policy_id, object_id, object_category_id, + data_id=data_id) assignments = assignment_helper.get_object_assignments(policy_id) assert len(assignments) == 0 @@ -154,7 +163,8 @@ def test_get_subject_assignments(db): data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id) assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id) - subj_assignments = assignment_helper.get_subject_assignments(policy_id, subject_id, subject_category_id) + subj_assignments = assignment_helper.get_subject_assignments(policy_id, subject_id, + subject_category_id) subject_id_1 = list(subj_assignments.keys())[0] assert subj_assignments[subject_id_1]["policy_id"] == policy_id assert subj_assignments[subject_id_1]["subject_id"] == subject_id @@ -186,7 +196,8 @@ def test_add_subject_assignments(db): subject_id = mock_data.create_subject(policy_id) data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id) - subject_assignments = assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id) + subject_assignments = assignment_helper.add_subject_assignment(policy_id, subject_id, + subject_category_id, data_id) assert subject_assignments subject_id_1 = list(subject_assignments.keys())[0] assert subject_assignments[subject_id_1]["policy_id"] == policy_id @@ -195,8 +206,12 @@ def test_add_subject_assignments(db): assert len(subject_assignments[subject_id_1].get("assignments")) == 1 assert data_id in subject_assignments[subject_id_1].get("assignments") - with pytest.raises(SubjectAssignmentExisting): - assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id) + with pytest.raises(SubjectAssignmentExisting) as exception_info: + assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, + data_id) + assert str(exception_info.value) == '409: Subject Assignment Existing' + assert str( + exception_info.value.description) == 'The given subject assignment value is existing.' def test_delete_subject_assignment(db): diff --git a/python_moondb/tests/unit_python/policies/test_data.py b/python_moondb/tests/unit_python/policies/test_data.py index fa3f8c06..8ce1ac00 100755 --- a/python_moondb/tests/unit_python/policies/test_data.py +++ b/python_moondb/tests/unit_python/policies/test_data.py @@ -6,7 +6,9 @@ import helpers.mock_data as mock_data import policies.mock_data import helpers.data_helper as data_helper +import helpers.assignment_helper as assignment_helper import pytest +from uuid import uuid4 import logging from python_moonutilities.exceptions import * @@ -56,6 +58,21 @@ def test_add_action_data(db): assert len(action_data['data']) == 1 +def test_add_action_data_duplicate(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1") + value = { + "name": "action-type", + "description": {"vm-action": "", "storage-action": "", }, + } + action_data = data_helper.add_action_data(policy_id=policy_id, category_id=action_category_id, value=value) + with pytest.raises(ActionScopeExisting) as exception_info: + action_data = data_helper.add_action_data(policy_id=policy_id, category_id=action_category_id, value=value) + assert str(exception_info.value) == '409: Action Scope Existing' + def test_add_action_data_with_invalid_category_id(db): subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( subject_category_name="subject_category1", @@ -66,9 +83,9 @@ def test_add_action_data_with_invalid_category_id(db): "name": "action-type", "description": {"vm-action": "", "storage-action": "", }, } - with pytest.raises(Exception) as exception_info: + with pytest.raises(ActionCategoryUnknown) as exception_info: data_helper.add_action_data(policy_id=policy_id, value=value).get('data') - assert str(exception_info.value) == 'Invalid category id' + assert str(exception_info.value) == '400: Action Category Unknown' def test_delete_action_data(db): @@ -84,7 +101,7 @@ def test_delete_action_data(db): } action_data = data_helper.add_action_data(policy_id=policy_id, category_id=action_category_id, value=value) data_id = list(action_data["data"])[0] - data_helper.delete_action_data(policy_id, data_id) + data_helper.delete_action_data(policy_id=policy_id, data_id=data_id) new_action_data = data_helper.get_action_data(policy_id) assert len(new_action_data[0]['data']) == 0 @@ -144,9 +161,27 @@ def test_add_object_data_with_invalid_category_id(db): "name": "object-security-level", "description": {"low": "", "medium": "", "high": ""}, } - with pytest.raises(MetaDataUnknown) as exception_info: + with pytest.raises(ObjectCategoryUnknown) as exception_info: data_helper.add_object_data(policy_id=policy_id, category_id="invalid", value=value).get('data') - assert str(exception_info.value) == '400: Meta data Unknown' + assert str(exception_info.value) == '400: Object Category Unknown' + + +def test_add_object_data_duplicate(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1") + value = { + "name": "object-security-level", + "description": {"low": "", "medium": "", "high": ""}, + } + object_data = data_helper.add_object_data(policy_id=policy_id, category_id=object_category_id, value=value).get( + 'data') + with pytest.raises(ObjectScopeExisting) as exception_info: + data_helper.add_object_data(policy_id=policy_id, category_id=object_category_id, value=value).get( + 'data') + assert str(exception_info.value) == '409: Object Scope Existing' def test_delete_object_data(db): @@ -229,9 +264,28 @@ def test_add_subject_data_with_no_category_id(db): "name": "subject-security-level", "description": {"low": "", "medium": "", "high": ""}, } - with pytest.raises(Exception) as exception_info: + with pytest.raises(SubjectCategoryUnknown) as exception_info: data_helper.add_subject_data(policy_id=policy_id, data_id=subject_category_id, value=value).get('data') - assert str(exception_info.value) == 'Invalid category id' + assert str(exception_info.value) == '400: Subject Category Unknown' + + +def test_add_subject_data_duplicate(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1") + value = { + "name": "subject-security-level", + "description": {"low": "", "medium": "", "high": ""}, + } + subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, value=value).get( + 'data') + + with pytest.raises(SubjectScopeExisting) as exception_info: + subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, + value=value).get('data') + assert str(exception_info.value) == '409: Subject Scope Existing' def test_delete_subject_data(db): @@ -247,7 +301,7 @@ def test_delete_subject_data(db): subject_data = data_helper.add_subject_data(policy_id=policy_id, category_id=subject_category_id, value=value).get( 'data') subject_data_id = list(subject_data.keys())[0] - data_helper.delete_subject_data(subject_data[subject_data_id].get('policy_id'), subject_data_id) + data_helper.delete_subject_data(policy_id=subject_data[subject_data_id].get('policy_id'), data_id=subject_data_id) new_subject_data = data_helper.get_subject_data(policy_id) assert len(new_subject_data[0]['data']) == 0 @@ -297,8 +351,9 @@ def test_add_action_twice(db): "description": "test", } data_helper.add_action(policy_id=policy_id, value=value) - with pytest.raises(ActionExisting): + with pytest.raises(PolicyExisting) as exception_info: data_helper.add_action(policy_id=policy_id, value=value) + assert str(exception_info.value) == '409: Policy Already Exists' def test_add_action_blank_name(db): @@ -307,9 +362,9 @@ def test_add_action_blank_name(db): "name": "", "description": "test", } - with pytest.raises(Exception) as exception_info: + with pytest.raises(PerimeterContentError) as exception_info: data_helper.add_action(policy_id=policy_id, value=value) - assert str(exception_info.value) == '400: Perimeter Name is Invalid' + assert str(exception_info.value) == '400: Perimeter content is invalid.' def test_add_action_with_name_space(db): @@ -318,9 +373,9 @@ def test_add_action_with_name_space(db): "name": " ", "description": "test", } - with pytest.raises(Exception) as exception_info: + with pytest.raises(PerimeterContentError) as exception_info: data_helper.add_action(policy_id=policy_id, value=value) - assert str(exception_info.value) == '400: Perimeter Name is Invalid' + assert str(exception_info.value) == '400: Perimeter content is invalid.' def test_add_action_multiple_times(db): @@ -377,7 +432,7 @@ def test_delete_action(db): def test_delete_action_with_invalid_perimeter_id(db): policy_id = "invalid" perimeter_id = "invalid" - with pytest.raises(Exception) as exception_info: + with pytest.raises(PolicyUnknown) as exception_info: data_helper.delete_action(policy_id, perimeter_id) assert str(exception_info.value) == '400: Policy Unknown' @@ -400,7 +455,7 @@ def test_get_objects(db): assert objects[object_id].get('policy_list')[0] == policy_id -def test_add_object(db): +def test_add_object_with_same_policy_twice(db): subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( subject_category_name="subject_category1", object_category_name="object_category1", @@ -415,8 +470,9 @@ def test_add_object(db): object_id = list(added_object.keys())[0] assert len(added_object[object_id].get('policy_list')) == 1 - with pytest.raises(ObjectExisting): + with pytest.raises(PolicyExisting) as exception_info: data_helper.add_object(policy_id=policy_id, value=value) + assert str(exception_info.value) == '409: Policy Already Exists' def test_add_objects_multiple_times(db): @@ -470,7 +526,7 @@ def test_delete_object(db): def test_delete_object_with_invalid_perimeter_id(db): policy_id = "invalid" perimeter_id = "invalid" - with pytest.raises(Exception) as exception_info: + with pytest.raises(PolicyUnknown) as exception_info: data_helper.delete_object(policy_id, perimeter_id) assert str(exception_info.value) == '400: Policy Unknown' @@ -504,11 +560,12 @@ def test_get_subjects_with_invalid_policy_id(db): "description": "test", } data_helper.add_subject(policy_id=policy_id, value=value) - with pytest.raises(PolicyUnknown): + with pytest.raises(PolicyUnknown) as exception_info: data_helper.get_subjects(policy_id="invalid") + assert str(exception_info.value) == '400: Policy Unknown' -def test_add_subject(db): +def test_add_subject_with_same_policy_twice(db): subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( subject_category_name="subject_category1", object_category_name="object_category1", @@ -522,9 +579,9 @@ def test_add_subject(db): assert subject subject_id = list(subject.keys())[0] assert len(subject[subject_id].get('policy_list')) == 1 - with pytest.raises(SubjectExisting) as exception_info: + with pytest.raises(PolicyExisting) as exception_info: data_helper.add_subject(policy_id=policy_id, value=value) - assert str(exception_info.value) == '409: Subject Existing' + assert str(exception_info.value) == '409: Policy Already Exists' def test_add_subjects_multiple_times(db): @@ -578,11 +635,59 @@ def test_delete_subject(db): def test_delete_subject_with_invalid_perimeter_id(db): policy_id = "invalid" perimeter_id = "invalid" - with pytest.raises(Exception) as exception_info: + with pytest.raises(PolicyUnknown) as exception_info: data_helper.delete_subject(policy_id, perimeter_id) assert str(exception_info.value) == '400: Policy Unknown' +def test_delete_subject_with_assignment(db): + + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category"+uuid4().hex, + object_category_name="object_category"+uuid4().hex, + action_category_name="action_category"+uuid4().hex, + meta_rule_name="meta_rule_"+uuid4().hex) + + subject_id = mock_data.create_subject(policy_id) + data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id) + assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id) + + with pytest.raises(DeletePerimeterWithAssignment) as exception_info: + data_helper.delete_subject(policy_id, subject_id) + assert '400: Perimeter With Assignment Error' == str(exception_info.value) + + +def test_delete_object_with_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category" + uuid4().hex, + object_category_name="object_category" + uuid4().hex, + action_category_name="action_category" + uuid4().hex, + meta_rule_name="meta_rule_" + uuid4().hex) + + object_id = mock_data.create_object(policy_id) + data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id) + assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) + + with pytest.raises(DeletePerimeterWithAssignment) as exception_info: + data_helper.delete_object(policy_id, object_id) + assert '400: Perimeter With Assignment Error' == str(exception_info.value) + +def test_delete_action_with_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category" + uuid4().hex, + object_category_name="object_category" + uuid4().hex, + action_category_name="action_category" + uuid4().hex, + meta_rule_name="meta_rule_" + uuid4().hex) + + action_id = mock_data.create_action(policy_id) + data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id) + assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id) + + with pytest.raises(DeletePerimeterWithAssignment) as exception_info: + data_helper.delete_action(policy_id, action_id) + assert '400: Perimeter With Assignment Error' == str(exception_info.value) + + def test_get_available_metadata(db): subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( subject_category_name="subject_category1", @@ -597,6 +702,6 @@ def test_get_available_metadata(db): def test_get_available_metadata_with_invalid_policy_id(db): - with pytest.raises(Exception) as exception_info: + with pytest.raises(PolicyUnknown) as exception_info: data_helper.get_available_metadata(policy_id='invalid') assert '400: Policy Unknown' == str(exception_info.value) diff --git a/python_moondb/tests/unit_python/policies/test_policies.py b/python_moondb/tests/unit_python/policies/test_policies.py index 07ee87fd..b2394203 100755 --- a/python_moondb/tests/unit_python/policies/test_policies.py +++ b/python_moondb/tests/unit_python/policies/test_policies.py @@ -6,8 +6,13 @@ import pytest import helpers.mock_data as mock_data import helpers.policy_helper as policy_helper +import helpers.model_helper as model_helper +import helpers.model_helper as model_helper from python_moonutilities.exceptions import * import helpers.pdp_helper as pdp_helper +import helpers.data_helper as data_helper +import helpers.assignment_helper as assignment_helper +from uuid import uuid4 def test_get_policies(db): @@ -17,9 +22,11 @@ def test_get_policies(db): def test_add_policies(db): + model = model_helper.add_model(model_id=uuid4().hex) + model_id = next(iter(model)) value = { "name": "test_policy", - "model_id": "", + "model_id": model_id, "genre": "authz", "description": "test", } @@ -35,43 +42,53 @@ def test_add_policies(db): def test_add_policies_twice_with_same_id(db): policy_id = 'policy_id_1' + model = model_helper.add_model(model_id=uuid4().hex) + model_id = next(iter(model)) value = { "name": "test_policy", - "model_id": "", + "model_id": model_id, "genre": "authz", "description": "test", } policy_helper.add_policies(policy_id, value) with pytest.raises(PolicyExisting) as exception_info: policy_helper.add_policies(policy_id, value) - # assert str(exception_info.value) == '409: Policy Error' + assert str(exception_info.value) == '409: Policy Already Exists' def test_add_policies_twice_with_same_name(db): + model = model_helper.add_model(model_id=uuid4().hex) + model_id = next(iter(model)) + policy_name=uuid4().hex value = { - "name": "test_policy", - "model_id": "", + "name": policy_name, + "model_id": model_id, "genre": "authz", "description": "test", } policy_helper.add_policies(value=value) with pytest.raises(Exception) as exception_info: policy_helper.add_policies(value=value) - # assert str(exception_info.value) == '409: Policy Error' + assert str(exception_info.value) == '409: Policy Already Exists' + assert str(exception_info.value.description)== 'Policy name Existed' def test_delete_policies(db): + model = model_helper.add_model(model_id=uuid4().hex) + model_id = next(iter(model)) + policy_name1 = uuid4().hex value = { - "name": "test_policy1", - "model_id": "", + "name": policy_name1, + "model_id": model_id, "genre": "authz", "description": "test", } policies = policy_helper.add_policies(value=value) policy_id1 = list(policies.keys())[0] + policy_name2 = uuid4().hex value = { - "name": "test_policy2", - "model_id": "", + "name": policy_name2, + "model_id": model_id, "genre": "authz", "description": "test", } @@ -95,7 +112,7 @@ def test_update_policy(db): policy_id = list(policies.keys())[0] value = { "name": "test_policy4", - "model_id": "", + "model_id": policies[policy_id]['model_id'], "genre": "authz", "description": "test-3", } @@ -106,6 +123,24 @@ def test_update_policy(db): assert updated_policy[policy_id][key] == value[key] +def test_update_policy_name_with_existed_one(db): + policies = policy_helper.add_policies() + policy_id1 = list(policies.keys())[0] + policy_name = uuid4().hex + value = { + "name": policy_name, + "model_id": policies[policy_id1]['model_id'], + "genre": "authz", + "description": "test-3", + } + policy_helper.add_policies(value=value) + with pytest.raises(PolicyExisting) as exception_info: + policy_helper.update_policy(policy_id=policy_id1,value=value) + + assert str(exception_info.value) == '409: Policy Already Exists' + assert str(exception_info.value.description)== 'Policy name Existed' + + def test_update_policy_with_invalid_id(db): policy_id = 'invalid-id' value = { @@ -116,7 +151,7 @@ def test_update_policy_with_invalid_id(db): } with pytest.raises(PolicyUnknown) as exception_info: policy_helper.update_policy(policy_id, value) - # assert str(exception_info.value) == '400: Policy Unknown' + assert str(exception_info.value) == '400: Policy Unknown' def test_get_policy_from_meta_rules(db): @@ -154,18 +189,10 @@ def test_get_rules(db): action_category_name="action_category12", meta_rule_name="meta_rule_12", model_name="model12") - value = { - "rule": ("low", "medium", "vm-action"), - "instructions": ({"decision": "grant"}), - "enabled": "", - } - policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) - value = { - "rule": ("low", "low", "vm-action"), - "instructions": ({"decision": "grant"}), - "enabled": "", - } - policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id) + + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id) rules = policy_helper.get_rules(policy_id=policy_id, meta_rule_id=meta_rule_id) assert isinstance(rules, dict) assert rules @@ -179,15 +206,22 @@ def test_get_rules_with_invalid_policy_id_failure(db): assert len(rules.get('rules')) == 0 -def test_add_rule(db): +def test_add_rule_existing(db): subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( subject_category_name="subject_category1", object_category_name="object_category1", action_category_name="action_category1", meta_rule_name="meta_rule_1", model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { - "rule": ("high", "medium", "vm-action"), + "rule": (subject_data_id, object_data_id, action_data_id), "instructions": ({"decision": "grant"}), "enabled": "", } @@ -201,23 +235,263 @@ def test_add_rule(db): assert key in rules[rule_id] assert rules[rule_id][key] == value[key] - with pytest.raises(RuleExisting): + with pytest.raises(RuleExisting) as exception_info: policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '409: Rule Existing' -def test_delete_rule(db): +def test_check_existing_rule_valid_request(db): subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( - subject_category_name="subject_category14", - object_category_name="object_category14", - action_category_name="action_category14", - meta_rule_name="meta_rule_14", - model_name="model14") + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) value = { - "rule": ("low", "low", "vm-action"), + "rule": (subject_data_id, object_data_id, action_data_id), "instructions": ({"decision": "grant"}), "enabled": "", } - rules = policy_helper.add_rule(policy_id, meta_rule_id, value) + + rules = policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert rules + assert len(rules) == 1 + assert isinstance(rules, dict) + rule_id = list(rules.keys())[0] + for key in ("rule", "instructions", "enabled"): + assert key in rules[rule_id] + assert rules[rule_id][key] == value[key] + + with pytest.raises(RuleExisting) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '409: Rule Existing' + + +def test_check_existing_rule_valid_multiple__data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id1 = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + subject_data_id2 = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id1 = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + object_data_id2 = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id1 = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + action_data_id2 = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": ( + subject_data_id1, object_data_id2, action_data_id1), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + rules = policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert rules + assert len(rules) == 1 + assert isinstance(rules, dict) + rule_id = list(rules.keys())[0] + for key in ("rule", "instructions", "enabled"): + assert key in rules[rule_id] + assert rules[rule_id][key] == value[key] + + with pytest.raises(RuleExisting) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '409: Rule Existing' + + +def test_check_existing_rule_missing_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (object_data_id, action_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(RuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Rule Error' + assert exception_info.value.description== "Missing Data" + + +def test_check_existing_rule_meta_rule_missing_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (subject_data_id, object_data_id, action_data_id, action_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(MetaRuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Meta Rule Error' + assert exception_info.value.description == "Missing Data" + + +def test_check_existing_rule_invalid_data_id_order(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (object_data_id, action_data_id, subject_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(RuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Rule Error' + assert "Missing Subject_category" in exception_info.value.description + + +def test_check_existing_rule_invalid_data_id_order_scenrio_2(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (subject_data_id, action_data_id, object_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(RuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Rule Error' + assert "Missing Object_category" in exception_info.value.description + + +def test_check_existing_rule_wrong_subject_data_id(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (uuid4().hex, object_data_id, action_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(RuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Rule Error' + assert "Missing Subject_category" in exception_info.value.description + + +def test_check_existing_rule_wrong_object_data_id(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (subject_data_id, uuid4().hex, action_data_id), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(RuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Rule Error' + assert "Missing Object_category" in exception_info.value.description + + +def test_check_existing_rule_wrong_action_data_id(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy( + subject_category_name="subject_category1", + object_category_name="object_category1", + action_category_name="action_category1", + meta_rule_name="meta_rule_1", + model_name="model1") + subject_data_id = mock_data.create_subject_data(policy_id=policy_id, + category_id=subject_category_id) + object_data_id = mock_data.create_object_data(policy_id=policy_id, + category_id=object_category_id) + action_data_id = mock_data.create_action_data(policy_id=policy_id, + category_id=action_category_id) + value = { + "rule": (subject_data_id, object_data_id, uuid4().hex), + "instructions": ({"decision": "grant"}), + "enabled": "", + } + + with pytest.raises(RuleContentError) as exception_info: + policy_helper.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + assert str(exception_info.value) == '400: Rule Error' + assert "Missing Action_category" in exception_info.value.description + + +def test_delete_rule(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + rules = policy_helper.add_rule(policy_id, meta_rule_id) rule_id = list(rules.keys())[0] policy_helper.delete_rule(policy_id, rule_id) rules = policy_helper.get_rules(policy_id, meta_rule_id) @@ -225,13 +499,7 @@ def test_delete_rule(db): def test_delete_policies_with_pdp(db): - value = { - "name": "test_policy1", - "model_id": "", - "genre": "authz", - "description": "test", - } - policies = policy_helper.add_policies(value=value) + policies = policy_helper.add_policies() policy_id1 = list(policies.keys())[0] pdp_id = "pdp_id1" value = { @@ -243,3 +511,133 @@ def test_delete_policies_with_pdp(db): pdp_helper.add_pdp(pdp_id=pdp_id, value=value) with pytest.raises(DeletePolicyWithPdp) as exception_info: policy_helper.delete_policies(policy_id1) + assert str(exception_info.value) == '400: Policy With PDP Error' + assert 'Cannot delete policy with pdp' == exception_info.value.description + + +def test_delete_policies_with_subject_perimeter(db): + policies = policy_helper.add_policies() + policy_id1 = list(policies.keys())[0] + + value = { + "name": "testuser", + "security_pipeline": [policy_id1], + "keystone_project_id": "keystone_project_id1", + "description": "...", + } + data_helper.add_subject(policy_id=policy_id1, value=value) + with pytest.raises(DeletePolicyWithPerimeter) as exception_info: + policy_helper.delete_policies(policy_id1) + assert str(exception_info.value) == '400: Policy With Perimeter Error' + assert 'Cannot delete policy with perimeter'== exception_info.value.description + + +def test_delete_policies_with_object_perimeter(db): + policies = policy_helper.add_policies() + policy_id1 = list(policies.keys())[0] + + value = { + "name": "test_obj", + "security_pipeline": [policy_id1], + "keystone_project_id": "keystone_project_id1", + "description": "...", + } + data_helper.add_object(policy_id=policy_id1, value=value) + with pytest.raises(DeletePolicyWithPerimeter) as exception_info: + policy_helper.delete_policies(policy_id1) + assert str(exception_info.value) == '400: Policy With Perimeter Error' + assert 'Cannot delete policy with perimeter'== exception_info.value.description + + +def test_delete_policies_with_action_perimeter(db): + policies = policy_helper.add_policies() + policy_id1 = list(policies.keys())[0] + + value = { + "name": "test_act", + "security_pipeline": [policy_id1], + "keystone_project_id": "keystone_project_id1", + "description": "...", + } + data_helper.add_action(policy_id=policy_id1, value=value) + with pytest.raises(DeletePolicyWithPerimeter) as exception_info: + policy_helper.delete_policies(policy_id1) + assert '400: Policy With Perimeter Error' == str(exception_info.value) + + +def test_delete_policies_with_subject_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + subject_id = mock_data.create_subject(policy_id) + data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id) + assignment_helper.add_subject_assignment(policy_id, subject_id, subject_category_id, data_id) + + with pytest.raises(DeletePolicyWithPerimeter) as exception_info: + policy_helper.delete_policies(policy_id) + + assert '400: Policy With Perimeter Error' == str(exception_info.value) + + +def test_delete_policies_with_object_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + object_id = mock_data.create_object(policy_id) + data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id) + assignment_helper.add_object_assignment(policy_id, object_id, object_category_id, data_id) + + with pytest.raises(DeletePolicyWithPerimeter) as exception_info: + policy_helper.delete_policies(policy_id) + assert '400: Policy With Perimeter Error' == str(exception_info.value) + + +def test_delete_policies_with_action_assignment(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + action_id = mock_data.create_action(policy_id) + data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id) + assignment_helper.add_action_assignment(policy_id, action_id, action_category_id, data_id) + + with pytest.raises(DeletePolicyWithPerimeter) as exception_info: + policy_helper.delete_policies(policy_id) + assert '400: Policy With Perimeter Error' == str(exception_info.value) + + +def test_delete_policies_with_subject_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + data_id = mock_data.create_subject_data(policy_id=policy_id, category_id=subject_category_id) + + with pytest.raises(DeletePolicyWithData) as exception_info: + policy_helper.delete_policies(policy_id) + + assert '400: Policy With Data Error' == str(exception_info.value) + + +def test_delete_policies_with_object_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + data_id = mock_data.create_object_data(policy_id=policy_id, category_id=object_category_id) + + with pytest.raises(DeletePolicyWithData) as exception_info: + policy_helper.delete_policies(policy_id) + assert '400: Policy With Data Error' == str(exception_info.value) + + +def test_delete_policies_with_action_data(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + data_id = mock_data.create_action_data(policy_id=policy_id, category_id=action_category_id) + + with pytest.raises(DeletePolicyWithData) as exception_info: + policy_helper.delete_policies(policy_id) + assert '400: Policy With Data Error' == str(exception_info.value) + + +def test_delete_policies_with_rule(db): + subject_category_id, object_category_id, action_category_id, meta_rule_id, policy_id = mock_data.create_new_policy() + + rules = policy_helper.add_rule(policy_id, meta_rule_id) + + with pytest.raises(DeletePolicyWithRules) as exception_info: + policy_helper.delete_policies(policy_id) + assert '400: Policy With Rule Error' == str(exception_info.value) diff --git a/python_moondb/tests/unit_python/requirements.txt b/python_moondb/tests/unit_python/requirements.txt index ff727723..aea8e3d5 100644 --- a/python_moondb/tests/unit_python/requirements.txt +++ b/python_moondb/tests/unit_python/requirements.txt @@ -1,4 +1,4 @@ sqlalchemy pymysql requests_mock -python_moonutilities \ No newline at end of file +python_moonutilities==1.4.20 \ No newline at end of file diff --git a/python_moonutilities/.gitignore b/python_moonutilities/.gitignore new file mode 100644 index 00000000..7bff7318 --- /dev/null +++ b/python_moonutilities/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + diff --git a/python_moonutilities/Changelog b/python_moonutilities/Changelog index ae7f352f..d001c892 100644 --- a/python_moonutilities/Changelog +++ b/python_moonutilities/Changelog @@ -98,3 +98,60 @@ CHANGES 1.4.10 ----- - Add CategoryNameInvalid and PerimeterNameInvalid exceptions + +1.4.11 +----- +- Add validate_data function + +1.4.12 +----- +- Fix a bug for the authz component +- updating Validation to be on mandatory keys only + +1.4.13 +----- +- Adding InvalidKey , InvalidContent exception +- fix error code of 'CategoryNameInvalid' to be 400 +- updating error of post/patch to mention key name + +1.4.14 +----- +- Adding updates to log +1.4.15 +----- +- Delete the check on each key send in request body for POST /models + +1.4.15-1 +-------- +- Revert to the previous functionality + +1.4.16 +----- +- Adding exceptions for MetaRuleNotLinkedWithPolicyModel , CategoryNotAssignedMetaRule + +1.4.17 +----- +- Update the security verification on attributes + +1.4.18 +----- +- Allow None values in input attributes (None is replaced by an empty string) + +1.4.19 +----- +- Allow boolean values in input attributes + +1.4.20 +----- +- Adding DeleteSubjectCategoryWithMetaRule exception +- Adding MetaRuleUpdate , PolicyUpdateError, ModelContentError exception +- Adding DeleteObjectCategoryWithMetaRule DeleteActionCategoryWithMetaRule exceptions + +1.4.21 +----- +- Allow in the cache the search of a perimeter element by it ID + +1.4.22 +----- +- Enable the target update in context manager +- Fix assignments update in cache diff --git a/python_moonutilities/python_moonutilities/__init__.py b/python_moonutilities/python_moonutilities/__init__.py index 6b30dedc..6e924e93 100644 --- a/python_moonutilities/python_moonutilities/__init__.py +++ b/python_moonutilities/python_moonutilities/__init__.py @@ -3,6 +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__ = "1.4.10" - - +__version__ = "1.4.22" diff --git a/python_moonutilities/python_moonutilities/cache.py b/python_moonutilities/python_moonutilities/cache.py index 1bb9d09e..49a3ef5b 100644 --- a/python_moonutilities/python_moonutilities/cache.py +++ b/python_moonutilities/python_moonutilities/cache.py @@ -102,14 +102,14 @@ class Cache(object): if policy_id in self.subjects: for _subject_id, _subject_dict in self.subjects[policy_id].items(): - if "name" in _subject_dict and _subject_dict["name"] == name: + if _subject_id == name or _subject_dict.get("name") == name: return _subject_id self.__update_subjects(policy_id) if policy_id in self.subjects: for _subject_id, _subject_dict in self.subjects[policy_id].items(): - if "name" in _subject_dict and _subject_dict["name"] == name: + if _subject_id == name or _subject_dict.get("name") == name: return _subject_id raise exceptions.SubjectUnknown("Cannot find subject {}".format(name)) @@ -131,14 +131,14 @@ class Cache(object): if policy_id in self.objects: for _object_id, _object_dict in self.__OBJECTS[policy_id].items(): - if "name" in _object_dict and _object_dict["name"] == name: + if _object_id == name or _object_dict.get("name") == name: return _object_id self.__update_objects(policy_id) if policy_id in self.objects: for _object_id, _object_dict in self.__OBJECTS[policy_id].items(): - if "name" in _object_dict and _object_dict["name"] == name: + if _object_id == name or _object_dict.get("name") == name: return _object_id raise exceptions.ObjectUnknown("Cannot find object {}".format(name)) @@ -161,13 +161,13 @@ class Cache(object): if policy_id in self.actions: for _action_id, _action_dict in self.__ACTIONS[policy_id].items(): - if "name" in _action_dict and _action_dict["name"] == name: + if _action_id == name or _action_dict.get("name") == name: return _action_id self.__update_actions(policy_id) for _action_id, _action_dict in self.__ACTIONS[policy_id].items(): - if "name" in _action_dict and _action_dict["name"] == name: + if _action_id == name or _action_dict.get("name") == name: return _action_id raise exceptions.ActionUnknown("Cannot find action {}".format(name)) @@ -218,6 +218,17 @@ class Cache(object): # assignment functions + def update_assignments(self, policy_id=None, perimeter_id=None): + if policy_id: + self.__update_subject_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_object_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_action_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + else: + for policy_id in self.__POLICIES: + self.__update_subject_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_object_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_action_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + @property def subject_assignments(self): return self.__SUBJECT_ASSIGNMENTS @@ -233,8 +244,7 @@ class Cache(object): if 'subject_assignments' in response.json(): if policy_id not in self.subject_assignments: self.__SUBJECT_ASSIGNMENTS[policy_id] = {} - - self.__SUBJECT_ASSIGNMENTS[policy_id].update(response.json()['subject_assignments']) + self.__SUBJECT_ASSIGNMENTS[policy_id] = response.json()['subject_assignments'] else: raise exceptions.SubjectAssignmentUnknown( "Cannot find subject assignment within policy_id {}".format(policy_id)) @@ -251,7 +261,7 @@ class Cache(object): if perimeter_id == value['subject_id'] and category_id == value['category_id']: return value['assignments'] else: - logger.warning("'subject_id' or 'category_id' or'assignments'" + logger.warning("'subject_id' or 'category_id' or 'assignments'" " keys are not found in subject_assignments") return [] @@ -271,7 +281,7 @@ class Cache(object): if policy_id not in self.object_assignments: self.__OBJECT_ASSIGNMENTS[policy_id] = {} - self.__OBJECT_ASSIGNMENTS[policy_id].update(response.json()['object_assignments']) + self.__OBJECT_ASSIGNMENTS[policy_id] = response.json()['object_assignments'] else: raise exceptions.ObjectAssignmentUnknown( "Cannot find object assignment within policy_id {}".format(policy_id)) @@ -308,7 +318,7 @@ class Cache(object): if policy_id not in self.__ACTION_ASSIGNMENTS: self.__ACTION_ASSIGNMENTS[policy_id] = {} - self.__ACTION_ASSIGNMENTS[policy_id].update(response.json()['action_assignments']) + self.__ACTION_ASSIGNMENTS[policy_id] = response.json()['action_assignments'] else: raise exceptions.ActionAssignmentUnknown( "Cannot find action assignment within policy_id {}".format(policy_id)) diff --git a/python_moonutilities/python_moonutilities/context.py b/python_moonutilities/python_moonutilities/context.py index 1d25cda2..dc140b74 100644 --- a/python_moonutilities/python_moonutilities/context.py +++ b/python_moonutilities/python_moonutilities/context.py @@ -59,19 +59,19 @@ class Context: @property def current_state(self): - self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index]) + self.__validate_meta_rule_content(self.__pdp_set[self.__meta_rule_ids[self.__index]]) return self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] @current_state.setter def current_state(self, state): if state not in ("grant", "deny", "passed"): state = "passed" - self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index]) + self.__validate_meta_rule_content(self.__pdp_set[self.__meta_rule_ids[self.__index]]) self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] = state @current_state.deleter def current_state(self): - self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index]) + self.__validate_meta_rule_content(self.__pdp_set[self.__meta_rule_ids[self.__index]]) self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] = "unset" @property @@ -110,38 +110,46 @@ class Context: self.__pdp_set[meta_rule_id]["effect"] = "unset" self.__pdp_set["effect"] = "deny" - # def update_target(self, context): - # # result = dict() - # current_request = context['current_request'] - # _subject = current_request.get("subject") - # _object = current_request.get("object") - # _action = current_request.get("action") - # meta_rule_id = context['headers'][context['index']] - # policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id) - # meta_rules = self.cache.meta_rules() - # # for meta_rule_id in meta_rules: - # for sub_cat in meta_rules[meta_rule_id]['subject_categories']: - # if sub_cat not in context["pdp_set"][meta_rule_id]["target"]: - # context["pdp_set"][meta_rule_id]["target"][sub_cat] = [] - # for assign in self.cache.get_subject_assignments(policy_id, _subject, sub_cat).values(): - # for assign in assign["assignments"]: - # if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]: - # context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign) - # for obj_cat in meta_rules[meta_rule_id]['object_categories']: - # if obj_cat not in context["pdp_set"][meta_rule_id]["target"]: - # context["pdp_set"][meta_rule_id]["target"][obj_cat] = [] - # for assign in self.cache.get_object_assignments(policy_id, _object, obj_cat).values(): - # for assign in assign["assignments"]: - # if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]: - # context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign) - # for act_cat in meta_rules[meta_rule_id]['action_categories']: - # if act_cat not in context["pdp_set"][meta_rule_id]["target"]: - # context["pdp_set"][meta_rule_id]["target"][act_cat] = [] - # for assign in self.cache.get_action_assignments(policy_id, _action, act_cat).values(): - # for assign in assign["assignments"]: - # if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]: - # context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign) - # # context["pdp_set"][meta_rule_id]["target"].update(result) + def update_target(self): + for meta_rule_id in self.__meta_rule_ids: + result = dict() + _subject = self.__current_request["subject"] + _object = self.__current_request["object"] + _action = self.__current_request["action"] + + meta_rules = self.cache.meta_rules + policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id) + + if 'subject_categories' not in meta_rules[meta_rule_id]: + raise exceptions.MetaRuleContentError(" 'subject_categories' key not found ") + + self.cache.update_assignments(policy_id) + + for sub_cat in meta_rules[meta_rule_id]['subject_categories']: + if sub_cat not in result: + result[sub_cat] = [] + result[sub_cat].extend( + self.cache.get_subject_assignments(policy_id, _subject, sub_cat)) + + if 'object_categories' not in meta_rules[meta_rule_id]: + raise exceptions.MetaRuleContentError(" 'object_categories' key not found ") + + for obj_cat in meta_rules[meta_rule_id]['object_categories']: + if obj_cat not in result: + result[obj_cat] = [] + result[obj_cat].extend( + self.cache.get_object_assignments(policy_id, _object, obj_cat)) + + if 'action_categories' not in meta_rules[meta_rule_id]: + raise exceptions.MetaRuleContentError(" 'action_categories' key not found ") + + for act_cat in meta_rules[meta_rule_id]['action_categories']: + if act_cat not in result: + result[act_cat] = [] + result[act_cat].extend( + self.cache.get_action_assignments(policy_id, _action, act_cat)) + + self.__pdp_set[meta_rule_id]["target"] = result def __add_target(self, meta_rule_id): """build target from meta_rule @@ -341,4 +349,5 @@ pdp_set: {pdp_set} def __validate_meta_rule_content(self, meta_rules): if 'effect' not in meta_rules: - raise exceptions.PdpContentError + logger.error("meta_rules={}".format(meta_rules)) + raise exceptions.PdpContentError("effect not in meta_rules") diff --git a/python_moonutilities/python_moonutilities/exceptions.py b/python_moonutilities/python_moonutilities/exceptions.py index a43ac89f..8ad90e96 100644 --- a/python_moonutilities/python_moonutilities/exceptions.py +++ b/python_moonutilities/python_moonutilities/exceptions.py @@ -133,6 +133,13 @@ class ModelUnknown(MoonError): logger = "Error" +class ModelContentError(MoonError): + description = _("The model content is invalid.") + code = 400 + title = 'Model Unknown' + logger = "Error" + + class ModelExisting(MoonError): description = _("The model already exists.") code = 409 @@ -197,18 +204,13 @@ class AdminRule(AdminException): code = 400 title = 'Rule Exception' + class CategoryNameInvalid(AdminMetaData): description = _("The given category name is invalid.") - code = 409 + code = 400 title = 'Category Name Invalid' logger = "ERROR" -class SubjectCategoryNameExisting(AdminMetaData): - description = _("The given subject category name already exists.") - code = 409 - title = 'Subject Category Name Existing' - logger = "ERROR" - class SubjectCategoryExisting(AdminMetaData): description = _("The given subject category already exists.") @@ -216,28 +218,12 @@ class SubjectCategoryExisting(AdminMetaData): title = 'Subject Category Existing' logger = "ERROR" - -class ObjectCategoryNameExisting(AdminMetaData): - description = _("The given object category name already exists.") - code = 409 - title = 'Object Category Name Existing' - logger = "ERROR" - - class ObjectCategoryExisting(AdminMetaData): description = _("The given object category already exists.") code = 409 title = 'Object Category Existing' logger = "ERROR" - -class ActionCategoryNameExisting(AdminMetaData): - description = _("The given action category name already exists.") - code = 409 - title = 'Action Category Name Existing' - logger = "ERROR" - - class ActionCategoryExisting(AdminMetaData): description = _("The given action category already exists.") code = 409 @@ -252,6 +238,20 @@ class SubjectCategoryUnknown(AdminMetaData): logger = "ERROR" +class DeleteSubjectCategoryWithMetaRule(MoonError): + description = _("Cannot delete subject category used in meta rule ") + code = 400 + title = 'Subject Category With Meta Rule Error' + logger = "Error" + + +class DeleteObjectCategoryWithMetaRule(MoonError): + description = _("Cannot delete Object category used in meta rule ") + code = 400 + title = 'Object Category With Meta Rule Error' + logger = "Error" + + class ObjectCategoryUnknown(AdminMetaData): description = _("The given object category is unknown.") code = 400 @@ -259,19 +259,33 @@ class ObjectCategoryUnknown(AdminMetaData): logger = "ERROR" +class DeleteActionCategoryWithMetaRule(MoonError): + description = _("Cannot delete Action category used in meta rule ") + code = 400 + title = 'Action Category With Meta Rule Error' + logger = "Error" + + class ActionCategoryUnknown(AdminMetaData): description = _("The given action category is unknown.") code = 400 title = 'Action Category Unknown' logger = "ERROR" - -class PerimeterNameInvalid(AdminPerimeter): - description = _("The given name is not valid.") +class PerimeterContentError(AdminPerimeter): + description = _("Perimeter content is invalid.") code = 400 - title = 'Perimeter Name is Invalid' + title = 'Perimeter content is invalid.' logger = "ERROR" + +class DeletePerimeterWithAssignment(MoonError): + description = _("Cannot delete perimeter with assignment") + code = 400 + title = 'Perimeter With Assignment Error' + logger = "Error" + + class SubjectUnknown(AdminPerimeter): description = _("The given subject is unknown.") code = 400 @@ -313,23 +327,24 @@ class ActionExisting(AdminPerimeter): title = 'Action Existing' logger = "ERROR" + class SubjectNameExisting(AdminPerimeter): description = _("The given subject name is existing.") - code = 400 + code = 409 title = 'Subject Name Existing' logger = "ERROR" class ObjectNameExisting(AdminPerimeter): description = _("The given object name is existing.") - code = 400 + code = 409 title = 'Object Name Existing' logger = "ERROR" class ActionNameExisting(AdminPerimeter): description = _("The given action name is existing.") - code = 400 + code = 409 title = 'Action Name Existing' logger = "ERROR" @@ -392,21 +407,21 @@ class ActionScopeExisting(AdminScope): class SubjectScopeNameExisting(AdminScope): description = _("The given subject scope name is existing.") - code = 400 + code = 409 title = 'Subject Scope Name Existing' logger = "ERROR" class ObjectScopeNameExisting(AdminScope): description = _("The given object scope name is existing.") - code = 400 + code = 409 title = 'Object Scope Name Existing' logger = "ERROR" class ActionScopeNameExisting(AdminScope): description = _("The given action scope name is existing.") - code = 400 + code = 409 title = 'Action Scope Name Existing' logger = "ERROR" @@ -434,21 +449,21 @@ class ActionAssignmentUnknown(AdminAssignment): class SubjectAssignmentExisting(AdminAssignment): description = _("The given subject assignment value is existing.") - code = 400 + code = 409 title = 'Subject Assignment Existing' logger = "ERROR" class ObjectAssignmentExisting(AdminAssignment): description = _("The given object assignment value is existing.") - code = 400 + code = 409 title = 'Object Assignment Existing' logger = "ERROR" class ActionAssignmentExisting(AdminAssignment): description = _("The given action assignment value is existing.") - code = 400 + code = 409 title = 'Action Assignment Existing' logger = "ERROR" @@ -475,23 +490,37 @@ class SubMetaRuleAlgorithmNotExisting(AdminMetaRule): class MetaRuleUnknown(AdminMetaRule): - description = _("The given sub meta rule is unknown.") + description = _("The given meta rule is unknown.") code = 400 - title = 'Sub Meta Rule Unknown' + title = 'Meta Rule Unknown' logger = "ERROR" +class MetaRuleNotLinkedWithPolicyModel(MoonError): + description = _("The meta rule is not found in the model attached to the policy.") + code = 400 + title = 'MetaRule Not Linked With Model - Policy' + logger = "Error" + + +class CategoryNotAssignedMetaRule(MoonError): + description = _("The category is not found in the meta rules attached to the policy.") + code = 400 + title = 'Category Not Linked With Meta Rule - Policy' + logger = "Error" + + class SubMetaRuleNameExisting(AdminMetaRule): description = _("The sub meta rule name already exists.") - code = 400 + code = 409 title = 'Sub Meta Rule Name Existing' logger = "ERROR" class MetaRuleExisting(AdminMetaRule): - description = _("The sub meta rule already exists.") - code = 400 - title = 'Sub Meta Rule Existing' + description = _("The meta rule already exists.") + code = 409 + title = 'Meta Rule Existing' logger = "ERROR" @@ -502,13 +531,27 @@ class MetaRuleContentError(AdminMetaRule): logger = "ERROR" +class MetaRuleUpdateError(AdminMetaRule): + description = _("Meta_rule is used in Rule.") + code = 400 + title = 'Meta_Rule Update Error' + logger = "ERROR" + + class RuleExisting(AdminRule): description = _("The rule already exists.") - code = 400 + code = 409 title = 'Rule Existing' logger = "ERROR" +class RuleContentError(AdminRule): + description = _("Invalid content of rule.") + code = 400 + title = 'Rule Error' + logger = "ERROR" + + class RuleUnknown(AdminRule): description = _("The rule for that request doesn't exist.") code = 400 @@ -570,6 +613,7 @@ class ConsulComponentContentError(ConsulError): title = 'Consul Content error' logger = "WARNING" + # Containers exceptions @@ -638,7 +682,7 @@ class PdpExisting(MoonError): class PdpContentError(MoonError): description = _("Invalid content of pdp.") - code = 409 + code = 400 title = 'Pdp Error' logger = "Error" @@ -656,11 +700,24 @@ class PolicyUnknown(MoonError): title = 'Policy Unknown' logger = "Error" +class PolicyContentError(MoonError): + description = _("The policy content is invalid.") + code = 400 + title = 'Policy Content Error' + logger = "Error" + class PolicyExisting(MoonError): description = _("The policy already exists.") code = 409 - title = 'Policy Error' + title = 'Policy Already Exists' + logger = "Error" + + +class PolicyUpdateError(MoonError): + description = _("The policy data is used.") + code = 400 + title = 'Policy update error' logger = "Error" @@ -674,33 +731,103 @@ class DeleteData(MoonError): class DeleteCategoryWithData(MoonError): description = _("Cannot delete category with data") code = 400 - title = 'Category Error' + title = 'Category With Data Error' logger = "Error" class DeleteCategoryWithMetaRule(MoonError): description = _("Cannot delete category with meta rule") code = 400 - title = 'Category Error' + title = 'Category With MetaRule Error' + logger = "Error" + + +class DeleteCategoryWithAssignment(MoonError): + description = _("Cannot delete category with assignment ") + code = 400 + title = 'Category With Assignment Error' logger = "Error" class DeleteModelWithPolicy(MoonError): description = _("Cannot delete model with policy") code = 400 - title = 'Model Error' + title = 'Model With Policy Error' logger = "Error" class DeletePolicyWithPdp(MoonError): description = _("Cannot delete policy with pdp") code = 400 - title = 'Policy Error' + title = 'Policy With PDP Error' + logger = "Error" + + +class DeletePolicyWithPerimeter(MoonError): + description = _("Cannot delete policy with perimeter") + code = 400 + title = 'Policy With Perimeter Error' + logger = "Error" + + +class DeletePolicyWithData(MoonError): + description = _("Cannot delete policy with data") + code = 400 + title = 'Policy With Data Error' + logger = "Error" + + +class DeletePolicyWithRules(MoonError): + description = _("Cannot delete policy with rules") + code = 400 + title = 'Policy With Rule Error' logger = "Error" class DeleteMetaRuleWithModel(MoonError): description = _("Cannot delete meta rule with model") code = 400 - title = 'Meta rule Error' + title = 'Meta rule With Model Error' + logger = "Error" + + +class DeleteMetaRuleWithRule(MoonError): + description = _("Cannot delete meta rule with rule") + code = 400 + title = 'Meta rule With Model Error' + logger = "Error" + + +class DataUnknown(MoonError): + description = _("The data unknown.") + code = 400 + title = 'Data Unknown' + logger = "Error" + + +class ValidationContentError(MoonError): + description = _("The Content validation incorrect.") + code = 400 + title = 'Invalid Content' + logger = "Error" + + def __init__(self, message=""): + self.message = message + super().__init__(message) + + def __str__(self): + return self.message + + +class ValidationKeyError(MoonError): + description = _("The Key validation incorrect.") + code = 400 + title = 'Invalid Key' logger = "Error" + + def __init__(self, message=""): + self.message = message + super().__init__(message) + + def __str__(self): + return self.message diff --git a/python_moonutilities/python_moonutilities/security_functions.py b/python_moonutilities/python_moonutilities/security_functions.py index 5d5275ee..1069eb2f 100644 --- a/python_moonutilities/python_moonutilities/security_functions.py +++ b/python_moonutilities/python_moonutilities/security_functions.py @@ -4,6 +4,7 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. +import html import re import os import types @@ -22,6 +23,7 @@ __targets = {} def filter_input(func_or_str): + def __filter(string): if string and type(string) is str: return "".join(re.findall("[\w\- +]*", string)) @@ -88,28 +90,22 @@ To do should check value of Dictionary but it's dependent on from where it's com def validate_data(data): def __validate_string(string): - if not string: - raise ValueError('Empty String') - ''' - is it valid to contains space inbetween - - ''' - - if " " in string: - raise ValueError('String contains space') + temp_str = html.escape(string) + if string != temp_str: + raise exceptions.ValidationContentError('Forbidden characters in string') def __validate_list_or_tuple(container): - if not container: - raise ValueError('Empty Container') for i in container: validate_data(i) def __validate_dict(dictionary): - if not dictionary: - raise ValueError('Empty Dictionary') for key in dictionary: validate_data(dictionary[key]) + if isinstance(data, bool): + return True + if data is None: + data = "" if isinstance(data, str): __validate_string(data) elif isinstance(data, list) or isinstance(data, tuple): @@ -117,7 +113,7 @@ def validate_data(data): elif isinstance(data, dict): __validate_dict(data) else: - raise ValueError('Value is Not String or Container or Dictionary') + raise exceptions.ValidationContentError('Value is Not String or Container or Dictionary: {}'.format(data)) def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]): @@ -161,24 +157,30 @@ def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]): validate_data(temp_args[i]) while len(kwargs_state) < len(kwargs): - kwargs_state.append(True) + kwargs_state.append(False) counter = 0 for i in kwargs: if kwargs_state[counter]: - validate_data({i: kwargs[i]}) + validate_data(kwargs[i]) counter = counter + 1 if type == "post" or type == "patch": body = request.json - while len(body_state) < len(body): - body_state.append(True) - counter = 0 - for i in body: - if body_state[counter]: - validate_data({i: body[i]}) - - counter = counter + 1 + # while len(body_state) < len(body): + # body_state.append(True) + # counter = 0 + for key in body_state: + if key in body: + if body_state[key]: + try: + validate_data(body.get(key)) + except exceptions.ValidationContentError as e: + raise exceptions.ValidationContentError("Key: '{}', [{}]".format(key, str(e))) + else: + raise exceptions.ValidationKeyError('Invalid Key :{} not found'.format(key)) + + # counter = counter + 1 return func(*args, **kwargs) @@ -189,16 +191,13 @@ def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]): def enforce(action_names, object_name, **extra): """Fake version of the enforce decorator""" - def wrapper_func(func): def wrapper_args(*args, **kwargs): # LOG.info("kwargs={}".format(kwargs)) # kwargs['user_id'] = kwargs.pop('user_id', "admin") # LOG.info("Calling enforce on {} with args={} kwargs={}".format(func.__name__, args, kwargs)) return func(*args, **kwargs) - return wrapper_args - return wrapper_func @@ -329,5 +328,4 @@ def check_auth(function): user_id = kwargs.pop("user_id", token) result = function(*args, **kwargs, user_id=user_id) return result - return wrapper diff --git a/python_moonutilities/tests/unit_python/requirements.txt b/python_moonutilities/tests/unit_python/requirements.txt index 3c1ad607..b08a2603 100644 --- a/python_moonutilities/tests/unit_python/requirements.txt +++ b/python_moonutilities/tests/unit_python/requirements.txt @@ -1,2 +1 @@ -pytest requests_mock \ No newline at end of file diff --git a/python_moonutilities/tests/unit_python/test_validated_input.py b/python_moonutilities/tests/unit_python/test_validated_input.py index c8e681e9..723bc8ba 100644 --- a/python_moonutilities/tests/unit_python/test_validated_input.py +++ b/python_moonutilities/tests/unit_python/test_validated_input.py @@ -1,166 +1,129 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + import pytest def test_valid_string(): from python_moonutilities.security_functions import validate_data validate_data("CorrectString") + validate_data("Correct String") + validate_data("Correct String!") + validate_data("Correct String@") + validate_data(None) + validate_data(True) -def test_unvalid_string(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data("Notcorrect String") - - assert str(exception_info.value) == 'String contains space' -def test_empty_string(): +def test_invalid_string(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data("") + validate_data("NotcorrectString") - assert str(exception_info.value) == 'Empty String' + assert str(exception_info.value) == 'Forbidden characters in string' def test_none_value(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data(None) + validate_data(object) - assert str(exception_info.value) == 'Value is Not String or Container or Dictionary' + assert 'Value is Not String or Container or Dictionary' in str(exception_info.value) -def test_int_value(): +def test_numeric_value(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: validate_data(1) + assert 'Value is Not String or Container or Dictionary' in str(exception_info.value) - assert str(exception_info.value) == 'Value is Not String or Container or Dictionary' - - -def test_float_value(): - from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: validate_data(1.23) - - assert str(exception_info.value) == 'Value is Not String or Container or Dictionary' + assert 'Value is Not String or Container or Dictionary' in str(exception_info.value) -def test_correct_list(): +def test_correct_list_one_element(): from python_moonutilities.security_functions import validate_data - validate_data(["skjdnfa","dao","daosdjpw"]) + validate_data(["test_1", "test_2", "test_3"]) -def test_correct_list(): +def test_correct_list_multiple_element(): from python_moonutilities.security_functions import validate_data - validate_data(["skjdnfa"]) + validate_data(["test"]) -def test_correct_instead_list(): +def test_correct_nested_list(): from python_moonutilities.security_functions import validate_data - validate_data([["skjdnfa","daswi"],[["daskdlw"],["daklwo"]],["dawl","afioa"],["dawno"]]) - - -def test_empty_list(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data([]) - - assert str(exception_info.value) == 'Empty Container' - - -def test_empty_list_inside_other_list(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data(["dajiwdj",[]]) - - assert str(exception_info.value) == 'Empty Container' + validate_data([["test_1", "test_2"], [["test_3"], ["test_4"]], ["test_5", "test_6"], ["test_7"]]) def test_incorrect_string_inside_list(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data(["dajiwdj",["dakwe","daow awoepa"]]) - - assert str(exception_info.value) == 'String contains space' - + validate_data(["test_1", ["test_2", "forbiddencharacter"]]) -def test_empty_string_inside_list(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data(["dajiwdj", ["dakwe", ""]]) - - assert str(exception_info.value) == 'Empty String' + assert str(exception_info.value) == 'Forbidden characters in string' def test_correct_tuples(): from python_moonutilities.security_functions import validate_data - validate_data(("dasdw","dawdwa")) - - -def test_empty_tuples(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data(()) + validate_data(("test_1", "test_2")) - assert str(exception_info.value) == 'Empty Container' def test_correct_tuple_of_tuple(): from python_moonutilities.security_functions import validate_data - validate_data(("gjosjefa",("diwajdi","oejfoea"),(("jwdi","fjia"),("nfioa","ifao")))) + validate_data(("test_1", ("test_2", "test_3"), (("test_4", "test_5"), ("test_6", "test_7")))) -def test_incorrect_tuple(): +def test_incorrect_string_within_tuple(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data(("djawo","dowa afw")) + validate_data(("test_1", "forbiddencharacter")) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' def test_correct_dictionary(): from python_moonutilities.security_functions import validate_data - validate_data({"daiwdw":"dwioajd"}) - - -def test_incorrect_dictionary(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data({"daiwdw":"dwioa jd"}) + validate_data({"test_1": "test_2"}) - assert str(exception_info.value) == 'String contains space' -def test_empty_dictionary(): +def test_incorrect_string_within_dictionary(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data({}) + validate_data({"test_1": "forbiddencharacter"}) - assert str(exception_info.value) == 'Empty Dictionary' + assert str(exception_info.value) == 'Forbidden characters in string' def test_correct_function_pass(): from python_moonutilities.security_functions import validate_input @validate_input() - def temp_function(string,list,tuple): - if string!="teststring" : + def temp_function(string, list, tuple): + if string != "teststring": raise ValueError("values which passed incorrect") - temp_function("teststring",["teststring",["teststring"]],("teststring",("teststring"))) + temp_function("teststring", ["teststring", ["teststring"]], ("teststring", ("teststring", ))) -def test_incorrect_function_pass1(): + +def test_incorrect_validating_function_with_kwargs(): from python_moonutilities.security_functions import validate_input - @validate_input() + @validate_input(kwargs_state=[True,True]) def temp_function(string, list, tuple): if string != "teststring": raise ValueError("values which passed incorrect") with pytest.raises(Exception) as exception_info: - temp_function("teststring",list=["teststring", ["testst ring"]],tuple=("teststring", ("teststri ng"))) + temp_function("teststring", list=["teststring", ["teststring"]],tuple=("teststring", ("teststring", ))) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' -def test_incorrect_function_pass2(): +def test_incorrect_validating_function(): from python_moonutilities.security_functions import validate_input @validate_input() @@ -169,23 +132,23 @@ def test_incorrect_function_pass2(): raise ValueError("values which passed incorrect") with pytest.raises(Exception) as exception_info: - temp_function("teststring", ["teststring", ["teststri ng"]], {"teststring": ("teststring")}) + temp_function("teststring", ["teststring", ["teststring"]], {"teststring": ("teststring", )}) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' -def test_incorrect_function_pass3(): +def test_incorrect_validating_class_function(): from python_moonutilities.security_functions import validate_input - class x: + class Testclass: @validate_input() - def temp_function(string, list, dictionary): + def temp_function(self, string, list, dictionary): if string != "teststring": raise ValueError("values which passed incorrect") - e=x; + e = Testclass() with pytest.raises(Exception) as exception_info: - e.temp_function("teststring", ["teststring", ["teststri ng"]], {"teststring": ("teststring")}) + e.temp_function("teststring", ["teststring", ["teststring"]], {"teststring": ("teststring", )}) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' -- cgit 1.2.3-korg