From 8bb53c04f2cf12f1aa6dd2ae0af46cbfcd758265 Mon Sep 17 00:00:00 2001 From: WuKong Date: Wed, 8 Jul 2015 18:14:12 +0200 Subject: authz policy engine Change-Id: I4edc67a09e1de000b0983d734bea21eb2655d74e Signed-off-by: WuKong --- keystone-moon/keystone/contrib/moon/algorithms.py | 64 +++++++++++ keystone-moon/keystone/contrib/moon/core.py | 124 ++++++++++++---------- 2 files changed, 132 insertions(+), 56 deletions(-) create mode 100644 keystone-moon/keystone/contrib/moon/algorithms.py (limited to 'keystone-moon') diff --git a/keystone-moon/keystone/contrib/moon/algorithms.py b/keystone-moon/keystone/contrib/moon/algorithms.py new file mode 100644 index 00000000..bfdfc5ca --- /dev/null +++ b/keystone-moon/keystone/contrib/moon/algorithms.py @@ -0,0 +1,64 @@ +import itertools + +""" an example of authz_buffer, sub_meta_rule_dict, rule_dict +authz_buffer = { + 'subject_uuid': xxx, + 'object_uuid': yyy, + 'action_uuid': zzz, + 'subject_attributes': { + 'subject_category1': [], + 'subject_category2': [], + ... + 'subject_categoryn': [] + }, + 'object_attributes': {}, + 'action_attributes': {}, +} + +sub_meta_rule_dict = { + "subject_categories": ["subject_security_level", "aaa"], + "action_categories": ["computing_action"], + "object_categories": ["object_security_level"], +} + +rule_dict = [ + ["high", "vm_admin", "medium"], + ["high", "vm_admin", "low"], + ["medium", "vm_admin", "low"], + ["high", "vm_access", "high"], + ["high", "vm_access", "medium"], + ["high", "vm_access", "low"], + ["medium", "vm_access", "medium"], + ["medium", "vm_access", "low"], + ["low", "vm_access", "low"] +] +""" + +def algo_inclusion(authz_buffer, sub_meta_rule_dict, rule_dict): + _cat = [] + for subject_cat in sub_meta_rule_dict['subject_categories']: + if subject_cat in authz_buffer['subject_attributes']: + _cat.append(authz_buffer['subject_attributes'][subject_cat]) + for action_cat in sub_meta_rule_dict['action_categories']: + if action_cat in authz_buffer['action_attributes']: + _cat.append(authz_buffer['action_attributes'][action_cat]) + for object_cat in sub_meta_rule_dict['object_categories']: + if object_cat in authz_buffer['object_attributes']: + _cat.append(authz_buffer['object_attributes'][object_cat]) + + for _element in itertools.product(*_cat): + if list(_element) in rule_dict: + return True + + return False + + +def algo_comparison(_authz_buffer, _sub_meta_rule_dict, _rule_dict): + return + + +def aggr_all_true(decision_buffer): + for _rule in decision_buffer: + if decision_buffer[_rule] is False: + return False + return True \ No newline at end of file diff --git a/keystone-moon/keystone/contrib/moon/core.py b/keystone-moon/keystone/contrib/moon/core.py index 56a491c9..ecbb6a90 100644 --- a/keystone-moon/keystone/contrib/moon/core.py +++ b/keystone-moon/keystone/contrib/moon/core.py @@ -20,6 +20,7 @@ from oslo_config import cfg from keystone.i18n import _ from keystone.contrib.moon.exception import * +from keystone.contrib.moon.algorithms import * CONF = config.CONF LOG = log.getLogger(__name__) @@ -288,6 +289,56 @@ class IntraExtensionManager(manager.Manager): driver = CONF.moon.intraextension_driver super(IntraExtensionManager, self).__init__(driver) + def __get_authz_buffer(self, intra_extension_uuid, subject_uuid, object_uuid, action_uuid): + """ + :param intra_extension_uuid: + :param subject_uuid: + :param object_uuid: + :param action_uuid: + :return: authz_buffer = { + 'subject_uuid': xxx, + 'object_uuid': yyy, + 'action_uuid': zzz, + 'subject_attributes': { + 'subject_category1': [], + 'subject_category2': [], + ... + 'subject_categoryn': [] + }, + 'object_attributes': {}, + 'action_attributes': {}, + } + """ + + if not self.driver.get_intra_extension(intra_extension_uuid): + raise IntraExtensionNotFound() + + _authz_buffer = dict() + _authz_buffer['subject_uuid'] = subject_uuid + _authz_buffer['object_uuid'] = object_uuid + _authz_buffer['action_uuid'] = action_uuid + + try: + _meta_data_dict = self.driver.get_meta_data_dict(intra_extension_uuid) + _subject_assignment_dict = self.driver.get_subject_category_assignment_dict(intra_extension_uuid, subject_uuid) + _object_assignment_dict = self.driver.get_object_category_assignment_dict(intra_extension_uuid, object_uuid) + _action_assignment_dict = self.driver.get_action_category_assignment_dict(intra_extension_uuid, action_uuid) + except exception: # Execption for ItemUnknow, ItemCategoryAssignmentOutOfScope, ItemCategoryAssignmentUnknown + pass + + _authz_buffer['subject_attributes'] = dict() + _authz_buffer['object_attributes'] = dict() + _authz_buffer['action_attributes'] = dict() + + for _subject_category in _meta_data_dict['subject_categories']: + _authz_buffer['subject_attributes'][_subject_category] = _subject_assignment_dict[_subject_category] + for _object_category in _meta_data_dict['object_categories']: + _authz_buffer['object_attributes'][_object_category] = _object_assignment_dict[_object_category] + for _action_category in _meta_data_dict['action_categories']: + _authz_buffer['action_attributes'][_action_category] = _action_assignment_dict[_action_category] + + return _authz_buffer + def authz(self, intra_extension_uuid, subject_uuid, object_uuid, action_uuid): """Check authorization for a particular action. @@ -301,68 +352,29 @@ class IntraExtensionManager(manager.Manager): SubjectUnknown ObjectUnknown ActionUnknown - SubjectCategoryAssignmentOutOfScope - ActionCategoryAssignmentOutOfScope - ObjectCategoryAssignmentOutOfScope SubjectCategoryAssignmentUnknown ObjectCategoryAssignmentUnknown ActionCategoryAssignmentUnknown """ - if not self.driver.get_intra_extension(intra_extension_uuid): - raise IntraExtensionNotFound() + + _authz_buffer = self.__get_authz_buffer(intra_extension_uuid, subject_uuid, object_uuid, action_uuid) + _decision_buffer = dict() try: - _subject_category_dict = self.driver.get_subject_category_dict(intra_extension_uuid) - _object_category_dict = self.driver.get_object_category_dict(intra_extension_uuid) - _action_category_dict = self.driver.get_action_category_dict(intra_extension_uuid) - _subject_category_value_dict = self.driver.get_subject_category_value_dict(intra_extension_uuid, subject_uuid) - _object_category_value_dict = self.driver.get_object_category_value_dict(intra_extension_uuid, object_uuid) - _action_category_value_dict = self.driver.get_action_category_value_dict(intra_extension_uuid, action_uuid) - _subject_assignment_dict = self.driver.get_subject_category_assignment_dict(intra_extension_uuid) - _action_assignment_dict = self.driver.get_action_category_assignment_dict(intra_extension_uuid) - _object_assignment_dict = self.driver.get_object_category_assignment_dict(intra_extension_uuid) - _meta_rule = self.driver.get_meta_rule(intra_extension_uuid) - _rules = self.driver.get_rules(intra_extension_uuid) - # # TODO: algorithm to validate requests - # return True - # except exception: # TODO: exception.IntraExtension.NotAuthorized - # pass - - # get all rules for intra_extension - rules = self.driver.get_rules(intra_extension_uuid) - # check if relation exists in rules - relation_to_check = None - relations = self.driver.get_sub_meta_rule_relations(intra_extension_uuid) - for relation in rules: - if relation in relations: - # hypothesis: only one relation to check - relation_to_check = relation - break - else: - self.moonlog_api.authz("KO: No relation can be used {}".format(rules.keys())) - return False - for sub_rule in rules[relation_to_check]: - for cat in sub_meta_rule[relation_to_check]["subject_categories"]: - rule_scope = sub_rule.pop(0) - if rule_scope in subject_assignments[cat][subject_uuid]: - break - else: - continue - for cat in sub_meta_rule[relation_to_check]["action_categories"]: - rule_scope = sub_rule.pop(0) - if rule_scope in action_assignments[cat][action_uuid]: - break - else: - continue - for cat in sub_meta_rule[relation_to_check]["object_categories"]: - rule_scope = sub_rule.pop(0) - if rule_scope in object_assignments[cat][object_uuid]: - break - else: - continue - self.moonlog_api.authz("OK ({} {},{},{})".format(intra_extension_uuid, subject_uuid, action_uuid, object_uuid)) - return True - self.moonlog_api.authz("KO ({} {},{},{})".format(intra_extension_uuid, subject_uuid, action_uuid, object_uuid)) + _meta_rule_dict = self.driver.get_meta_rule_dict(intra_extension_uuid) + _rule_dict = self.driver.get_rule_dict(intra_extension_uuid) + except exception: # Execption for rule + pass + + for _rule in _meta_rule_dict['sub_meta_rules']: + if _meta_rule_dict['sub_meta_rules'][_rule]['algorithm'] == 'inclusion': + _decision_buffer[_rule] = algo_inclusion(_authz_buffer, _meta_rule_dict['sub_meta_rules'][_rule], _rule_dict[_rule]) + elif _meta_rule_dict['sub_meta_rules'][_rule]['algorithm'] == 'comparison': + _decision_buffer[_rule] = algo_comparison(_authz_buffer, _meta_rule_dict['sub_meta_rules'][_rule], _rule_dict[_rule]) + + if _meta_rule_dict['aggregation'] == 'all_true': + return aggr_all_true(_decision_buffer) + return False def __get_key_from_value(self, value, values_dict): -- cgit 1.2.3-korg