diff options
author | WuKong <rebirthmonkey@gmail.com> | 2017-04-22 13:25:07 +0200 |
---|---|---|
committer | WuKong <rebirthmonkey@gmail.com> | 2017-04-22 13:25:07 +0200 |
commit | d182202fc6001983541504ed323d68479086317e (patch) | |
tree | 11d4c10cdd3e995f519c3e0e324968fdaf175114 /moonv4/moon_authz/moon_authz | |
parent | 83c1c966baf73329fab8ddcfad19ad7fe0c41c2a (diff) |
add moonv4
Change-Id: I247af788d0b0fb961fbc85416486b241eb1d807c
Signed-off-by: WuKong <rebirthmonkey@gmail.com>
Diffstat (limited to 'moonv4/moon_authz/moon_authz')
-rw-r--r-- | moonv4/moon_authz/moon_authz/__init__.py | 6 | ||||
-rw-r--r-- | moonv4/moon_authz/moon_authz/__main__.py | 3 | ||||
-rw-r--r-- | moonv4/moon_authz/moon_authz/api/__init__.py | 0 | ||||
-rw-r--r-- | moonv4/moon_authz/moon_authz/api/authorization.py | 445 | ||||
-rw-r--r-- | moonv4/moon_authz/moon_authz/api/generic.py | 28 | ||||
-rw-r--r-- | moonv4/moon_authz/moon_authz/messenger.py | 63 | ||||
-rw-r--r-- | moonv4/moon_authz/moon_authz/server.py | 36 |
7 files changed, 581 insertions, 0 deletions
diff --git a/moonv4/moon_authz/moon_authz/__init__.py b/moonv4/moon_authz/moon_authz/__init__.py new file mode 100644 index 00000000..903c6518 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/__init__.py @@ -0,0 +1,6 @@ +# 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'. + +__version__ = "0.1.0" diff --git a/moonv4/moon_authz/moon_authz/__main__.py b/moonv4/moon_authz/moon_authz/__main__.py new file mode 100644 index 00000000..be483962 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/__main__.py @@ -0,0 +1,3 @@ +from moon_authz.server import main + +main() diff --git a/moonv4/moon_authz/moon_authz/api/__init__.py b/moonv4/moon_authz/moon_authz/api/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/moonv4/moon_authz/moon_authz/api/__init__.py diff --git a/moonv4/moon_authz/moon_authz/api/authorization.py b/moonv4/moon_authz/moon_authz/api/authorization.py new file mode 100644 index 00000000..248a9565 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/api/authorization.py @@ -0,0 +1,445 @@ +# 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 copy +import itertools +from oslo_log import log as logging +from oslo_config import cfg +from moon_utilities.security_functions import call, Context +from moon_utilities.misc import get_uuid_from_name +from moon_utilities import exceptions +from moon_db.core import PDPManager +from moon_db.core import ModelManager +from moon_db.core import PolicyManager + +# TODO (asteroide): +# - end the dev of the context +# - rebuild the authorization function according to the context +# - call the next security function +# - call the master if an element is absent + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class PDP: + + def __init__(self, context): + self.__context = context + + +class Authorization(object): + """ + Retrieve the current status of all components. + """ + + __version__ = "0.1.0" + pdp_id = None + meta_rule_id = None + keystone_project_id = None + + def __init__(self, component_id): + self.component_id = component_id + LOG.info("ext={}".format(component_id)) + for _id_value in component_id.split("_"): + LOG.info("_id_value={}".format(_id_value.split(":"))) + _type, _id = _id_value.split(":") + if _type == "pdp": + self.pdp_id = _id + elif _type == "metarule": + self.meta_rule_id = _id + elif _type == "project": + self.keystone_project_id = _id + # self.manager = IntraExtensionAdminManager + # self.context = {"id": self.component_id, "user_id": "admin"} + # self.aggregation_algorithm_dict = ConfigurationManager.driver.get_aggregation_algorithms_dict() + # self.__subjects = None + # self.__objects = None + # self.__actions = None + # self.__subject_scopes = None + # self.__object_scopes = None + # self.__action_scopes = None + # self.__subject_categories = None + # self.__object_categories = None + # self.__action_categories = None + # self.__subject_assignments = None + # self.__object_assignments = None + # self.__action_assignments = None + # self.__sub_meta_rules = None + # self.__rules = None + # self.aggregation_algorithm_id = None + + # @property + # def subjects(self): + # if not self.__subjects: + # self.__subjects = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_subjects", args={}) + # if "subjects" in self.__subjects: + # return self.__subjects + # else: + # LOG.error("An error occurred {}".format(self.__subjects)) + # return self.__subjects + # + # @property + # def objects(self): + # if not self.__objects: + # self.__objects = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_objects", args={}) + # if "objects" in self.__objects: + # return self.__objects + # else: + # LOG.error("An error occurred {}".format(self.__objects)) + # return self.__objects + # + # @property + # def actions(self): + # if not self.__actions: + # self.__actions = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_actions", args={}) + # if "actions" in self.__actions: + # return self.__actions + # else: + # LOG.error("An error occurred {}".format(self.__actions)) + # return self.__actions + # + # @property + # def subject_scopes(self): + # if not self.__subject_scopes: + # self.__subject_scopes = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_subject_scopes", args={}) + # if "subject_scopes" in self.__subject_scopes: + # return self.__subject_scopes + # else: + # LOG.error("An error occurred {}".format(self.__subject_scopes)) + # return self.__subject_scopes + # + # @property + # def object_scopes(self): + # if not self.__object_scopes: + # self.__object_scopes = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_object_scopes", args={}) + # if "object_scopes" in self.__object_scopes: + # return self.__object_scopes + # else: + # LOG.error("An error occurred {}".format(self.__object_scopes)) + # return self.__object_scopes + # + # @property + # def action_scopes(self): + # if not self.__action_scopes: + # self.__action_scopes = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_action_scopes", args={}) + # if "action_scopes" in self.__action_scopes: + # return self.__action_scopes + # else: + # LOG.error("An error occurred {}".format(self.__action_scopes)) + # return self.__action_scopes + # + # @property + # def subject_categories(self): + # if not self.__subject_categories: + # self.__subject_categories = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_subject_categories", args={}) + # if "subject_categories" in self.__subject_categories: + # return self.__subject_categories + # else: + # LOG.error("An error occurred {}".format(self.__subject_categories)) + # return self.__subject_categories + # + # @property + # def object_categories(self): + # if not self.__object_categories: + # self.__object_categories = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_object_categories", args={}) + # if "object_categories" in self.__object_categories: + # return self.__object_categories + # else: + # LOG.error("An error occurred {}".format(self.__object_categories)) + # return self.__object_categories + # + # @property + # def action_categories(self): + # if not self.__action_categories: + # self.__action_categories = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_action_categories", args={}) + # if "action_categories" in self.__action_categories: + # return self.__action_categories + # else: + # LOG.error("An error occurred {}".format(self.__action_categories)) + # return self.__action_categories + # + # @property + # def subject_assignments(self): + # if not self.__subject_assignments: + # context = copy.deepcopy(self.context) + # context['sid'] = None + # context['scid'] = None + # args = {'ssid': None} + # self.__subject_assignments = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=context, + # method="get_subject_assignments", args=args) + # if "subject_assignments" in self.__subject_assignments: + # return self.__subject_assignments + # else: + # LOG.error("An error occurred {}".format(self.__subject_assignments)) + # return self.__subject_assignments + # + # @property + # def object_assignments(self): + # if not self.__object_assignments: + # context = copy.deepcopy(self.context) + # context['sid'] = None + # context['scid'] = None + # args = {'ssid': None} + # self.__object_assignments = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=context, + # method="get_object_assignments", args=args) + # if "object_assignments" in self.__object_assignments: + # return self.__object_assignments + # else: + # LOG.error("An error occurred {}".format(self.__object_assignments)) + # return self.__object_assignments + # + # @property + # def action_assignments(self): + # if not self.__action_assignments: + # context = copy.deepcopy(self.context) + # context['sid'] = None + # context['scid'] = None + # args = {'ssid': None} + # self.__action_assignments = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=context, + # method="get_action_assignments", args=args) + # if "action_assignments" in self.__action_assignments: + # return self.__action_assignments + # else: + # LOG.error("An error occurred {}".format(self.__action_assignments)) + # return self.__action_assignments + # + # @property + # def sub_meta_rules(self): + # if not self.__sub_meta_rules: + # self.__sub_meta_rules = call("moon_secfunction_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_sub_meta_rules", args={}) + # if "sub_meta_rules" in self.__sub_meta_rules: + # return self.__sub_meta_rules + # else: + # LOG.error("An error occurred {}".format(self.__sub_meta_rules)) + # return self.__sub_meta_rules + # + # @property + # def rules(self): + # if not self.__rules: + # self.__rules = dict() + # for _id, _value in self.sub_meta_rules["sub_meta_rules"].items(): + # context = copy.deepcopy(self.context) + # context["sub_meta_rule_id"] = _id + # __elements = call("moon_secfunction_{}".format(self.intra_extension_id), ctx=context, + # method="get_rules", args={}) + # if "rules" in __elements: + # self.__rules[_id] = __elements + # else: + # LOG.error("An error occurred {}".format(__elements)) + # return self.__rules + + # def __get_authz_buffer(self, subject_id, object_id, action_id): + # """ + # :param intra_extension_id: + # :param subject_id: + # :param object_id: + # :param action_id: + # :return: authz_buffer = { + # 'subject_id': xxx, + # 'object_id': yyy, + # 'action_id': zzz, + # 'subject_assignments': { + # 'subject_category1': [], + # 'subject_category2': [], + # ... + # }, + # 'object_assignments': {}, + # 'action_assignments': {}, + # } + # """ + # authz_buffer = dict() + # # Sometimes it is not the subject ID but the User Keystone ID, so, we have to check + # subjects_dict = copy.deepcopy(self.subjects) + # if subject_id not in subjects_dict["subjects"].keys(): + # for _subject_id in subjects_dict["subjects"]: + # if subjects_dict["subjects"][_subject_id]['keystone_id']: + # subject_id = _subject_id + # break + # authz_buffer['subject_id'] = subject_id + # authz_buffer['object_id'] = object_id + # authz_buffer['action_id'] = action_id + # meta_data_dict = dict() + # meta_data_dict["subject_categories"] = copy.deepcopy(self.subject_categories["subject_categories"]) + # meta_data_dict["object_categories"] = copy.deepcopy(self.object_categories["object_categories"]) + # meta_data_dict["action_categories"] = copy.deepcopy(self.action_categories["action_categories"]) + # subject_assignment_dict = copy.deepcopy(self.subject_assignments['subject_assignments'][subject_id]) + # LOG.info("__get_authz_buffer self.object_assignments['object_assignments']={}".format(self.object_assignments['object_assignments'])) + # LOG.info("__get_authz_buffer object_id={}".format(object_id)) + # object_assignment_dict = copy.deepcopy(self.object_assignments['object_assignments'][object_id]) + # action_assignment_dict = copy.deepcopy(self.action_assignments['action_assignments'][action_id]) + # + # authz_buffer['subject_assignments'] = dict() + # authz_buffer['object_assignments'] = dict() + # authz_buffer['action_assignments'] = dict() + # + # for _subject_category in meta_data_dict['subject_categories']: + # authz_buffer['subject_assignments'][_subject_category] = list(subject_assignment_dict[_subject_category]) + # for _object_category in meta_data_dict['object_categories']: + # authz_buffer['object_assignments'][_object_category] = list(object_assignment_dict[_object_category]) + # for _action_category in meta_data_dict['action_categories']: + # authz_buffer['action_assignments'][_action_category] = list(action_assignment_dict[_action_category]) + # return authz_buffer + # + # def __get_decision_dict(self, subject_id, object_id, action_id): + # """Check authorization for a particular action. + # + # :param intra_extension_id: UUID of an IntraExtension + # :param subject_id: subject UUID of the request + # :param object_id: object UUID of the request + # :param action_id: action UUID of the request + # :return: True or False or raise an exception + # :raises: + # """ + # authz_buffer = self.__get_authz_buffer(subject_id, object_id, action_id) + # decision_buffer = dict() + # + # meta_rule_dict = copy.deepcopy(self.sub_meta_rules['sub_meta_rules']) + # rules_dict = copy.deepcopy(self.rules) + # for sub_meta_rule_id in meta_rule_dict: + # if meta_rule_dict[sub_meta_rule_id]['algorithm'] == 'inclusion': + # decision_buffer[sub_meta_rule_id] = algorithms.inclusion( + # authz_buffer, + # meta_rule_dict[sub_meta_rule_id], + # rules_dict[sub_meta_rule_id]['rules'].values()) + # elif meta_rule_dict[sub_meta_rule_id]['algorithm'] == 'comparison': + # decision_buffer[sub_meta_rule_id] = algorithms.comparison( + # authz_buffer, + # meta_rule_dict[sub_meta_rule_id], + # rules_dict[sub_meta_rule_id]['rules'].values()) + # + # return decision_buffer + # + # def __authz(self, subject_id, object_id, action_id): + # decision = False + # decision_dict = dict() + # try: + # decision_dict = self.__get_decision_dict(subject_id, object_id, action_id) + # except (exceptions.SubjectUnknown, exceptions.ObjectUnknown, exceptions.ActionUnknown) as e: + # # maybe we need to synchronize with the master + # pass + # # if CONF.slave.slave_name and CONF.slave.master_url: + # # self.get_data_from_master() + # # decision_dict = self.__get_decision_dict(subject_id, object_id, action_id) + # + # try: + # # aggregation_algorithm_id = IntraExtensionAdminManager.get_aggregation_algorithm_id( + # # "admin", + # # self.intra_extension_id)['aggregation_algorithm'] + # if not self.aggregation_algorithm_id: + # self.aggregation_algorithm_id = self.intra_extension['aggregation_algorithm'] + # except Exception as e: + # LOG.error(e, exc_info=True) + # LOG.error(self.intra_extension) + # return { + # 'authz': False, + # 'comment': "Aggregation algorithm not set" + # } + # if self.aggregation_algorithm_dict[self.aggregation_algorithm_id]['name'] == 'all_true': + # decision = algorithms.all_true(decision_dict) + # elif self.aggregation_algorithm_dict[self.aggregation_algorithm_id]['name'] == 'one_true': + # decision = algorithms.one_true(decision_dict) + # if not decision_dict or not decision: + # raise exceptions.AuthzException("{} {}-{}-{}".format(self.intra_extension['id'], subject_id, action_id, object_id)) + # return { + # 'authz': decision, + # 'comment': "{} {}-{}-{}".format(self.intra_extension['id'], subject_id, action_id, object_id) + # } + # + # def authz_bak(self, ctx, args): + # """Return the authorization for a specific request + # + # :param ctx: { + # "subject_name" : "string name", + # "action_name" : "string name", + # "object_name" : "string name" + # } + # :param args: {} + # :return: { + # "authz": "True or False", + # "message": "optional message" + # } + # """ + # intra_extension_id = ctx["id"] + # try: + # subject_id = get_uuid_from_name(ctx["subject_name"], self.subjects['subjects']) + # object_id = get_uuid_from_name(ctx["object_name"], self.objects['objects']) + # action_id = get_uuid_from_name(ctx["action_name"], self.actions['actions']) + # authz_result = self.__authz(subject_id, object_id, action_id) + # return authz_result + # except Exception as e: + # LOG.error(e, exc_info=True) + # return {"authz": False, + # "error": str(e), + # "intra_extension_id": intra_extension_id, + # "ctx": ctx, "args": args} + # + # return {"authz": False} + + def __check_rules(self, context): + scopes_list = list() + current_header_id = context.headers[context.index]['id'] + current_pdp = context.pdp_set[current_header_id] + category_list = list() + category_list.extend(current_pdp["meta_rules"]["subject_categories"]) + category_list.extend(current_pdp["meta_rules"]["action_categories"]) + category_list.extend(current_pdp["meta_rules"]["object_categories"]) + for category in category_list: + if not current_pdp['target'][category]: + LOG.warning("Empty assignment detected: {} target={}".format(category, current_pdp['target'])) + return False, "Empty assignment detected..." + scopes_list.append(current_pdp['target'][category]) + scopes_list.append([True, ]) + rules = PolicyManager.get_rules_dict(user_id="admin", + policy_id=self.policy_id, + meta_rule_id=current_header_id).values() + for item in itertools.product(*scopes_list): + if list(item) in rules: + return True, "" + LOG.warning("No rule match the request...") + return False, "No rule match the request..." + + def authz(self, ctx, args): + LOG.info("authz {}".format(ctx)) + keystone_project_id = ctx["id"] + try: + if "authz_context" not in ctx: + ctx["authz_context"] = Context(keystone_project_id, + ctx["subject_name"], + ctx["object_name"], + ctx["action_name"], + ctx["request_id"]).to_dict() + LOG.info("Context={}".format(ctx["authz_context"])) + else: + ctx["authz_context"].index += 1 + result, message = self.__check_rules(ctx["authz_context"]) + # if ctx["authz_context"].index < len(ctx["authz_context"].headers): + del ctx["authz_context"] + return {"authz": result, + "error": message, + "pdp_id": self.pdp_id, + "ctx": ctx, "args": args} + except Exception as e: + try: + LOG.error(ctx["authz_context"]) + # del ctx["authz_context"] + except KeyError: + LOG.error("Cannot find \"authz_context\" in context") + LOG.error(e, exc_info=True) + return {"authz": False, + "error": str(e), + "pdp_id": self.pdp_id, + "ctx": ctx, "args": args} + diff --git a/moonv4/moon_authz/moon_authz/api/generic.py b/moonv4/moon_authz/moon_authz/api/generic.py new file mode 100644 index 00000000..db61188b --- /dev/null +++ b/moonv4/moon_authz/moon_authz/api/generic.py @@ -0,0 +1,28 @@ +# 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'. + + +class Status(object): + """ + Retrieve the current status of all components. + """ + + __version__ = "0.1.0" + + def get_status(self, ctx, args): + return {"status": "Running"} + + +class Logs(object): + """ + Retrieve the current status of all components. + """ + + __version__ = "0.1.0" + + def get_logs(self, ctx, args): + return {"error": "NotImplemented"} + + diff --git a/moonv4/moon_authz/moon_authz/messenger.py b/moonv4/moon_authz/moon_authz/messenger.py new file mode 100644 index 00000000..8ebd1633 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/messenger.py @@ -0,0 +1,63 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from oslo_config import cfg +import oslo_messaging +import hashlib +import time +from oslo_log import log as logging +from moon_authz.api.generic import Status, Logs +from moon_authz.api.authorization import Authorization +from moon_utilities.security_functions import call +from moon_utilities.api import APIList + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class Server: + + def __init__(self, component_id, keystone_project_id): + self.TOPIC = "authz_"+hashlib.sha224(component_id.encode("utf-8")).hexdigest() + self.transport = oslo_messaging.get_transport(cfg.CONF) + self.target = oslo_messaging.Target(topic=self.TOPIC, server='moon_authz_server1') + # ctx = {'user_id': 'admin', 'id': component_id, 'method': 'get_intra_extensions'} + # if CONF.slave.slave_name: + # ctx['call_master'] = True + # intra_extension = call( + # endpoint="security_router", + # ctx=ctx, + # method='route', + # args={} + # ) + # if "intra_extensions" not in intra_extension: + # LOG.error("Error reading intra_extension from router") + # LOG.error("intra_extension: {}".format(intra_extension)) + # raise IntraExtensionUnknown + # component_id = list(intra_extension["intra_extensions"].keys())[0] + LOG.info("Starting MQ server with topic: {}".format(self.TOPIC)) + self.endpoints = [ + APIList((Status, Logs)), + Status(), + Logs(), + Authorization(component_id) + ] + self.server = oslo_messaging.get_rpc_server(self.transport, self.target, self.endpoints, + executor='threading', + access_policy=oslo_messaging.DefaultRPCAccessPolicy) + + def run(self): + try: + self.server.start() + while True: + time.sleep(1) + except KeyboardInterrupt: + print("Stopping server by crtl+c") + except SystemExit: + print("Stopping server") + + self.server.stop() + self.server.wait() + diff --git a/moonv4/moon_authz/moon_authz/server.py b/moonv4/moon_authz/moon_authz/server.py new file mode 100644 index 00000000..0c2a36ff --- /dev/null +++ b/moonv4/moon_authz/moon_authz/server.py @@ -0,0 +1,36 @@ +# 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 os +from oslo_config import cfg +from oslo_log import log as logging +# cfg.CONF.register_cli_opt(cfg.StrOpt('function_type', positional=True, +# help="The type of function managed by this component (example 'authz').")) +cfg.CONF.register_cli_opt(cfg.StrOpt('uuid', positional=True, + help="The ID of the component managed here.")) +cfg.CONF.register_cli_opt(cfg.StrOpt('keystone_project_id', positional=True, + help="The ID of the component managed here.")) +from moon_utilities import options # noqa +from moon_authz.messenger import Server + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF +DOMAIN = "moon_authz" + +__CWD__ = os.path.dirname(os.path.abspath(__file__)) + + +def main(): + component_id = CONF.uuid + keystone_project_id = CONF.keystone_project_id + # function_type = CONF.intra_extension_id.replace(component_id, "").strip('_') + LOG.info("Starting server with IP {} on component {}".format( + CONF.security_router.host, component_id)) + server = Server(component_id=component_id, keystone_project_id=keystone_project_id) + server.run() + + +if __name__ == '__main__': + main() |