Update code to 4.6 official version 07/63207/1
authorThomas Duval <thomas.duval@orange.com>
Fri, 5 Oct 2018 14:54:37 +0000 (16:54 +0200)
committerThomas Duval <thomas.duval@orange.com>
Fri, 5 Oct 2018 14:58:48 +0000 (16:58 +0200)
Change-Id: Ibd0da0e476e24b2685f54693efc11f7a58d40a62

138 files changed:
moon_authz/Changelog
moon_authz/moon_authz/__init__.py
moon_authz/moon_authz/__main__.py
moon_authz/moon_authz/api/authorization.py
moon_authz/moon_authz/api/update.py [new file with mode: 0644]
moon_authz/moon_authz/http_server.py
moon_authz/moon_authz/server.py
moon_authz/tests/unit_python/mock_pods.py
moon_dashboard/Dockerfile
moon_dashboard/moon/api/__init__.py [new file with mode: 0644]
moon_dashboard/moon/api/moon_api.py [new file with mode: 0644]
moon_dashboard/moon/static/moon/js/moon.module.js
moon_dashboard/moon/static/moon/js/util.service.js
moon_dashboard/moon/static/moon/model/model.controller.js
moon_dashboard/moon/static/moon/model/model.html
moon_dashboard/moon/static/moon/model/model.service.js
moon_dashboard/moon/static/moon/pdp/pdp.controller.js
moon_dashboard/moon/static/moon/policy/policy.controller.js
moon_dashboard/moon/static/moon/policy/policy.html
moon_dashboard/moon/static/moon/policy/policy.service.js
moon_dashboard/moon/static/moon/policy/policy.service.spec.js
moon_dashboard/moon/static/moon/scss/moon.scss
moon_dashboard/run.sh
moon_dashboard/setup.cfg
moon_forming/.gitignore [new file with mode: 0644]
moon_interface/Changelog
moon_interface/moon_interface/__init__.py
moon_interface/moon_interface/api/update.py [new file with mode: 0644]
moon_interface/moon_interface/authz_requests.py
moon_interface/moon_interface/http_server.py
moon_manager/.gitignore [new file with mode: 0644]
moon_manager/Changelog
moon_manager/moon_manager/__init__.py
moon_manager/moon_manager/api/assignments.py
moon_manager/moon_manager/api/base_exception.py
moon_manager/moon_manager/api/data.py
moon_manager/moon_manager/api/generic.py
moon_manager/moon_manager/api/json_export.py
moon_manager/moon_manager/api/json_import.py
moon_manager/moon_manager/api/json_utils.py
moon_manager/moon_manager/api/meta_data.py
moon_manager/moon_manager/api/meta_rules.py
moon_manager/moon_manager/api/models.py
moon_manager/moon_manager/api/pdp.py
moon_manager/moon_manager/api/perimeter.py
moon_manager/moon_manager/api/policies.py
moon_manager/moon_manager/api/rules.py
moon_manager/moon_manager/api/slaves.py
moon_manager/moon_manager/http_server.py
moon_manager/moon_manager/server.py
moon_manager/tests/unit_python/api/import_export_utilities.py
moon_manager/tests/unit_python/api/test_assignement.py [new file with mode: 0644]
moon_manager/tests/unit_python/api/test_data.py
moon_manager/tests/unit_python/api/test_import.py
moon_manager/tests/unit_python/api/test_meta_data.py
moon_manager/tests/unit_python/api/test_meta_rules.py
moon_manager/tests/unit_python/api/test_pdp.py
moon_manager/tests/unit_python/api/test_perimeter.py
moon_manager/tests/unit_python/api/test_policies.py
moon_manager/tests/unit_python/api/test_rules.py
moon_manager/tests/unit_python/api/test_unit_models.py
moon_manager/tests/unit_python/conftest.py
moon_manager/tests/unit_python/helpers/data_builder.py
moon_manager/tests/unit_python/helpers/data_helper.py
moon_manager/tests/unit_python/helpers/model_helper.py
moon_manager/tests/unit_python/helpers/policy_helper.py
moon_manager/tests/unit_python/requirements.txt
moon_orchestrator/Changelog
moon_orchestrator/Dockerfile
moon_orchestrator/moon_orchestrator/__init__.py
moon_orchestrator/moon_orchestrator/api/generic.py
moon_orchestrator/moon_orchestrator/api/pods.py
moon_orchestrator/moon_orchestrator/drivers.py
moon_orchestrator/moon_orchestrator/http_server.py
moon_wrapper/Changelog
moon_wrapper/moon_wrapper/__init__.py
moon_wrapper/moon_wrapper/__main__.py
moon_wrapper/moon_wrapper/api/generic.py
moon_wrapper/moon_wrapper/api/oslowrapper.py
moon_wrapper/moon_wrapper/api/slaveupdate.py [new file with mode: 0644]
moon_wrapper/moon_wrapper/http_server.py
moon_wrapper/moon_wrapper/server.py
moon_wrapper/tests/unit_python/conftest.py
python_moonclient/.gitignore [new file with mode: 0644]
python_moonclient/Changelog
python_moonclient/python_moonclient/__init__.py
python_moonclient/python_moonclient/cli/authz.py
python_moonclient/python_moonclient/cli/export.py
python_moonclient/python_moonclient/cli/import.py
python_moonclient/python_moonclient/cli/models.py
python_moonclient/python_moonclient/cli/parser.py
python_moonclient/python_moonclient/cli/pdps.py
python_moonclient/python_moonclient/cli/policies.py
python_moonclient/python_moonclient/cli/projects.py
python_moonclient/python_moonclient/cli/slaves.py
python_moonclient/python_moonclient/core/authz.py
python_moonclient/python_moonclient/core/check_tools.py
python_moonclient/python_moonclient/core/cli_exceptions.py
python_moonclient/python_moonclient/core/config.py
python_moonclient/python_moonclient/core/json_export.py
python_moonclient/python_moonclient/core/json_import.py
python_moonclient/python_moonclient/core/models.py
python_moonclient/python_moonclient/core/pdp.py
python_moonclient/python_moonclient/core/policies.py
python_moonclient/python_moonclient/core/slaves.py
python_moonclient/python_moonclient/moon.py
python_moondb/.gitignore [new file with mode: 0644]
python_moondb/Changelog
python_moondb/python_moondb/__init__.py
python_moondb/python_moondb/api/keystone.py
python_moondb/python_moondb/api/managers.py
python_moondb/python_moondb/api/model.py
python_moondb/python_moondb/api/policy.py
python_moondb/python_moondb/backends/__init__.py
python_moondb/python_moondb/backends/sql.py
python_moondb/python_moondb/core.py
python_moondb/python_moondb/migrate_repo/versions/001_moon.py
python_moondb/tests/unit_python/helpers/data_helper.py
python_moondb/tests/unit_python/helpers/meta_rule_helper.py
python_moondb/tests/unit_python/helpers/mock_data.py
python_moondb/tests/unit_python/helpers/model_helper.py
python_moondb/tests/unit_python/helpers/policy_helper.py
python_moondb/tests/unit_python/models/test_categories.py
python_moondb/tests/unit_python/models/test_meta_rules.py
python_moondb/tests/unit_python/models/test_models.py
python_moondb/tests/unit_python/policies/test_assignments.py
python_moondb/tests/unit_python/policies/test_data.py
python_moondb/tests/unit_python/policies/test_policies.py
python_moondb/tests/unit_python/requirements.txt
python_moonutilities/.gitignore [new file with mode: 0644]
python_moonutilities/Changelog
python_moonutilities/python_moonutilities/__init__.py
python_moonutilities/python_moonutilities/cache.py
python_moonutilities/python_moonutilities/context.py
python_moonutilities/python_moonutilities/exceptions.py
python_moonutilities/python_moonutilities/security_functions.py
python_moonutilities/tests/unit_python/requirements.txt
python_moonutilities/tests/unit_python/test_validated_input.py

index 59d7f8e..ae1ec4d 100644 (file)
@@ -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
index 0fb3205..85c245e 100644 (file)
@@ -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"
index 2693f68..6f1f980 100644 (file)
@@ -1,4 +1,4 @@
 from moon_authz.server import create_server
 
-server = create_server()
-server.run()
+SERVER = create_server()
+SERVER.run()
index 8411446..59af295 100644 (file)
@@ -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 (file)
index 0000000..68b7f0c
--- /dev/null
@@ -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}
index 7d3b1ec..86d8a91 100644 (file)
@@ -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)
 
index 0cc5f6f..d1b5a59 100644 (file)
@@ -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,
index 9e05e33..39223a5 100644 (file)
@@ -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")
index 8f997fe..790a2b2 100644 (file)
@@ -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 (file)
index 0000000..e69de29
diff --git a/moon_dashboard/moon/api/moon_api.py b/moon_dashboard/moon/api/moon_api.py
new file mode 100644 (file)
index 0000000..e69de29
index ed56ec2..c8b8643 100755 (executable)
@@ -23,7 +23,7 @@
                .module('moon', [
                        'ngResource',
                ]).constant('moon.URI', {
-                       API: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}',
+                       API: 'http://{{MANAGER_HOST}}:{{MANAGER_PORT}}', 
                })
 
 })();
index 18ae901..29680a4 100755 (executable)
             },
 
             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);
                 }
             },
     
index d6a7503..99a7c7e 100644 (file)
       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
               });
             });
     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 = {
         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'),
         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);
       }
     }
 
         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 = {
       }
     }
 
+    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)
       }
     }
 
index 98d64c7..97f0891 100644 (file)
         <translate>Import</translate>
       </label>
       <input id="file" class="input-file" type="file" on-read-file="ctrl.importData(contents)" accept="application/json,.json"/>
-      <!--button type="button" class="btn btn-primary" ng-click="ctrl.createModel()">
-        <span class="fa fa-upload"></span>
-        <translate>Import</translate>
-      </button-->
     </div>
   </div>
 
                   <tr>
                     <td>
                       <p ng-repeat="category in metaRule.subject_categories">
-                        <span>{$ category.name $}</span>
+                        <span title="{$ category.description $}">{$ category.name $}</span>
                         <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategoryFromMetaRule('subject', metaRule, category)" title="{$ 'Remove Subject' | translate $}"></button>
                       </p>
                     </td>
                     <td>
                       <p ng-repeat="category in metaRule.object_categories">
-                        <span>{$ category.name $}</span>
+                        <span title="{$ category.description $}">{$ category.name $}</span>
                         <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategoryFromMetaRule('object', metaRule, category)" title="{$ 'Remove Object' | translate $}"></button>
                       </p>
                     </td>
                     <td>
                       <p ng-repeat="category in metaRule.action_categories">
-                        <span>{$ category.name $}</span>
+                        <span title="{$ category.description $}">{$ category.name $}</span>
                         <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeCategoryFromMetaRule('action', metaRule, category)" title="{$ 'Remove Action' | translate $}"></button>
                       </p>
                     </td>
index 76c3da0..986eb6b 100755 (executable)
                 return modelsMap[id];
             },
             createModel: function createModel(model) {
+                model.meta_rules = [];
                 modelResource.create(null, model, success, util.displayErrorFunction('Unable to create model'));
 
                 function success(data) {
                 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];
index c57f3b2..1859b1f 100644 (file)
@@ -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 = {
         type: "object",
         properties: {
           id: { type: "string", title: gettext("Select a Project:") }
-        }
+        },
+        required: ['id']
       };
       var model = {id : pdp.keystone_project_id};
 
index 6c6631c..a3cc18f 100644 (file)
 
     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);
       }
     }
           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)
           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'),
         type: "object",
         properties: {
           instructions: { type: "string", title: gettext("Instructions") }
-        }
+        },
+        required: ['instructions']
       };
 
       var config = {
     }
 
     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);
     }
 
     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);
     }
 
 
     self.showRule = function showRule(rule) {
       self.selectedRule = rule;
+      self.currentData = null;
     }
 
     self.hideRule = function hideRule() {
         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]];
         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 = {
       if (type == 'subject') {
         config.form.push('email');
       }
-      
+
       ModalFormService.open(config).then(submit);
 
       function submit(form) {
       }
     }
 
+    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);
         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
index 70789fb..ba13bec 100644 (file)
@@ -10,7 +10,7 @@
   </div>
 
   <div class="list-group">
-    <div ng-repeat="policy in ctrl.model.policies | orderBy:'name' | filter:filterText" class="list-group-item">
+    <div ng-repeat="policy in ctrl.model.policies | orderBy:'name' | filter:filterText" class="list-group-item" ng-init="toggle = {};toggle.showUnused = false">
       <h3 class="list-group-item-heading inline">{$ policy.name $}</h3>
       <div class="pull-right">
         <button type="button" class="fa fa-trash" title="{$ 'Remove Policy' | translate $}" ng-click="ctrl.removePolicy(policy)"></button>
         <translate>Genre:</translate>
         <translate>{$ policy.genre ? policy.genre : 'none' $}</translate>
       </h4>
+      <div ng-if="policy.unusedSubjectData.length  
+            || policy.unusedSubjectData.length
+            || policy.unusedSubjectData.length" class="alert alert-dismissable alert-warning">
+        <button type="button" class="close" data-dismiss="alert" ng-click="toggle.showUnused=false">×</button>
+        <h4 translate>Warning!</h4>
+        <p translate>
+          Some data are unused, please check them and delete them if necessary.
+          <a href="" ng-click="toggle.showUnused=true" ng-show="!toggle.showUnused" translate>Show unused data</a>
+          <a href="" ng-click="toggle.showUnused=false" ng-show="toggle.showUnused" translate>Hide unused data</a>
+        </p>
+      </div>
+
+      <div ng-if="toggle.showUnused" class="list-group-item-text overflow-hidden">
+        <div class="list-group col-lg-3" ng-if="policy.unusedSubjectData.length">
+          <h3 class="list-group-item active" translate>Unused Subject data</h3>
+          <div ng-repeat="subject in policy.unusedSubjectData | orderBy:'name'" class="list-group-item">
+            <h4 class="list-group-item-heading inline" title="{$ subject.description $}">{$ subject.name $}</h4>
+            <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeData('subject', policy, subject)" title="{$ 'Remove Subject data' | translate $}"></button>
+          </div>
+        </div>
+
+        <div class="list-group col-lg-3" ng-if="policy.unusedObjectData.length">
+          <h3 class="list-group-item active" translate>Unused Object data</h3>
+          <div ng-repeat="object in policy.unusedObjectData | orderBy:'name'" class="list-group-item">
+            <h4 class="list-group-item-heading inline" title="{$ object.description $}">{$ object.name $}</h4>
+            <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeData('object', policy, object)" title="{$ 'Remove Object data' | translate $}"></button>
+          </div>
+        </div>
+
+        <div class="list-group col-lg-3" ng-if="policy.unusedActionData.length">
+          <h3 class="list-group-item active" translate>Unused Action data</h3>
+          <div ng-repeat="action in policy.unusedActionData | orderBy:'name'" class="list-group-item">
+            <h4 class="list-group-item-heading inline" title="{$ action.description $}">{$ action.name $}</h4>
+            <button type="button" class="fa fa-trash pull-right" ng-click="ctrl.removeData('action', policy, action)" title="{$ 'Remove Action data' | translate $}"></button>
+          </div>
+        </div>
+        
+      </div>
+
+
       <details class="list-group-item-text">
         <summary ng-click="ctrl.populatePolicy(policy)">
           <h4 class="inline" translate>Rules</h4>
                     <tr>
                       <td>
                         <p ng-repeat="data in rule.subjectData">
-                          <span ng-class="{'text-primary': ctrl.currentData.data == data}">{$ data.name $}</span>
+                          <span ng-class="{'text-primary': ctrl.currentData.data == data}" title="{$ data.description $}">{$ data.name $}</span>
                           <button ng-if="ctrl.currentData.data != data" type="button" class="fa fa-exchange pull-right" ng-click="ctrl.assignData('subject', policy, data)"
                             title="{$ 'Assign to perimeters' | translate $}"></button>
                           <button ng-if="ctrl.currentData.data == data" type="button" class="fa fa-times pull-right" ng-click="ctrl.currentData = null"
                       </td>
                       <td>
                         <p ng-repeat="data in rule.objectData">
-                          <span ng-class="{'text-primary': ctrl.currentData.data == data}">{$ data.name $}</span>
+                          <span ng-class="{'text-primary': ctrl.currentData.data == data}" title="{$ data.description $}">{$ data.name $}</span>
                           <button ng-if="ctrl.currentData.data != data" type="button" class="fa fa-exchange pull-right" ng-click="ctrl.assignData('object', policy, data)"
                             title="{$ 'Assign to perimeters' | translate $}"></button>
                           <button ng-if="ctrl.currentData.data == data" type="button" class="fa fa-times pull-right" ng-click="ctrl.currentData = null"
                       </td>
                       <td>
                         <p ng-repeat="data in rule.actionData">
-                          <span ng-class="{'text-primary': ctrl.currentData.data == data}">{$ data.name $}</span>
+                          <span ng-class="{'text-primary': ctrl.currentData.data == data}" title="{$ data.description $}">{$ data.name $}</span>
                           <button ng-if="ctrl.currentData.data != data" type="button" class="fa fa-exchange pull-right" ng-click="ctrl.assignData('action', policy, data)"
                             title="{$ 'Assign to perimeters' | translate $}"></button>
                           <button ng-if="ctrl.currentData.data == data" type="button" class="fa fa-times pull-right" ng-click="ctrl.currentData = null"
                   </div>
                   <div>
                     <div class="col-lg-4">
-                      <h4 translate>Available perimeters</h4>
+                      <h4 translate>All perimeters</h4>
+                      <div class="w-100 height-200 scroll list-group border">
+                        <button class="list-group-item" ng-repeat="perimeter in ctrl.currentData.allPerimeters | orderBy:'name' | filter:filterPerimeter"
+                          title="{$ perimeter.description $}" ng-click="ctrl.addPerimeter(ctrl.currentData.type, policy, perimeter)">{$ perimeter.name $}</button>
+
+                      </div>
+                      <p translate class="mt-5">Click to add</p>
+                    </div>
+
+                    <div class="col-lg-4">
+                      <h4 translate>Policy perimeters</h4>
                       <div class="w-100 height-200 scroll list-group border">
-                        <button class="list-group-item" ng-repeat="perimeter in ctrl.currentData.perimeters | orderBy:'name' | filter:filterPerimeter" title="{$ perimeter.description $}"
-                          ng-click="ctrl.assign(ctrl.currentData.type, policy, perimeter, ctrl.currentData.data)">{$ perimeter.name $}</button>
+                        <div ng-click="ctrl.assign(ctrl.currentData.type, policy, perimeter, ctrl.currentData.data)" class="list-group-item" ng-repeat="perimeter in ctrl.currentData.perimeters | orderBy:'name' | filter:filterPerimeter">
+                          <span title="{$ perimeter.description $}">
+                            {$ perimeter.name $}
+                          </span>
+                          <button type="button" class="fa fa-trash pull-right" ng-click="$event.stopPropagation();ctrl.removePerimeterFromPolicy(ctrl.currentData.type, policy, perimeter)"
+                            title="{$ 'Remove Perimeter' | translate $}"></button>
+                        </div>
+
                       </div>
                       <p translate class="mt-5">Click to assign</p>
                     </div>
                     <div class="col-lg-4">
                       <h4 translate>Assigned perimeters</h4>
                       <div class="w-100 list-group border height-200 scroll">
-                        <button class="list-group-item" ng-repeat="perimeter in ctrl.currentData.assignments | orderBy:'name' | filter:filterPerimeter" title="{$ perimeter.description $}"
-                          ng-click="ctrl.unassign(ctrl.currentData.type, policy, perimeter, ctrl.currentData.data)">{$ perimeter.name $}</button>
+                        <button class="list-group-item" ng-repeat="perimeter in ctrl.currentData.assignments | orderBy:'name' | filter:filterPerimeter"
+                          title="{$ perimeter.description $}" ng-click="ctrl.unassign(ctrl.currentData.type, policy, perimeter, ctrl.currentData.data)">{$ perimeter.name $}</button>
                       </div>
                       <p translate class="mt-5">Click to unassign</p>
                     </div>
index 87250b2..3781156 100755 (executable)
             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', {}, {
                 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",
             }
         }
 
 
         function removeRuleInternal(policy, rule) {
             policy.rules.splice(policy.rules.indexOf(rule), 1);
+            updateUnusedData(policy);
         }
 
         function loadPolicyRule(policy) {
                 }
     
                 $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 : [];
             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);
                         policy.rules.push(populateRule(policy, rule))
                     }
                     util.displaySuccess('Rule created');
+                    updateUnusedData(policy);
                 }
             },
             removeRuleFromPolicy: function removeRuleFromPolicy(policy, rule) {
                     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]);
                     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,
                 }
     
                     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'))
                 
index 045bf9b..8d0ca8b 100755 (executable)
 
         });
 
+        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();
+        });
+
 
     });
 
index 20bf6c4..3cdbb6e 100644 (file)
@@ -51,4 +51,8 @@ details {
 
 .input-file {
     display: none !important;
+}
+
+.overflow-hidden {
+    overflow: hidden;
 }
\ No newline at end of file
index bf18faa..9a68ca6 100644 (file)
@@ -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
index f68765d..9cf3f77 100644 (file)
@@ -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 (file)
index 0000000..7bff731
--- /dev/null
@@ -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/
+
index cea475f..361d784 100644 (file)
@@ -30,3 +30,7 @@ CHANGES
 4.3.3-1
 -----
 - Fix a bug in authz_requests
+
+4.4.0
+-----
+- Add the update API
index a8cd945..85c245e 100644 (file)
@@ -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 (file)
index 0000000..e798059
--- /dev/null
@@ -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}
index c809053..cf50dfe 100644 (file)
@@ -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
 
index 1e0858c..50bf2a6 100644 (file)
@@ -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 (file)
index 0000000..894a44c
--- /dev/null
@@ -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/
index 56521a0..1fb9ac0 100644 (file)
@@ -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
index 205f6d8..f088774 100644 (file)
@@ -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"
index 426789e..9bc54b2 100644 (file)
@@ -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/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
     )
 
-    @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/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
     )
 
-    @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/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>",
     )
 
-    @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}
index 0af3b6d..0a414a5 100644 (file)
@@ -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
index d887ac2..92d7b2c 100644 (file)
@@ -28,13 +28,12 @@ class SubjectData(Resource):
         "/policies/<string:uuid>/subject_data",
         "/policies/<string:uuid>/subject_data/",
         "/policies/<string:uuid>/subject_data/<string:category_id>",
-        "/policies/<string:uuid>/subject_data/<string:category_id>/"
-        "<string:data_id>",
+        "/policies/<string:uuid>/subject_data/<string:category_id>/<string:data_id>",
     )
 
     @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}
-
-
index c79520f..721f621 100644 (file)
@@ -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:
index 1d3643e..069e588 100644 (file)
@@ -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:
index e57a27c..05f4a0c 100644 (file)
@@ -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"]
index cc4c8b0..6a5830f 100644 (file)
@@ -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
-
index 62ca050..b0b86d1 100644 (file)
@@ -30,7 +30,7 @@ class SubjectCategories(Resource):
         "/subject_categories/<string:category_id>",
     )
 
-    @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/<string:category_id>",
     )
 
-    @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.
index 3dc9996..738aad7 100644 (file)
@@ -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}
-
index c306836..c72396c 100644 (file)
@@ -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}
-
index a5d7c00..65a6a5f 100644 (file)
@@ -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}
-
index 6c39c43..a0fda4a 100644 (file)
@@ -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}
 
index 9fe237b..3264e8e 100644 (file)
@@ -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}
-
index a024809..cbd3996 100644 (file)
@@ -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}
-
index 769b681..e2928de 100644 (file)
@@ -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
index 204e7e0..5387952 100644 (file)
@@ -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))
index a8db8fd..70ddaee 100644 (file)
@@ -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")
 
 
index 12cb208..2ee2627 100644 (file)
@@ -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 (file)
index 0000000..b56fb42
--- /dev/null
@@ -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
+
+# ---------------------------------------------------------------------------
index ff0856a..433f69e 100644 (file)
@@ -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, "<a>")
     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, "<a>")
     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, "<a>")
     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
 # ---------------------------------------------------------------------------
index f1ab825..af5f753 100644 (file)
@@ -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 !"
index 4cb8691..e6cb083 100644 (file)
@@ -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, "<a>")
     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, "test<z>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_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, "<a>")
     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, "test<a>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_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, "<a>")
     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, "test<a>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_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'
index 80d648b..634f19d 100644 (file)
@@ -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, "<a>")
     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, "<br/>", "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'
index 1ac9b84..53a87b2 100644 (file)
@@ -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": "<a>",
         "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": "<a>",
         "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, "<a>")
     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"
index 322d90c..ff7b09d 100644 (file)
@@ -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": "<a>",
         "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": "<br/>",
         "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<a>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": "<a>",
         "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": "test<a>user",
+        "description": "description of {}".format("test user"),
+    }
+    req = client.post("/policies/{}/actions".format("111"), data=json.dumps(data),
+                      headers={'Content-Type': 'application/json'})
+    assert req.status_code == 400
+    assert json.loads(req.data)["message"] == "Key: 'name', [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)
index cd50f4c..76161d5 100644 (file)
@@ -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'
-
index af1501e..a3c2183 100644 (file)
@@ -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():
index d754b97..6e93ed2 100644 (file)
@@ -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, "<br/>")
+    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<br>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, "<a></a>", "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
index d989923..90a27e5 100644 (file)
@@ -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"}
index 2a7c597..91808cb 100644 (file)
@@ -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
index da6b937..e1c0564 100644 (file)
@@ -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_iddata_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_iddata_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_iddata_id)
+    PolicyManager.delete_subject_data("", policy_id=policy_id, data_id=data_id)
 
 
 def get_actions(policy_id, perimeter_id=None):
index d2ffb85..73808e0 100644 (file)
@@ -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",
index c932ee3..eddd0b8 100644 (file)
@@ -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",
index 6c6e5bb..d6f190e 100644 (file)
@@ -1,5 +1,5 @@
 flask
 flask_cors
 flask_restful
-python_moondb
-python_moonutilities
+python_moondb==1.2.20
+python_moonutilities==1.4.20
index 783c913..c04af79 100644 (file)
@@ -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
index 09d12fd..7c59efb 100644 (file)
@@ -1,4 +1,4 @@
-FROM python:3
+FROM python:3.6
 
 LABEL Name=Orchestrator
 LABEL Description="Orchestrator component for the Moon platform"
index bc8f278..31d4018 100644 (file)
@@ -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"
index 37e30a2..9128140 100644 (file)
@@ -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:
index 389fa5b..8943e01 100644 (file)
@@ -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
index 4519f3a..233d389 100644 (file)
@@ -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)
index 1cb1261..72e1235 100644 (file)
@@ -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("@", "-")
-
index 071e4ef..b2d6265 100644 (file)
@@ -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
index 98a9814..f088774 100644 (file)
@@ -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"
index 46cafa7..3a40329 100644 (file)
@@ -1,4 +1,4 @@
 from moon_wrapper.server import main
 
-server = main()
-server.run()
+SERVER = main()
+SERVER.run()
index 498513c..e492b32 100644 (file)
@@ -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
index 905c32d..3912862 100644 (file)
@@ -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 (file)
index 0000000..b2ce22f
--- /dev/null
@@ -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)
index dfbaed9..015bb28 100644 (file)
@@ -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
-
index 280fdb6..77def17 100644 (file)
@@ -28,5 +28,5 @@ def main():
 
 
 if __name__ == '__main__':
-    server = main()
-    server.run()
+    SERVER = main()
+    SERVER.run()
index 2c332c8..a667784 100644 (file)
@@ -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 (file)
index 0000000..9c29724
--- /dev/null
@@ -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
index 9066e44..7cd1434 100644 (file)
@@ -72,3 +72,7 @@ CHANGES
 1.4.1
 -----
 - Update exception during configuration
+
+1.4.2
+-----
+- apply PyLint rules
\ No newline at end of file
index e3ad930..bbd3108 100644 (file)
@@ -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"
index 2f45e84..4edc307 100644 (file)
@@ -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)
index a16928d..4ea5cf4 100644 (file)
@@ -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"
index c6c4343..efefc30 100644 (file)
@@ -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
-
index 922a183..369d902 100644 (file)
@@ -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)
-
-
-
index edd18a2..e71cd6c 100644 (file)
@@ -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")
index f1f8fe3..a4f7bba 100644 (file)
@@ -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)
index 94d13db..af8e959 100644 (file)
@@ -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)
index c4653a5..1caa0ac 100644 (file)
@@ -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'])
+                )
index 1880f4c..587e903 100644 (file)
@@ -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))
-
-
-
-
index 7bf9b57..d331004 100644 (file)
@@ -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
-
index 8138f54..381e92c 100644 (file)
@@ -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))
index 2ec2ed1..01fd23e 100644 (file)
@@ -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)
-
-
index f8e3fe2..c123499 100644 (file)
@@ -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
index 53c1b1f..edaeb17 100644 (file)
@@ -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
index a724476..b65ec39 100644 (file)
@@ -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
index 709b4a7..8d3c885 100644 (file)
@@ -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:
index 4e9e404..f67a4d0 100644 (file)
@@ -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)
index 46d918a..b9b05dd 100644 (file)
@@ -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
-
index 112b56f..77b127c 100644 (file)
@@ -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)
index f8cf027..0bd8092 100644 (file)
@@ -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 (file)
index 0000000..9c29724
--- /dev/null
@@ -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
index f4feef6..9236c26 100644 (file)
@@ -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
index e2e1628..37c9a72 100644 (file)
@@ -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"
index 582ae71..57521c3 100644 (file)
@@ -103,4 +103,3 @@ class KeystoneManager(Managers):
                                _exception=exceptions.KeystoneUserError)
         except exceptions.KeystoneUserConflict:
             return True
-
index f500d02..414725f 100644 (file)
@@ -4,6 +4,7 @@
 # or at 'http://www.apache.org/licenses/LICENSE-2.0'.
 
 import logging
+
 logger = logging.getLogger("moon.db.api.managers")
 
 
index c1603b8..4f6c34c 100644 (file)
@@ -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)
index 05c2b7d..03a93ff 100644 (file)
@@ -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
index 237bdc3..6f1cd3d 100644 (file)
@@ -1,4 +1,3 @@
-
 """
 intra_extensions = {
     intra_extension_id1: {
@@ -94,4 +93,4 @@ rules = {
         ...},
     sub_meta_rule_id2: { },
     ...}
-"""
\ No newline at end of file
+"""
index 7310e7f..d25586b 100644 (file)
@@ -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)
index 984b81a..3fee146 100644 (file)
@@ -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,),
         )
 
 
index 1bfb2ff..13670b9 100644 (file)
@@ -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)
-
-
index 20d9ae9..8a8238f 100644 (file)
@@ -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_iddata_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_iddata_id)
+    PolicyManager.delete_subject_data("", policy_id=policy_id, data_id=data_id)
 
 
 def get_actions(policy_id, perimeter_id=None):
index 80d138c..87af250 100644 (file)
@@ -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):
index 82eebe8..0d65ea0 100644 (file)
@@ -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]
-
index 58946a9..98a6271 100644 (file)
@@ -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,
index c932ee3..93d81c6 100644 (file)
@@ -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": "",
         }
index f87d0e1..39dc4c7 100644 (file)
@@ -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():
index 102cd72..3b2b5b0 100644 (file)
@@ -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'
index 0026345..1b17106 100644 (file)
@@ -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'
index 675c2ff..24a3a7b 100755 (executable)
@@ -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):
index fa3f8c0..8ce1ac0 100755 (executable)
@@ -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_iddata_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)
index 07ee87f..b239420 100755 (executable)
@@ -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)
index ff72772..aea8e3d 100644 (file)
@@ -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 (file)
index 0000000..7bff731
--- /dev/null
@@ -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/
+
index ae7f352..d001c89 100644 (file)
@@ -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
index 6b30ded..6e924e9 100644 (file)
@@ -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"
index 1bb9d09..49a3ef5 100644 (file)
@@ -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))
index 1d25cda..dc140b7 100644 (file)
@@ -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")
index a43ac89..8ad90e9 100644 (file)
@@ -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
index 5d5275e..1069eb2 100644 (file)
@@ -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
index c8e681e..723bc8b 100644 (file)
+# 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("Notcorrect<a>String")
 
-    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", "forbidden<a>character"]])
 
-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", "forbidden<a>character"))
 
-    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": "forbidden<a>character"})
 
-    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", ["testst<a>ring"]],tuple=("teststring", ("teststri<a>ng", )))
 
-    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", ["teststri<a>ng"]], {"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", ["teststri<a>ng"]], {"teststring": ("teststring", )})
 
-    assert str(exception_info.value) == 'String contains space'
+    assert str(exception_info.value) == 'Forbidden characters in string'