diff options
Diffstat (limited to 'moonv4/moon_interface')
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/assignments.py | 264 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/authz.py | 244 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/data.py | 259 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/meta_data.py | 204 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/meta_rules.py | 138 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/models.py | 101 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/pdp.py | 106 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/perimeter.py | 312 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/policies.py | 106 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/rules.py | 114 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/api/wrapper.py | 120 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/authz_requests.py | 159 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/containers.py | 102 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/http_server.py | 59 | ||||
-rw-r--r-- | moonv4/moon_interface/moon_interface/server.py | 3 |
15 files changed, 641 insertions, 1650 deletions
diff --git a/moonv4/moon_interface/moon_interface/api/assignments.py b/moonv4/moon_interface/moon_interface/api/assignments.py deleted file mode 100644 index 855a9049..00000000 --- a/moonv4/moon_interface/moon_interface/api/assignments.py +++ /dev/null @@ -1,264 +0,0 @@ -# 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'. -""" -Assignments allow to connect data with elements of perimeter - -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.2.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class SubjectAssignments(Resource): - """ - Endpoint for subject assignment requests - """ - - __urls__ = ( - "/policies/<string:uuid>/subject_assignments", - "/policies/<string:uuid>/subject_assignments/", - "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>", - "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>", - "/policies/<string:uuid>/subject_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", - ) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject - :param category_id: uuid of the subject category - :param data_id: uuid of the subject scope - :param user_id: user ID who do the request - :return: { - "subject_data_id": { - "policy_id": "ID of the policy", - "subject_id": "ID of the subject", - "category_id": "ID of the category", - "assignments": "Assignments list (list of data_id)", - } - } - :internal_api: get_subject_assignments - """ - return call(ctx={"id": uuid, "method": "get_subject_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): - """Create a subject assignment. - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject (not used here) - :param category_id: uuid of the subject category (not used here) - :param data_id: uuid of the subject scope (not used here) - :param user_id: user ID who do the request - :request body: { - "id": "UUID of the subject", - "category_id": "UUID of the category" - "data_id": "UUID of the scope" - } - :return: { - "subject_data_id": { - "policy_id": "ID of the policy", - "subject_id": "ID of the subject", - "category_id": "ID of the category", - "assignments": "Assignments list (list of data_id)", - } - } - :internal_api: update_subject_assignment - """ - return call("security_router", - ctx={"id": uuid, "method": "update_subject_assignment", "user_id": user_id}, args=request.json) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject - :param category_id: uuid of the subject category - :param data_id: uuid of the subject scope - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_subject_assignment - """ - return call("security_router", - ctx={"id": uuid, "method": "delete_subject_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - -class ObjectAssignments(Resource): - """ - Endpoint for object assignment requests - """ - - __urls__ = ( - "/policies/<string:uuid>/object_assignments", - "/policies/<string:uuid>/object_assignments/", - "/policies/<string:uuid>/object_assignments/<string:perimeter_id>", - "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>", - "/policies/<string:uuid>/object_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", - ) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the object - :param category_id: uuid of the object category - :param data_id: uuid of the object scope - :param user_id: user ID who do the request - :return: { - "object_data_id": { - "policy_id": "ID of the policy", - "object_id": "ID of the object", - "category_id": "ID of the category", - "assignments": "Assignments list (list of data_id)", - } - } - :internal_api: get_object_assignments - """ - return call("security_router", - ctx={"id": uuid, "method": "get_object_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): - """Create an object assignment. - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the object (not used here) - :param category_id: uuid of the object category (not used here) - :param data_id: uuid of the object scope (not used here) - :param user_id: user ID who do the request - :request body: { - "id": "UUID of the action", - "category_id": "UUID of the category" - "data_id": "UUID of the scope" - } - :return: { - "object_data_id": { - "policy_id": "ID of the policy", - "object_id": "ID of the object", - "category_id": "ID of the category", - "assignments": "Assignments list (list of data_id)", - } - } - :internal_api: update_object_assignment - """ - return call("security_router", - ctx={"id": uuid, "method": "update_object_assignment", "user_id": user_id}, args=request.json) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the object - :param category_id: uuid of the object category - :param data_id: uuid of the object scope - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_object_assignment - """ - return call("security_router", - ctx={"id": uuid, "method": "delete_object_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - -class ActionAssignments(Resource): - """ - Endpoint for action assignment requests - """ - - __urls__ = ( - "/policies/<string:uuid>/action_assignments", - "/policies/<string:uuid>/action_assignments/", - "/policies/<string:uuid>/action_assignments/<string:perimeter_id>", - "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>", - "/policies/<string:uuid>/action_assignments/<string:perimeter_id>/<string:category_id>/<string:data_id>", - ) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the action - :param category_id: uuid of the action category - :param data_id: uuid of the action scope - :param user_id: user ID who do the request - :return: { - "action_data_id": { - "policy_id": "ID of the policy", - "object_id": "ID of the action", - "category_id": "ID of the category", - "assignments": "Assignments list (list of data_id)", - } - } - :internal_api: get_action_assignments - """ - return call("security_router", ctx={"id": uuid, "method": "get_action_assignments", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - @check_auth - def post(self, uuid=None, perimeter_id=None, category_id=None, data_id=None, user_id=None): - """Create an action assignment. - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the action (not used here) - :param category_id: uuid of the action category (not used here) - :param data_id: uuid of the action scope (not used here) - :param user_id: user ID who do the request - :request body: { - "id": "UUID of the action", - "category_id": "UUID of the category", - "data_id": "UUID of the scope" - } - :return: { - "action_data_id": { - "policy_id": "ID of the policy", - "object_id": "ID of the action", - "category_id": "ID of the category", - "assignments": "Assignments list (list of data_id)", - } - } - :internal_api: update_action_assignment - """ - return call("security_router", ctx={"id": uuid, "method": "update_action_assignment", "user_id": user_id}, - args=request.json) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the action - :param category_id: uuid of the action category - :param data_id: uuid of the action scope - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_action_assignment - """ - return call("security_router", ctx={"id": uuid, "method": "delete_action_assignment", "perimeter_id": perimeter_id, "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) diff --git a/moonv4/moon_interface/moon_interface/api/authz.py b/moonv4/moon_interface/moon_interface/api/authz.py index 69de0f80..3847cc73 100644 --- a/moonv4/moon_interface/moon_interface/api/authz.py +++ b/moonv4/moon_interface/moon_interface/api/authz.py @@ -6,23 +6,194 @@ Authz is the endpoint to get authorization response """ -from uuid import uuid4 -import time +from flask import request from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call +import logging +import pickle +import requests +import time +from uuid import uuid4 + +from moon_interface.containers import DockerManager +from moon_interface.authz_requests import AuthzRequest +from moon_utilities import configuration __version__ = "0.1.0" LOG = logging.getLogger("moon.interface.api." + __name__) +def pdp_in_cache(cache, uuid): + """Check if a PDP exist with this Keystone Project ID in the cache of this component + + :param cache: Cache to use + :param uuid: Keystone Project ID + :return: True or False + """ + for item_uuid, item_value in cache.pdp.items(): + if uuid == item_value['keystone_project_id']: + return item_uuid, item_value + return None, None + + +def pdp_in_manager(cache, uuid): + """Check if a PDP exist with this Keystone Project ID in the Manager component + + :param cache: Cache to use + :param uuid: Keystone Project ID + :return: True or False + """ + cache.update() + return pdp_in_cache(cache, uuid) + + +def container_exist(cache, uuid): + """Check if a PDP exist with this Keystone Project ID in the Manager component + + :param cache: Cache to use + :param uuid: Keystone Project ID + :return: True or False + """ + for key, value in cache.containers.items(): + if "keystone_project_id" not in value: + continue + if value["keystone_project_id"] == uuid: + try: + req = requests.head("http://{}:{}/".format( + value.get("hostname"), + value.get("port")[0].get("PublicPort"))) + LOG.info("container_exist {}".format(req.status_code)) + if req.status_code in (200, 201): + return value + return + except requests.exceptions.ConnectionError: + pass + # maybe hostname is not working so trying with IP address + try: + req = requests.head("http://{}:{}/".format( + value.get("ip"), + value.get("port")[0].get("PublicPort"))) + if req.status_code in (200, 201): + return value + return + except requests.exceptions.ConnectionError: + return + + +def build_container(cache, manager_url, uuid, meta_rule_id, plugin_name="authz"): + """Create the container and update the cache with the given perimeter elements + + :param cache: Cache to use + :param manager_url: URL of the manager + :param uuid: Keystone Project ID + :param meta_rule_id: UUID of the meta_rule + :param plugin_name: name of the plugin to use + :return: True or False + """ + LOG.info("Building a new container for {}".format(plugin_name)) + manager = DockerManager() + tcp_port = configuration.increment_port() + container_name = configuration.get_plugins()[plugin_name]['container'] + name = "{}_{}".format(plugin_name, uuid4().hex) + policy_id = cache.get_policy_from_meta_rules(meta_rule_id) + container_data = { + "name": name, + "hostname": name, + "port": { + "PrivatePort": tcp_port, + "Type": "tcp", + "IP": "0.0.0.0", + "PublicPort": tcp_port + }, + "keystone_project_id": uuid, + "pdp_id": cache.get_pdp_from_keystone_project(uuid), + "meta_rule_id": meta_rule_id, + "policy_id": policy_id, + "container_name": container_name, + "plugin_name": plugin_name + } + container = manager.create_container(container_data) + container_data['container_id'] = container.id + container_data['port']["IP"] = container.ip + container_data['start_time'] = time.time() + req = requests.post("{}/containers".format(manager_url), + json=container_data) + if req.status_code == 200: + cache.add_container(container_data) + return True + + +def create_containers(cache, manager_url, uuid, plugin_name="authz"): + """Create the container and update the cache with the given perimeter elements + + :param cache: Cache to use + :param manager_url: URL of the manager + :param uuid: Keystone Project ID + :param plugin_name: name of the plugin to use + :return: True or False + """ + LOG.info("Need to create some containers for {}".format(uuid)) + for pdp_id, pdp_value in cache.pdp.items(): + LOG.info("pdp {}".format(pdp_value)) + if uuid == pdp_value.get("keystone_project_id", ""): + LOG.info("uuid {}".format(uuid)) + for policy_id in pdp_value.get("security_pipeline", []): + LOG.info("policy {}".format(policy_id)) + model_id = cache.policies[policy_id]["model_id"] + model_value = cache.models[model_id] + for meta_rule_id in model_value["meta_rules"]: + LOG.info("meta_rule {}".format(meta_rule_id)) + build_container( + cache=cache, + uuid=uuid, + manager_url=manager_url, + meta_rule_id=meta_rule_id, + plugin_name=plugin_name) + return + + +def create_authz_request(cache, interface_name, manager_url, uuid, subject_name, object_name, action_name): + """Create the authorization request and make the first call to the Authz function + + :param cache: Cache to use + :param interface_name: hostname of the interface + :param manager_url: URL of the manager + :param uuid: Keystone Project ID + :param subject_name: name of the subject + :param object_name: name of the object + :param action_name: name of the action + :return: Authorisation request + """ + req_id = uuid4().hex + ctx = { + "project_id": uuid, + "subject_name": subject_name, + "object_name": object_name, + "action_name": action_name, + "request_id": req_id, + "interface_name": interface_name, + "manager_url": manager_url, + "cookie": uuid4().hex + } + cache.authz_requests[req_id] = AuthzRequest(ctx) + return cache.authz_requests[req_id] + + class Authz(Resource): """ Endpoint for authz requests """ - __urls__ = ("/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>", ) + __urls__ = ( + "/authz/<string:uuid>", + "/authz/<string:uuid>/<string:subject_name>/<string:object_name>/<string:action_name>", + ) + + 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 get(self, uuid=None, subject_name=None, object_name=None, action_name=None): """Get a response on an authorization request @@ -51,17 +222,52 @@ class Authz(Resource): } :internal_api: authz """ - # Note (asteroide): user_id default to admin to be able to read the database - # it would be better to have a read-only user. - start_time = time.time() - result = call("security_router", ctx={"id": uuid, - "call_master": False, - "method": "authz", - "subject_name": subject_name, - "object_name": object_name, - "action_name": action_name, - "user_id": "admin", - "request_id": uuid4().hex}, args={}) - end_time = time.time() - result['time'] = {"start": start_time, "end": end_time} - return result + pdp_id, pdp_value = pdp_in_cache(self.CACHE, uuid) + if not pdp_id: + pdp_id, pdp_value = pdp_in_manager(self.CACHE, uuid) + if not pdp_id: + return { + "result": False, + "message": "Unknown Project ID or " + "Project ID is not bind to a PDP."}, 403 + if not container_exist(self.CACHE, uuid): + create_containers( + cache=self.CACHE, + uuid=uuid, + manager_url=self.MANAGER_URL, + plugin_name="authz") + authz_request = create_authz_request( + cache=self.CACHE, + uuid=uuid, + interface_name=self.INTERFACE_NAME, + manager_url=self.MANAGER_URL, + subject_name=subject_name, + object_name=object_name, + action_name=action_name) + cpt = 0 + while True: + if cpt > self.TIMEOUT*10: + return {"result": False, + "message": "Authz request had timed out."}, 500 + if authz_request.is_authz(): + if authz_request.final_result == "Grant": + return {"result": True, "message": ""}, 200 + return {"result": False, "message": ""}, 401 + cpt += 1 + time.sleep(0.1) + + def patch(self, uuid=None, subject_name=None, object_name=None, action_name=None): + """Get a response on an authorization request + + :param uuid: uuid of the authorization request + :param subject_name: not used + :param object_name: not used + :param action_name: not used + :request body: a Context object + :return: {} + :internal_api: authz + """ + if uuid in self.CACHE.authz_requests: + self.CACHE.authz_requests[uuid].set_result(pickle.loads(request.data)) + return "", 201 + return {"result": False, "message": "The request ID is unknown"}, 500 diff --git a/moonv4/moon_interface/moon_interface/api/data.py b/moonv4/moon_interface/moon_interface/api/data.py deleted file mode 100644 index 6d959095..00000000 --- a/moonv4/moon_interface/moon_interface/api/data.py +++ /dev/null @@ -1,259 +0,0 @@ -# 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'. -""" -Data are elements used to create rules - -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.2.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class SubjectData(Resource): - """ - Endpoint for subject data requests - """ - - __urls__ = ( - "/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>", - ) - - @check_auth - def get(self, uuid=None, category_id=None, data_id=None, user_id=None): - """Retrieve all subject categories or a specific one if sid is given for a given policy - - :param uuid: uuid of the policy - :param category_id: uuid of the subject category - :param data_id: uuid of the subject data - :param user_id: user ID who do the request - :return: [{ - "policy_id": "policy_id1", - "category_id": "category_id1", - "data": { - "subject_data_id": { - "name": "name of the data", - "description": "description of the data" - } - } - }] - :internal_api: get_subject_data - """ - return call("security_router", ctx={"id": uuid, "method": "get_subject_data", "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - @check_auth - 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 - :param category_id: uuid of the subject category - :param data_id: uuid of the subject data - :param user_id: user ID who do the request - :request body: { - "name": "name of the data", - "description": "description of the data" - } - :return: { - "policy_id": "policy_id1", - "category_id": "category_id1", - "data": { - "subject_data_id": { - "name": "name of the data", - "description": "description of the data" - } - } - } - :internal_api: add_subject_data - """ - return call("security_router", ctx={"id": uuid, "method": "add_subject_data", "category_id": category_id, "user_id": user_id}, - args=request.json) - - @check_auth - 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 - :param category_id: uuid of the subject category - :param data_id: uuid of the subject data - :param user_id: user ID who do the request - :return: [{ - "result": "True or False", - "message": "optional message" - }] - :internal_api: delete_subject_data - """ - return call("security_router", ctx={"id": uuid, "method": "delete_subject_data", "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - -class ObjectData(Resource): - """ - Endpoint for object data requests - """ - - __urls__ = ( - "/policies/<string:uuid>/object_data", - "/policies/<string:uuid>/object_data/", - "/policies/<string:uuid>/object_data/<string:category_id>", - "/policies/<string:uuid>/object_data/<string:category_id>/<string:data_id>", - ) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param category_id: uuid of the object category - :param data_id: uuid of the object data - :param user_id: user ID who do the request - :return: [{ - "policy_id": "policy_id1", - "category_id": "category_id1", - "data": { - "object_data_id": { - "name": "name of the data", - "description": "description of the data" - } - } - }] - :internal_api: get_object_data - """ - return call("security_router", ctx={"id": uuid, "method": "get_object_data", "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - @check_auth - 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 - :param category_id: uuid of the object category - :param data_id: uuid of the object data - :param user_id: user ID who do the request - :request body: { - "name": "name of the data", - "description": "description of the data" - } - :return: { - "policy_id": "policy_id1", - "category_id": "category_id1", - "data": { - "object_data_id": { - "name": "name of the data", - "description": "description of the data" - } - } - } - :internal_api: add_object_data - """ - return call("security_router", ctx={"id": uuid, "method": "add_object_data", "category_id": category_id, "user_id": user_id}, args=request.json) - - @check_auth - 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 - :param category_id: uuid of the object category - :param data_id: uuid of the object data - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_object_data - """ - return call("security_router", ctx={"id": uuid, "method": "delete_object_data", "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - -class ActionData(Resource): - """ - Endpoint for action data requests - """ - - __urls__ = ( - "/policies/<string:uuid>/action_data", - "/policies/<string:uuid>/action_data/", - "/policies/<string:uuid>/action_data/<string:category_id>", - "/policies/<string:uuid>/action_data/<string:category_id>/<string:data_id>", - ) - - @check_auth - 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 - - :param uuid: uuid of the policy - :param category_id: uuid of the action category - :param data_id: uuid of the action data - :param user_id: user ID who do the request - :return: [{ - "policy_id": "policy_id1", - "category_id": "category_id1", - "data": { - "action_data_id": { - "name": "name of the data", - "description": "description of the data" - } - } - }] - :internal_api: get_action_data - """ - return call("security_router", ctx={"id": uuid, "method": "get_action_data", "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - @check_auth - 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 - :param category_id: uuid of the action category - :param data_id: uuid of the action data - :param user_id: user ID who do the request - :request body: { - "name": "name of the data", - "description": "description of the data" - } - :return: { - "policy_id": "policy_id1", - "category_id": "category_id1", - "data": { - "action_data_id": { - "name": "name of the data", - "description": "description of the data" - } - } - } - :internal_api: add_action_data - """ - return call("security_router", ctx={"id": uuid, "method": "add_action_data", "category_id": category_id, "user_id": user_id}, - args=request.json) - - @check_auth - 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 - :param category_id: uuid of the action category - :param data_id: uuid of the action data - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_action_data - """ - return call("security_router", ctx={"id": uuid, "method": "delete_action_data", "category_id": category_id, "user_id": user_id}, - args={"data_id": data_id}) - - diff --git a/moonv4/moon_interface/moon_interface/api/meta_data.py b/moonv4/moon_interface/moon_interface/api/meta_data.py deleted file mode 100644 index 3c933759..00000000 --- a/moonv4/moon_interface/moon_interface/api/meta_data.py +++ /dev/null @@ -1,204 +0,0 @@ -# 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'. -""" -Meta Data are elements used to create Meta data (skeleton of security policies) - -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.2.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class SubjectCategories(Resource): - """ - Endpoint for subject categories requests - """ - - __urls__ = ( - "/subject_categories", - "/subject_categories/", - "/subject_categories/<string:category_id>", - ) - - @check_auth - def get(self, category_id=None, user_id=None): - """Retrieve all subject categories or a specific one - - :param category_id: uuid of the subject category - :param user_id: user ID who do the request - :return: { - "subject_category_id": { - "name": "name of the category", - "description": "description of the category" - } - } - :internal_api: get_subject_categories - """ - return call("security_router", ctx={"method": "get_subject_categories", "user_id": user_id}, args={"category_id": category_id}) - - @check_auth - def post(self, category_id=None, user_id=None): - """Create or update a subject category. - - :param category_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the category", - "description": "description of the category" - } - :return: { - "subject_category_id": { - "name": "name of the category", - "description": "description of the category" - } - } - :internal_api: add_subject_category - """ - return call("security_router", ctx={"method": "set_subject_category", "user_id": user_id}, args=request.json) - - @check_auth - def delete(self, category_id=None, user_id=None): - """Delete a subject category - - :param category_id: uuid of the subject category to delete - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_subject_category - """ - return call("security_router", ctx={"method": "delete_subject_category", "user_id": user_id}, args={"category_id": category_id}) - - -class ObjectCategories(Resource): - """ - Endpoint for object categories requests - """ - - __urls__ = ( - "/object_categories", - "/object_categories/", - "/object_categories/<string:category_id>", - ) - - @check_auth - def get(self, category_id=None, user_id=None): - """Retrieve all object categories or a specific one - - :param category_id: uuid of the object category - :param user_id: user ID who do the request - :return: { - "object_category_id": { - "name": "name of the category", - "description": "description of the category" - } - } - :internal_api: get_object_categories - """ - return call("security_router", ctx={"method": "get_object_categories", "user_id": user_id}, args={"category_id": category_id}) - - @check_auth - def post(self, category_id=None, user_id=None): - """Create or update a object category. - - :param category_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the category", - "description": "description of the category" - } - :return: { - "object_category_id": { - "name": "name of the category", - "description": "description of the category" - } - } - :internal_api: add_object_category - """ - return call("security_router", ctx={"method": "set_object_category", "user_id": user_id}, args=request.json) - - @check_auth - def delete(self, category_id=None, user_id=None): - """Delete an object category - - :param category_id: uuid of the object category to delete - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_object_category - """ - return call("security_router", ctx={"method": "delete_object_category", "user_id": user_id}, args={"category_id": category_id}) - - -class ActionCategories(Resource): - """ - Endpoint for action categories requests - """ - - __urls__ = ( - "/action_categories", - "/action_categories/", - "/action_categories/<string:category_id>", - ) - - @check_auth - def get(self, category_id=None, user_id=None): - """Retrieve all action categories or a specific one - - :param category_id: uuid of the action category - :param user_id: user ID who do the request - :return: { - "action_category_id": { - "name": "name of the category", - "description": "description of the category" - } - } - :internal_api: get_action_categories - """ - return call("security_router", ctx={"method": "get_action_categories", "user_id": user_id}, args={"category_id": category_id}) - - @check_auth - def post(self, category_id=None, user_id=None): - """Create or update an action category. - - :param category_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the category", - "description": "description of the category" - } - :return: { - "action_category_id": { - "name": "name of the category", - "description": "description of the category" - } - } - :internal_api: add_action_category - """ - return call("security_router", ctx={"method": "set_action_category", "user_id": user_id}, args=request.json) - - @check_auth - def delete(self, category_id=None, user_id=None): - """Delete an action - - :param category_id: uuid of the action category to delete - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_action_category - """ - return call("security_router", ctx={"method": "delete_action_category", "user_id": user_id}, args={"category_id": category_id}) diff --git a/moonv4/moon_interface/moon_interface/api/meta_rules.py b/moonv4/moon_interface/moon_interface/api/meta_rules.py deleted file mode 100644 index 85072243..00000000 --- a/moonv4/moon_interface/moon_interface/api/meta_rules.py +++ /dev/null @@ -1,138 +0,0 @@ -# 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'. -""" -Meta rules are skeleton for security policies - -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.1.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class MetaRules(Resource): - """ - Endpoint for meta rules requests - """ - - __urls__ = ("/meta_rules", - "/meta_rules/", - "/meta_rules/<string:meta_rule_id>", - "/meta_rules/<string:meta_rule_id>/") - - @check_auth - def get(self, meta_rule_id=None, user_id=None): - """Retrieve all sub meta rules - - :param meta_rule_id: Meta rule algorithm ID - :param user_id: user ID who do the request - :return: { - "meta_rules": { - "meta_rule_id1": { - "name": "name of the meta rule", - "algorithm": "name of the meta rule algorithm", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - }, - } - } - :internal_api: get_meta_rules - """ - return call("security_router", ctx={"method": "get_meta_rules", - "user_id": user_id, - "meta_rule_id": meta_rule_id}, args={}) - - @check_auth - def post(self, meta_rule_id=None, user_id=None): - """Add a meta rule - - :param meta_rule_id: Meta rule ID - :param user_id: user ID who do the request - :request body: post = { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - } - :return: { - "meta_rules": { - "meta_rule_id1": { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - }, - } - } - :internal_api: add_meta_rules - """ - return call("security_router", ctx={"method": "add_meta_rules", - "user_id": user_id, - "meta_rule_id": meta_rule_id}, args=request.json) - - @check_auth - def patch(self, meta_rule_id=None, user_id=None): - """Update a meta rule - - :param meta_rule_id: Meta rule ID - :param user_id: user ID who do the request - :request body: patch = { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - } - :return: { - "meta_rules": { - "meta_rule_id1": { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - }, - } - } - :internal_api: set_meta_rules - """ - return call("security_router", ctx={"method": "set_meta_rules", - "user_id": user_id, - "meta_rule_id": meta_rule_id}, args=request.json) - - @check_auth - def delete(self, meta_rule_id=None, user_id=None): - """Delete a meta rule - - :param meta_rule_id: Meta rule ID - :param user_id: user ID who do the request - :request body: delete = { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - } - :return: { - "meta_rules": { - "meta_rule_id1": { - "name": "name of the meta rule", - "subject_categories": ["subject_category_id1", "subject_category_id2"], - "object_categories": ["object_category_id1"], - "action_categories": ["action_category_id1"] - }, - } - } - :internal_api: delete_meta_rules - """ - return call("security_router", ctx={"method": "delete_meta_rules", - "user_id": user_id, - "meta_rule_id": meta_rule_id}, args=request.json) - - diff --git a/moonv4/moon_interface/moon_interface/api/models.py b/moonv4/moon_interface/moon_interface/api/models.py deleted file mode 100644 index f905db63..00000000 --- a/moonv4/moon_interface/moon_interface/api/models.py +++ /dev/null @@ -1,101 +0,0 @@ -# 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'. -""" -Models aggregate multiple meta rules -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.1.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class Models(Resource): - """ - Endpoint for model requests - """ - - __urls__ = ( - "/models", - "/models/", - "/models/<string:uuid>", - "/models/<string:uuid>/", - ) - - @check_auth - def get(self, uuid=None, user_id=None): - """Retrieve all models - - :param uuid: uuid of the model - :param user_id: user ID who do the request - :return: { - "model_id1": { - "name": "...", - "description": "...", - "meta_rules": ["meta_rule_id1", ] - } - } - :internal_api: get_models - """ - return call("security_router", ctx={"id": uuid, "method": "get_models", "user_id": user_id}, args={}) - - @check_auth - def post(self, uuid=None, user_id=None): - """Create model. - - :param uuid: uuid of the model (not used here) - :param user_id: user ID who do the request - :request body: { - "name": "...", - "description": "...", - "meta_rules": ["meta_rule_id1", ] - } - :return: { - "model_id1": { - "name": "...", - "description": "...", - "meta_rules": ["meta_rule_id1", ] - } - } - :internal_api: add_model - """ - return call("security_router", ctx={"id": uuid, "method": "add_model", "user_id": user_id}, args=request.json) - - @check_auth - def delete(self, uuid=None, user_id=None): - """Delete a model - - :param uuid: uuid of the model to delete - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_model - """ - return call("security_router", ctx={"id": uuid, "method": "delete_model", "user_id": user_id}, args={}) - - @check_auth - def patch(self, uuid=None, user_id=None): - """Update a model - - :param uuid: uuid of the model to update - :param user_id: user ID who do the request - :return: { - "model_id1": { - "name": "...", - "description": "...", - "meta_rules": ["meta_rule_id1", ] - } - } - :internal_api: update_model - """ - return call("security_router", ctx={"id": uuid, "method": "update_model", "user_id": user_id}, args=request.json) - diff --git a/moonv4/moon_interface/moon_interface/api/pdp.py b/moonv4/moon_interface/moon_interface/api/pdp.py deleted file mode 100644 index 5316227b..00000000 --- a/moonv4/moon_interface/moon_interface/api/pdp.py +++ /dev/null @@ -1,106 +0,0 @@ -# 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'. -""" -PDP are Policy Decision Point. - -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.1.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class PDP(Resource): - """ - Endpoint for pdp requests - """ - - __urls__ = ( - "/pdp", - "/pdp/", - "/pdp/<string:uuid>", - "/pdp/<string:uuid>/", - ) - - @check_auth - def get(self, uuid=None, user_id=None): - """Retrieve all pdp - - :param uuid: uuid of the pdp - :param user_id: user ID who do the request - :return: { - "pdp_id1": { - "name": "...", - "security_pipeline": [...], - "keystone_project_id": "keystone_project_id1", - "description": "...", - } - } - :internal_api: get_pdp - """ - return call("security_router", ctx={"id": uuid, "method": "get_pdp", "user_id": user_id}, args={}) - - @check_auth - def post(self, uuid=None, user_id=None): - """Create pdp. - - :param uuid: uuid of the pdp (not used here) - :param user_id: user ID who do the request - :request body: { - "name": "...", - "security_pipeline": [...], - "keystone_project_id": "keystone_project_id1", - "description": "...", - } - :return: { - "pdp_id1": { - "name": "...", - "security_pipeline": [...], - "keystone_project_id": "keystone_project_id1", - "description": "...", - } - } - :internal_api: add_pdp - """ - return call("security_router", ctx={"id": uuid, "method": "add_pdp", "user_id": user_id}, args=request.json) - - @check_auth - def delete(self, uuid=None, user_id=None): - """Delete a pdp - - :param uuid: uuid of the pdp to delete - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_pdp - """ - return call("security_router", ctx={"id": uuid, "method": "delete_pdp", "user_id": user_id}, args={}) - - @check_auth - def patch(self, uuid=None, user_id=None): - """Update a pdp - - :param uuid: uuid of the pdp to update - :param user_id: user ID who do the request - :return: { - "pdp_id1": { - "name": "...", - "security_pipeline": [...], - "keystone_project_id": "keystone_project_id1", - "description": "...", - } - } - :internal_api: update_pdp - """ - return call("security_router", ctx={"id": uuid, "method": "update_pdp", "user_id": user_id}, args=request.json) - diff --git a/moonv4/moon_interface/moon_interface/api/perimeter.py b/moonv4/moon_interface/moon_interface/api/perimeter.py deleted file mode 100644 index 177161f6..00000000 --- a/moonv4/moon_interface/moon_interface/api/perimeter.py +++ /dev/null @@ -1,312 +0,0 @@ -# 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'. -""" -* Subjects are the source of an action on an object (examples : users, virtual machines) -* Objects are the destination of an action (examples virtual machines, virtual Routers) -* Actions are what subject wants to do on an object -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.2.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class Subjects(Resource): - """ - Endpoint for subjects requests - """ - - __urls__ = ( - "/subjects", - "/subjects/", - "/subjects/<string:perimeter_id>", - "/policies/<string:uuid>/subjects", - "/policies/<string:uuid>/subjects/", - "/policies/<string:uuid>/subjects/<string:perimeter_id>", - ) - - @check_auth - def get(self, uuid=None, perimeter_id=None, user_id=None): - """Retrieve all subjects or a specific one if perimeter_id is given for a given policy - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject - :param user_id: user ID who do the request - :return: { - "subject_id": { - "name": "name of the subject", - "keystone_id": "keystone id of the subject", - "description": "a description" - } - } - :internal_api: get_subjects - """ - return call("security_router", ctx={"id": uuid, "method": "get_subjects", "user_id": user_id}, args={"perimeter_id": perimeter_id}) - - @check_auth - def post(self, uuid=None, perimeter_id=None, user_id=None): - """Create or update a subject. - - :param uuid: uuid of the policy - :param perimeter_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" - } - :return: { - "subject_id": { - "name": "name of the subject", - "keystone_id": "keystone id of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" - } - } - :internal_api: set_subject - """ - return call("security_router", ctx={"id": uuid, "method": "set_subject", "user_id": user_id, "perimeter_id": None}, - args=request.json) - - @check_auth - def patch(self, uuid=None, perimeter_id=None, user_id=None): - """Create or update a subject. - - :param uuid: uuid of the policy - :param perimeter_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" - } - :return: { - "subject_id": { - "name": "name of the subject", - "keystone_id": "keystone id of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" - } - } - :internal_api: set_subject - """ - return call("security_router", ctx={"id": uuid, "method": "set_subject", "user_id": user_id, "perimeter_id": perimeter_id}, - args=request.json) - - @check_auth - def delete(self, uuid=None, perimeter_id=None, user_id=None): - """Delete a subject for a given policy - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the subject - :param user_id: user ID who do the request - :return: { - "subject_id": { - "name": "name of the subject", - "keystone_id": "keystone id of the subject", - "description": "description of the subject", - "password": "password for the subject", - "email": "email address of the subject" - } - } - :internal_api: delete_subject - """ - return call("security_router", ctx={"id": uuid, "method": "delete_subject", "user_id": user_id}, args={"perimeter_id": perimeter_id}) - - -class Objects(Resource): - """ - Endpoint for objects requests - """ - - __urls__ = ( - "/objects", - "/objects/", - "/objects/<string:perimeter_id>", - "/policies/<string:uuid>/objects", - "/policies/<string:uuid>/objects/", - "/policies/<string:uuid>/objects/<string:perimeter_id>", - ) - - @check_auth - def get(self, uuid=None, perimeter_id=None, user_id=None): - """Retrieve all objects or a specific one if perimeter_id is given for a given policy - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the object - :param user_id: user ID who do the request - :return: { - "object_id": { - "name": "name of the object", - "description": "description of the object" - } - } - :internal_api: get_objects - """ - return call("security_router", ctx={"id": uuid, "method": "get_objects", "user_id": user_id}, args={"perimeter_id": perimeter_id}) - - @check_auth - def post(self, uuid=None, perimeter_id=None, user_id=None): - """Create or update a object. - - :param uuid: uuid of the policy - :param perimeter_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "object_name": "name of the object", - "object_description": "description of the object" - } - :return: { - "object_id": { - "name": "name of the object", - "description": "description of the object" - } - } - :internal_api: set_object - """ - return call("security_router", ctx={"id": uuid, "method": "set_object", "user_id": user_id, "perimeter_id": None}, - args=request.json) - - @check_auth - def patch(self, uuid=None, perimeter_id=None, user_id=None): - """Create or update a object. - - :param uuid: uuid of the policy - :param perimeter_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "object_name": "name of the object", - "object_description": "description of the object" - } - :return: { - "object_id": { - "name": "name of the object", - "description": "description of the object" - } - } - :internal_api: set_object - """ - return call("security_router", ctx={"id": uuid, "method": "set_object", "user_id": user_id, "perimeter_id": perimeter_id}, - args=request.json) - - @check_auth - def delete(self, uuid=None, perimeter_id=None, user_id=None): - """Delete a object for a given policy - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the object - :param user_id: user ID who do the request - :return: { - "object_id": { - "name": "name of the object", - "description": "description of the object" - } - } - :internal_api: delete_object - """ - return call("security_router", ctx={"id": uuid, "method": "delete_object", "user_id": user_id}, args={"perimeter_id": perimeter_id}) - - -class Actions(Resource): - """ - Endpoint for actions requests - """ - - __urls__ = ( - "/actions", - "/actions/", - "/actions/<string:perimeter_id>", - "/policies/<string:uuid>/actions", - "/policies/<string:uuid>/actions/", - "/policies/<string:uuid>/actions/<string:perimeter_id>", - ) - - @check_auth - def get(self, uuid=None, perimeter_id=None, user_id=None): - """Retrieve all actions or a specific one if perimeter_id is given for a given policy - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the action - :param user_id: user ID who do the request - :return: { - "action_id": { - "name": "name of the action", - "description": "description of the action" - } - } - :internal_api: get_actions - """ - return call("security_router", ctx={"id": uuid, "method": "get_actions", "user_id": user_id}, args={"perimeter_id": perimeter_id}) - - @check_auth - def post(self, uuid=None, perimeter_id=None, user_id=None): - """Create or update a action. - - :param uuid: uuid of the policy - :param perimeter_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the action", - "description": "description of the action" - } - :return: { - "action_id": { - "name": "name of the action", - "description": "description of the action" - } - } - :internal_api: set_action - """ - return call("security_router", ctx={"id": uuid, "method": "set_action", "user_id": user_id, "perimeter_id": None}, - args=request.json) - - @check_auth - def patch(self, uuid=None, perimeter_id=None, user_id=None): - """Create or update a action. - - :param uuid: uuid of the policy - :param perimeter_id: must not be used here - :param user_id: user ID who do the request - :request body: { - "name": "name of the action", - "description": "description of the action" - } - :return: { - "action_id": { - "name": "name of the action", - "description": "description of the action" - } - } - :internal_api: set_action - """ - return call("security_router", ctx={"id": uuid, "method": "set_action", "user_id": user_id, "perimeter_id": perimeter_id}, - args=request.json) - - @check_auth - def delete(self, uuid=None, perimeter_id=None, user_id=None): - """Delete a action for a given policy - - :param uuid: uuid of the policy - :param perimeter_id: uuid of the action - :param user_id: user ID who do the request - :return: { - "action_id": { - "name": "name of the action", - "description": "description of the action" - } - } - :internal_api: delete_action - """ - return call("security_router", ctx={"id": uuid, "method": "delete_action", "user_id": user_id}, args={"perimeter_id": perimeter_id}) diff --git a/moonv4/moon_interface/moon_interface/api/policies.py b/moonv4/moon_interface/moon_interface/api/policies.py deleted file mode 100644 index 5a84b612..00000000 --- a/moonv4/moon_interface/moon_interface/api/policies.py +++ /dev/null @@ -1,106 +0,0 @@ -# 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'. -""" -Policies are instances of security models and implement security policies - -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.1.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class Policies(Resource): - """ - Endpoint for policy requests - """ - - __urls__ = ( - "/policies", - "/policies/", - "/policies/<string:uuid>", - "/policies/<string:uuid>/", - ) - - @check_auth - def get(self, uuid=None, user_id=None): - """Retrieve all policies - - :param uuid: uuid of the policy - :param user_id: user ID who do the request - :return: { - "policy_id1": { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", - } - } - :internal_api: get_policies - """ - return call("security_router", ctx={"id": uuid, "method": "get_policies", "user_id": user_id}, args={}) - - @check_auth - def post(self, uuid=None, user_id=None): - """Create policy. - - :param uuid: uuid of the policy (not used here) - :param user_id: user ID who do the request - :request body: { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", - } - :return: { - "policy_id1": { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", - } - } - :internal_api: add_policy - """ - return call("security_router", ctx={"id": uuid, "method": "add_policy", "user_id": user_id}, args=request.json) - - @check_auth - def delete(self, uuid=None, user_id=None): - """Delete a policy - - :param uuid: uuid of the policy to delete - :param user_id: user ID who do the request - :return: { - "result": "True or False", - "message": "optional message" - } - :internal_api: delete_policy - """ - return call("security_router", ctx={"id": uuid, "method": "delete_policy", "user_id": user_id}, args={}) - - @check_auth - def patch(self, uuid=None, user_id=None): - """Update a policy - - :param uuid: uuid of the policy to update - :param user_id: user ID who do the request - :return: { - "policy_id1": { - "name": "...", - "model_id": "...", - "genre": "...", - "description": "...", - } - } - :internal_api: update_policy - """ - return call("security_router", ctx={"id": uuid, "method": "update_policy", "user_id": user_id}, args=request.json) - diff --git a/moonv4/moon_interface/moon_interface/api/rules.py b/moonv4/moon_interface/moon_interface/api/rules.py deleted file mode 100644 index 1111729c..00000000 --- a/moonv4/moon_interface/moon_interface/api/rules.py +++ /dev/null @@ -1,114 +0,0 @@ -# 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'. -""" -Rules (TODO) -""" - -from flask import request -from flask_restful import Resource -from oslo_log import log as logging -from moon_utilities.security_functions import call -from moon_utilities.security_functions import check_auth - -__version__ = "0.1.0" - -LOG = logging.getLogger("moon.interface.api." + __name__) - - -class Rules(Resource): - """ - Endpoint for rules requests - """ - - __urls__ = ("/policies/<string:uuid>/rules", - "/policies/<string:uuid>/rules/", - "/policies/<string:uuid>/rules/<string:rule_id>", - "/policies/<string:uuid>/rules/<string:rule_id>/", - ) - - @check_auth - def get(self, uuid=None, rule_id=None, user_id=None): - """Retrieve all rules or a specific one - - :param uuid: policy ID - :param rule_id: rule ID - :param user_id: user ID who do the request - :return: { - "rules": [ - "policy_id": "policy_id1", - "meta_rule_id": "meta_rule_id1", - "rule_id1": ["subject_data_id1", "object_data_id1", "action_data_id1"], - "rule_id2": ["subject_data_id2", "object_data_id2", "action_data_id2"], - ] - } - :internal_api: get_rules - """ - return call("security_router", ctx={"id": uuid, - "method": "get_rules", - "user_id": user_id, - "rule_id": rule_id}, args={}) - - @check_auth - def post(self, uuid=None, rule_id=None, user_id=None): - """Add a rule to a meta rule - - :param uuid: policy ID - :param rule_id: rule ID - :param user_id: user ID who do the request - :request body: post = { - "meta_rule_id": "meta_rule_id1", - "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"], - "instructions": ( - {"decision": "grant"}, - ) - "enabled": True - } - :return: { - "rules": [ - "meta_rule_id": "meta_rule_id1", - "rule_id1": { - "rule": ["subject_data_id1", "object_data_id1", "action_data_id1"], - "instructions": ( - {"decision": "grant"}, # "grant" to immediately exit, - # "continue" to wait for the result of next policy - # "deny" to deny the request - ) - } - "rule_id2": { - "rule": ["subject_data_id2", "object_data_id2", "action_data_id2"], - "instructions": ( - { - "update": { - "operation": "add", # operations may be "add" or "delete" - "target": "rbac:role:admin" # add the role admin to the current user - } - }, - {"chain": {"name": "rbac"}} # chain with the policy named rbac - ) - } - ] - } - :internal_api: add_rule - """ - return call("security_router", ctx={"id": uuid, - "method": "add_rule", - "user_id": user_id, - "rule_id": rule_id}, args=request.json) - - @check_auth - def delete(self, uuid=None, rule_id=None, user_id=None): - """Delete one rule linked to a specific sub meta rule - - :param uuid: policy ID - :param rule_id: rule ID - :param user_id: user ID who do the request - :return: { "result": true } - :internal_api: delete_rule - """ - return call("security_router", ctx={"id": uuid, - "method": "delete_rule", - "user_id": user_id, - "rule_id": rule_id}, args={}) - diff --git a/moonv4/moon_interface/moon_interface/api/wrapper.py b/moonv4/moon_interface/moon_interface/api/wrapper.py new file mode 100644 index 00000000..5ba5779f --- /dev/null +++ b/moonv4/moon_interface/moon_interface/api/wrapper.py @@ -0,0 +1,120 @@ +# 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 flask +from flask import request +from flask_restful import Resource +import logging +import json +import requests +import time +from uuid import uuid4 + +from moon_interface.api.authz import pdp_in_cache, pdp_in_manager, container_exist, \ + create_containers, create_authz_request +from moon_interface.authz_requests import AuthzRequest +from moon_utilities import configuration + +__version__ = "0.1.0" + +LOG = logging.getLogger("moon.interface.api." + __name__) + + +class Wrapper(Resource): + """ + Endpoint for authz requests + """ + + __urls__ = ( + "/authz/wrapper", + "/authz/wrapper/", + ) + + def __init__(self, **kwargs): + self.port = kwargs.get("port") + 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 get(self): + LOG.info("GET") + return self.manage_data() + + def post(self): + LOG.info("POST {}".format(request.form)) + response = flask.make_response("False") + if self.manage_data(): + response = flask.make_response("True") + response.headers['content-type'] = 'application/octet-stream' + return response + + @staticmethod + def __get_subject(target, credentials): + _subject = target.get("user_id", "") + if not _subject: + _subject = credentials.get("user_id", "none") + return _subject + + @staticmethod + def __get_object(target, credentials): + try: + # note: case of Glance + return target['target']['name'] + except KeyError: + pass + + # note: default case + return target.get("project_id", "none") + + @staticmethod + def __get_project_id(target, credentials): + return target.get("project_id", "none") + + def manage_data(self): + target = json.loads(request.form.get('target', {})) + credentials = json.loads(request.form.get('credentials', {})) + rule = request.form.get('rule', "") + _subject = self.__get_subject(target, credentials) + _object = self.__get_object(target, credentials) + _project_id = self.__get_project_id(target, credentials) + LOG.info("GET with args project={} / " + "subject={} - object={} - action={}".format( + _project_id, _subject, _object, rule)) + pdp_id, pdp_value = pdp_in_cache(self.CACHE, _project_id) + if not pdp_id: + pdp_id, pdp_value = pdp_in_manager(self.CACHE, _project_id) + if not pdp_id: + LOG.error("Unknown Project ID or " + "Project ID is not bind to a PDP.") + return False + if not container_exist(self.CACHE, _project_id): + create_containers(self.CACHE, _project_id, self.MANAGER_URL, + plugin_name="authz") + authz_request = create_authz_request( + cache=self.CACHE, + uuid=_project_id, + interface_name=self.INTERFACE_NAME, + manager_url=self.MANAGER_URL, + subject_name=_subject, + object_name=_object, + action_name=rule) + cpt = 0 + while True: + LOG.info("Wait") + if cpt > self.TIMEOUT*10: + LOG.error("Authz request had timed out.") + return False + if authz_request.is_authz(): + if authz_request.final_result == "Grant": + LOG.info("Grant") + return True + LOG.info("Deny") + return False + cpt += 1 + time.sleep(0.1) diff --git a/moonv4/moon_interface/moon_interface/authz_requests.py b/moonv4/moon_interface/moon_interface/authz_requests.py new file mode 100644 index 00000000..2eb5fd19 --- /dev/null +++ b/moonv4/moon_interface/moon_interface/authz_requests.py @@ -0,0 +1,159 @@ +# 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'. + +import logging +import itertools +import pickle +import requests +from moon_utilities import configuration, exceptions +from moon_utilities.security_functions import Context +from moon_utilities.cache import Cache + +LOG = logging.getLogger("moon.interface.authz_requests") + + +CACHE = Cache() +CACHE.update() + + +class AuthzRequest: + + result = None + final_result = "Deny" + req_max_delay = 2 + + def __init__(self, ctx, args=None): + self.context = Context(ctx, CACHE) + self.args = args + self.request_id = ctx["request_id"] + if ctx['project_id'] not in CACHE.container_chaining: + raise exceptions.KeystoneProjectError("Unknown Project ID {}".format(ctx['project_id'])) + self.container_chaining = CACHE.container_chaining[ctx['project_id']] + if len(self.container_chaining) == 0: + raise exceptions.MoonError('Void container chaining') + self.pdp_container = self.container_chaining[0]["container_id"] + self.run() + + def run(self): + self.context.delete_cache() + try: + req = requests.post("http://{}:{}/authz".format( + self.container_chaining[0]["hostname"], + self.container_chaining[0]["port"], + ), data=pickle.dumps(self.context)) + if req.status_code != 200: + # LOG.error("Cannot connect to {}".format( + # "http://{}:{}/authz".format( + # self.container_chaining[0]["hostname"], + # self.container_chaining[0]["port"] + # ))) + raise exceptions.AuthzException( + "Receive bad response from Authz function " + "(with hostname - {})".format( + req.status_code + )) + except requests.exceptions.ConnectionError: + try: + req = requests.post("http://{}:{}/authz".format( + self.container_chaining[0]["hostip"], + self.container_chaining[0]["port"], + ), data=pickle.dumps(self.context)) + if req.status_code != 200: + # LOG.error("req={}".format(req)) + raise exceptions.AuthzException( + "Receive bad response from Authz function " + "(with IP address - {})".format( + req.status_code + )) + except requests.exceptions.ConnectionError: + LOG.error("Cannot connect to {}".format( + "http://{}:{}/authz".format( + self.container_chaining[0]["hostip"], + self.container_chaining[0]["port"] + ))) + raise exceptions.AuthzException( + "Cannot connect to Authz function with IP address") + self.context.set_cache(CACHE) + if len(self.container_chaining) == 1: + # req.raw.decode_content = True + self.result = pickle.loads(req.content) + + def __exec_next_state(self, rule_found): + index = self.context.index + current_meta_rule = self.context.headers[index] + current_container = self.__get_container_from_meta_rule(current_meta_rule) + current_container_genre = current_container["genre"] + try: + next_meta_rule = self.context.headers[index + 1] + except IndexError: + next_meta_rule = None + if current_container_genre == "authz": + if rule_found: + return True + pass + if next_meta_rule: + # next will be session if current is deny and session is unset + 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 + else: + LOG.error("Delegation is not developed!") + + else: + # else next will be None and the request is sent to router + return self.__return_to_router() + elif current_container_genre == "session": + pass + # next will be next container in headers if current is passed + 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) + # next will be None if current is grant and the request is sent to router + else: + return self.__return_to_router() + elif current_container_genre == "delegation": + LOG.error("Delegation is not developed!") + # next will be authz if current is deny + # next will be None if current is grant and the request is sent to router + + def set_result(self, result): + self.result = result + + def is_authz(self): + if not self.result: + return False + authz_results = [] + for key in self.result.pdp_set: + if "effect" in self.result.pdp_set[key]: + if self.result.pdp_set[key]["effect"] == "grant": + # the pdp is a authorization PDP and grant the request + authz_results.append(True) + elif self.result.pdp_set[key]["effect"] == "passed": + # the pdp is not a authorization PDP (session or delegation) and had run normally + authz_results.append(True) + elif self.result.pdp_set[key]["effect"] == "unset": + # the pdp is not a authorization PDP (session or delegation) and had not yep run + authz_results.append(True) + else: + # the pdp is (or not) a authorization PDP and had run badly + authz_results.append(False) + if list(itertools.accumulate(authz_results, lambda x, y: x & y))[-1]: + self.result.pdp_set["effect"] = "grant" + if self.result: + if self.result.pdp_set["effect"] == "grant": + self.final_result = "Grant" + return True + self.final_result = "Deny" + return True + + # def notify(self, request_id, container_id, payload): + # LOG.info("notify {} {} {}".format(request_id, container_id, payload)) + # # TODO: send the notification and wait for the result + # # req = requests.get() diff --git a/moonv4/moon_interface/moon_interface/containers.py b/moonv4/moon_interface/moon_interface/containers.py new file mode 100644 index 00000000..1ca76a2d --- /dev/null +++ b/moonv4/moon_interface/moon_interface/containers.py @@ -0,0 +1,102 @@ +# Copyright 2017 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 docker +import logging +import re +import requests +import time +from moon_utilities import configuration, exceptions + +__version__ = "0.1.0" + +LOG = logging.getLogger("moon.interface.container") + + +class DockerManager: + + def __init__(self): + docker_conf = configuration.get_configuration("docker")['docker'] + self.docker = docker.DockerClient(base_url=docker_conf['url']) + + def create_container(self, data): + """Create the container through the docker client + + :param data: { + "name": "authz", + "hostname": "authz123456789", + "port": { + "PrivatePort": 8090, + "Type": "tcp", + "IP": "0.0.0.0", + "PublicPort": 8090 + }, + "keystone_project_id": "keystone_project_id1", + "pdp_id": "123456789", + "container_name": "wukongsun/moon_authz:v4.1" + } + :return: container output + """ + output = self.docker.containers.run( + image=data.get("container_name"), + hostname=data.get("hostname", data.get("name"))[:63], + name=data.get("name"), + network='moon', + ports={'{}/{}'.format( + data.get("port").get("PrivatePort"), + data.get("port").get("Type") + ): int(data.get("port").get("PrivatePort"))}, + environment={ + "UUID": data.get("hostname"), + "BIND": data.get("port").get("IP"), + "TYPE": data.get("plugin_name"), + "PORT": data.get("port").get("PrivatePort"), + "PDP_ID": data.get("pdp_id"), + "META_RULE_ID": data.get("meta_rule_id"), + "KEYSTONE_PROJECT_ID": data.get("keystone_project_id"), + }, + detach=True + ) + try: + req = requests.head("http://{}:{}/".format(data.get("hostname"), data.get("port").get("PublicPort"))) + except requests.exceptions.ConnectionError: + pass + else: + if req.status_code != 200: + raise exceptions.DockerError("Container {} is not running!".format(data.get("hostname"))) + output.ip = "0.0.0.0" + return output + + # Note: host is not reachable through hostname so trying to find th IP address + res = output.exec_run("ip addr") + find = re.findall("inet (\d+\.\d+\.\d+\.\d+)", res.decode("utf-8")) + ip = "127.0.0.1" + for ip in find: + if ip.startswith("127"): + continue + break + cpt = 0 + while True: + try: + req = requests.head("http://{}:{}/".format(ip, data.get("port").get("PublicPort"))) + except requests.exceptions.ConnectionError: + pass + else: + if req.status_code not in (200, 201): + LOG.error("url={}".format("http://{}:{}/".format(ip, data.get("port").get("PublicPort")))) + LOG.error("req={}".format(req)) + raise exceptions.DockerError("Container {} is not running!".format(data.get("hostname"))) + output.ip = ip + return output + finally: + cpt += 1 + time.sleep(0.1) + if cpt > 20: + break + output.ip = ip + return output + + def delete_container(self, uuid): + raise NotImplementedError diff --git a/moonv4/moon_interface/moon_interface/http_server.py b/moonv4/moon_interface/moon_interface/http_server.py index 046337a2..d7f8469c 100644 --- a/moonv4/moon_interface/moon_interface/http_server.py +++ b/moonv4/moon_interface/moon_interface/http_server.py @@ -3,23 +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'. -from flask import Flask +from flask import Flask, jsonify from flask_cors import CORS, cross_origin from flask_restful import Resource, Api import logging from moon_interface import __version__ from moon_interface.api.generic import Status, Logs, API -from moon_interface.api.models import Models -from moon_interface.api.policies import Policies -from moon_interface.api.pdp import PDP -from moon_interface.api.meta_rules import MetaRules -from moon_interface.api.meta_data import SubjectCategories, ObjectCategories, ActionCategories -from moon_interface.api.perimeter import Subjects, Objects, Actions -from moon_interface.api.data import SubjectData, ObjectData, ActionData -from moon_interface.api.assignments import SubjectAssignments, ObjectAssignments, ActionAssignments -from moon_interface.api.rules import Rules from moon_interface.api.authz import Authz -from moon_utilities import exceptions +from moon_interface.api.wrapper import Wrapper +from moon_interface.authz_requests import CACHE +from moon_utilities import configuration, exceptions logger = logging.getLogger("moon.interface.http") @@ -68,13 +61,7 @@ class Server: raise NotImplementedError() __API__ = ( - Status, Logs, API, - MetaRules, SubjectCategories, ObjectCategories, ActionCategories, - Subjects, Objects, Actions, - SubjectAssignments, ObjectAssignments, ActionAssignments, - SubjectData, ObjectData, ActionData, - Rules, Authz, - Models, Policies, PDP + Status, Logs, API ) @@ -106,24 +93,28 @@ class HTTPServer(Server): def __init__(self, host="localhost", port=80, **kwargs): super(HTTPServer, self).__init__(host=host, port=port, **kwargs) self.app = Flask(__name__) + self.port = port + conf = configuration.get_configuration("components/manager") + self.manager_hostname = conf["components/manager"].get("hostname", "manager") + self.manager_port = conf["components/manager"].get("port", 80) #Todo : specify only few urls instead of * CORS(self.app) self.api = Api(self.app) self.__set_route() - # self.__hook_errors() + self.__hook_errors() - @self.app.errorhandler(exceptions.AuthException) - def _auth_exception(error): - return {"error": "Unauthorized"}, 401 + # @self.app.errorhandler(exceptions.AuthException) + # def _auth_exception(error): + # return {"error": "Unauthorized"}, 401 def __hook_errors(self): - # FIXME (dthom): it doesn't work + def get_404_json(e): - return {"error": "Error", "code": 404, "description": 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 {"error": "Error", "code": 400, "description": 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) @@ -132,7 +123,23 @@ class HTTPServer(Server): for api in __API__: self.api.add_resource(api, *api.__urls__) + self.api.add_resource(Wrapper, *Wrapper.__urls__, + resource_class_kwargs={ + "port": self.port, + "cache": CACHE, + "interface_name": self.host, + "manager_url": "http://{}:{}".format(self.manager_hostname, self.manager_port), + } + ) + self.api.add_resource(Authz, *Authz.__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(debug=True, host=self._host, port=self._port) # nosec + self.app.run(host=self._host, port=self._port) # nosec + # self.app.run(debug=True, host=self._host, port=self._port) # nosec diff --git a/moonv4/moon_interface/moon_interface/server.py b/moonv4/moon_interface/moon_interface/server.py index 711aa00a..86274ec5 100644 --- a/moonv4/moon_interface/moon_interface/server.py +++ b/moonv4/moon_interface/moon_interface/server.py @@ -14,7 +14,6 @@ def main(): configuration.init_logging() try: conf = configuration.get_configuration("components/interface") - LOG.debug("interface.conf={}".format(conf)) hostname = conf["components/interface"].get("hostname", "interface") port = conf["components/interface"].get("port", 80) bind = conf["components/interface"].get("bind", "127.0.0.1") @@ -25,6 +24,8 @@ def main(): configuration.add_component(uuid="interface", name=hostname, port=port, bind=bind) LOG.info("Starting server with IP {} on port {} bind to {}".format(hostname, port, bind)) server = HTTPServer(host=bind, port=port) + # LOG.info("Starting server") + # server = HTTPServer(host="0.0.0.0", port=8081) server.run() |