aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasteroide <thomas.duval@orange.com>2017-05-15 14:19:43 +0200
committerasteroide <thomas.duval@orange.com>2017-05-15 14:19:43 +0200
commit019b10d95976bb80bcce60ee93099b0fd57fcab5 (patch)
tree9e2b5c68dd8dadfc97346b77bf5549edbdf2c57a
parent80ca346a4cb183a6a1e684f6d8a9e19e3fc55d0e (diff)
Update Moon engine to allow a session policy
Change-Id: I63a80597710f08a6641e159cc2306d3cc68b1240
-rw-r--r--moonv4/moon_authz/moon_authz/api/authorization.py248
-rw-r--r--moonv4/moon_db/moon_db/backends/sql.py6
-rw-r--r--moonv4/moon_interface/moon_interface/api/rules.py25
-rw-r--r--moonv4/moon_interface/tests/apitests/populate_default_values.py61
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/rbac.py19
-rw-r--r--moonv4/moon_interface/tests/apitests/scenario/session.py23
-rw-r--r--moonv4/moon_interface/tests/apitests/set_authz.py13
-rw-r--r--moonv4/moon_interface/tests/apitests/utils/policies.py3
-rw-r--r--moonv4/moon_orchestrator/conf/plugins/session.py67
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/api/containers.py2
-rw-r--r--moonv4/moon_orchestrator/moon_orchestrator/server.py2
-rw-r--r--moonv4/moon_secrouter/moon_secrouter/api/route.py19
-rw-r--r--moonv4/moon_utilities/moon_utilities/security_functions.py78
13 files changed, 451 insertions, 115 deletions
diff --git a/moonv4/moon_authz/moon_authz/api/authorization.py b/moonv4/moon_authz/moon_authz/api/authorization.py
index 5968178e..e4d7ad7c 100644
--- a/moonv4/moon_authz/moon_authz/api/authorization.py
+++ b/moonv4/moon_authz/moon_authz/api/authorization.py
@@ -25,12 +25,6 @@ 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.
@@ -40,13 +34,14 @@ class Authorization(object):
pdp_id = None
meta_rule_id = None
keystone_project_id = None
+ payload = None
def __init__(self, component_desc):
self.component_id = component_desc
LOG.info("ext={}".format(component_desc))
self.filter_rule = oslo_messaging.NotificationFilter(
event_type='^authz$',
- context={'container_id': "authz_"+hashlib.sha224(component_desc.encode("utf-8")).hexdigest()}
+ context={'container_id': "\w+_"+hashlib.sha224(component_desc.encode("utf-8")).hexdigest()}
)
for _id_value in component_desc.split("_"):
@@ -61,27 +56,205 @@ class Authorization(object):
def __check_rules(self, context):
scopes_list = list()
current_header_id = context['headers'][context['index']]
+ Context.update_target(context)
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"]["object_categories"])
category_list.extend(current_pdp["meta_rules"]["action_categories"])
for category in category_list:
- # if not current_pdp['target'][category]:
- # LOG.warning("Empty assignment detected: {} target={}".format(category, current_pdp['target']))
- scopes_list.append(current_pdp['target'][category])
+ scope = list(current_pdp['target'][category])
+ scopes_list.append(scope)
policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id)
rules = PolicyManager.get_rules(user_id="admin",
policy_id=policy_id,
meta_rule_id=current_header_id)
- rules = list(map(lambda x: x['rule'], rules['rules']))
for item in itertools.product(*scopes_list):
req = list(item)
- if req in rules:
- return True, ""
+ for rule in rules['rules']:
+ if req == rule['rule']:
+ return rule['instructions'], ""
LOG.warning("No rule match the request...")
return False, "No rule match the request..."
+ def __update_subject_category_in_policy(self, operation, target):
+ result = False
+ try:
+ policy_name, category_name, data_name = target.split(":")
+ except ValueError:
+ LOG.error("Cannot understand value in instruction ({})".format(target))
+ return False
+ pdp_set = self.payload["authz_context"]['pdp_set']
+ for meta_rule_id in self.payload["authz_context"]['pdp_set']:
+ policy_id = PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ if meta_rule_id == "effect":
+ continue
+ if pdp_set[meta_rule_id]["meta_rules"]["name"] == policy_name:
+ for category_id, category_value in ModelManager.get_subject_categories("admin").items():
+ if category_value["name"] == "role":
+ subject_category_id = category_id
+ break
+ else:
+ LOG.error("Cannot understand category in instruction ({})".format(target))
+ return False
+ subject_data_id = None
+ for data in PolicyManager.get_subject_data("admin", policy_id, category_id=subject_category_id):
+ for data_id, data_value in data['data'].items():
+ if data_value["name"] == data_name:
+ subject_data_id = data_id
+ break
+ if subject_data_id:
+ break
+ else:
+ LOG.error("Cannot understand data in instruction ({})".format(target))
+ return False
+ if operation == "add":
+ self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][subject_category_id].append(
+ subject_data_id)
+ elif operation == "delete":
+ try:
+ self.payload["authz_context"]['pdp_set'][meta_rule_id]['target'][subject_category_id].remove(
+ subject_data_id)
+ except ValueError:
+ LOG.warning("Cannot remove role {} from target".format(data_name))
+ result = True
+ break
+ return result
+
+ def __update_container_chaining(self):
+ for index in range(len(self.payload["authz_context"]['headers'])):
+ self.payload["container_chaining"][index]["meta_rule_id"] = self.payload["authz_context"]['headers'][index]
+
+ def __get_container_from_meta_rule(self, meta_rule_id):
+ for index in range(len(self.payload["authz_context"]['headers'])):
+ if self.payload["container_chaining"][index]["meta_rule_id"] == meta_rule_id:
+ return self.payload["container_chaining"][index]
+
+ def __update_headers(self, name):
+ context = self.payload["authz_context"]
+ for meta_rule_id, meta_rule_value in context["pdp_set"].items():
+ if meta_rule_id == "effect":
+ continue
+ if meta_rule_value["meta_rules"]["name"] == name:
+ self.payload["authz_context"]['headers'].append(meta_rule_id)
+ return True
+ return False
+
+ def __exec_next_state(self, rule_found):
+ index = self.payload["authz_context"]['index']
+ current_meta_rule = self.payload["authz_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.payload["authz_context"]['headers'][index+1]
+ except IndexError:
+ next_meta_rule = None
+ if current_container_genre == "authz":
+ if rule_found:
+ return self.__return_to_router()
+ 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 __return_to_router(self):
+ call(endpoint="security_router",
+ ctx={"id": self.component_id,
+ "call_master": False,
+ "method": "return_authz",
+ "request_id": self.payload["authz_context"]["request_id"]},
+ method="route",
+ args=self.payload["authz_context"])
+
+ def __exec_instructions(self, instructions):
+ current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']]
+ for instruction in instructions:
+ for key in instruction:
+ if key == "decision":
+ if instruction["decision"] == "grant":
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "grant"
+ self.__return_to_router()
+ else:
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = instruction["decision"]
+ elif key == "chain":
+ result = self.__update_headers(**instruction["chain"])
+ if not result:
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ else:
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "passed"
+ elif key == "update":
+ result = self.__update_subject_category_in_policy(**instruction["update"])
+ if not result:
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ else:
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "passed"
+ # LOG.info("__exec_instructions {}".format(self.payload["authz_context"]))
+
+ def __update_current_request(self):
+ index = self.payload["authz_context"]["index"]
+ current_header_id = self.payload["authz_context"]['headers'][index]
+ previous_header_id = self.payload["authz_context"]['headers'][index-1]
+ current_policy_id = PolicyManager.get_policy_from_meta_rules("admin", current_header_id)
+ previous_policy_id = PolicyManager.get_policy_from_meta_rules("admin", previous_header_id)
+ # FIXME (asteroide): must change those lines to be ubiquitous against any type of policy
+ if self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "session":
+ subject = self.payload["authz_context"]['current_request'].get("subject")
+ subject_category_id = None
+ role_names = []
+ for category_id, category_value in ModelManager.get_subject_categories("admin").items():
+ if category_value["name"] == "role":
+ subject_category_id = category_id
+ break
+ for assignment_id, assignment_value in PolicyManager.get_subject_assignments(
+ "admin", previous_policy_id, subject, subject_category_id).items():
+ for data_id in assignment_value["assignments"]:
+ data = PolicyManager.get_subject_data("admin", previous_policy_id, data_id, subject_category_id)
+ for _data in data:
+ for key, value in _data["data"].items():
+ role_names.append(value["name"])
+ new_role_ids = []
+ for perimeter_id, perimeter_value in PolicyManager.get_objects("admin", current_policy_id).items():
+ if perimeter_value["name"] in role_names:
+ new_role_ids.append(perimeter_id)
+ break
+ perimeter_id = None
+ for perimeter_id, perimeter_value in PolicyManager.get_actions("admin", current_policy_id).items():
+ if perimeter_value["name"] == "*":
+ break
+
+ self.payload["authz_context"]['current_request']['object'] = new_role_ids[0]
+ self.payload["authz_context"]['current_request']['action'] = perimeter_id
+ elif self.payload["authz_context"]['pdp_set'][current_header_id]['meta_rules']['name'] == "rbac":
+ self.payload["authz_context"]['current_request']['subject'] = self.payload["authz_context"]['initial_request']['subject']
+ self.payload["authz_context"]['current_request']['object'] = self.payload["authz_context"]['initial_request']['object']
+ self.payload["authz_context"]['current_request']['action'] = self.payload["authz_context"]['initial_request']['action']
+
def critical(self, ctxt, publisher_id, event_type, payload, metadata):
"""This is the authz endpoint
but due to the oslo_messaging notification architecture, we must call it "critical"
@@ -93,50 +266,39 @@ class Authorization(object):
:param metadata: metadata of the notification
:return: result of the authorization for the current component
"""
- LOG.info("authz {} {}".format(ctxt, payload))
- keystone_project_id = payload["id"]
+ LOG.info("calling authz {} {}".format(ctxt, payload))
+ self.keystone_project_id = payload["id"]
+ self.payload = payload
try:
if "authz_context" not in payload:
- payload["authz_context"] = Context(keystone_project_id,
- payload["subject_name"],
- payload["object_name"],
- payload["action_name"],
- payload["request_id"]).to_dict()
+ self.payload["authz_context"] = Context(self.keystone_project_id,
+ self.payload["subject_name"],
+ self.payload["object_name"],
+ self.payload["action_name"],
+ self.payload["request_id"]).to_dict()
+ self.__update_container_chaining()
else:
- payload["authz_context"]["index"] += 1
- result, message = self.__check_rules(payload["authz_context"])
- current_header_id = payload["authz_context"]['headers'][payload["authz_context"]['index']]
- # current_pdp = payload["authz_context"]['pdp_set'][current_header_id]
+ self.payload["authz_context"]["index"] += 1
+ self.__update_current_request()
+ result, message = self.__check_rules(self.payload["authz_context"])
+ current_header_id = self.payload["authz_context"]['headers'][self.payload["authz_context"]['index']]
if result:
- payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "grant"
- if payload["authz_context"]["index"]+1 < len(payload["authz_context"]["headers"]):
- next_index = payload["authz_context"]["index"]+1
- notify(
- request_id=payload["authz_context"]["request_id"],
- container_id=payload["container_chaining"][next_index],
- payload=payload)
+ self.__exec_instructions(result)
else:
- ret = call(endpoint="security_router",
- ctx={"id": self.component_id,
- "call_master": False,
- "method": "return_authz",
- "request_id": payload["authz_context"]["request_id"]},
- method="route",
- args=payload["authz_context"])
- del payload["authz_context"]
+ self.payload["authz_context"]['pdp_set'][current_header_id]["effect"] = "deny"
+ self.__exec_next_state(result)
return {"authz": result,
"error": message,
"pdp_id": self.pdp_id,
- "ctx": ctxt, "args": payload}
+ "ctx": ctxt, "args": self.payload}
except Exception as e:
try:
- LOG.error(payload["authz_context"])
- # del ctx["authz_context"]
+ LOG.error(self.payload["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": ctxt, "args": payload}
+ "ctx": ctxt, "args": self.payload}
diff --git a/moonv4/moon_db/moon_db/backends/sql.py b/moonv4/moon_db/moon_db/backends/sql.py
index 5ab653a6..8cb6bb8e 100644
--- a/moonv4/moon_db/moon_db/backends/sql.py
+++ b/moonv4/moon_db/moon_db/backends/sql.py
@@ -328,6 +328,7 @@ class Rule(Base, DictBase):
return {
'id': self.id,
'rule': self.rule["rule"],
+ 'instructions': self.rule["instructions"],
'enabled': self.rule["enabled"],
'policy_id': self.policy_id,
'meta_rule_id': self.meta_rule_id
@@ -651,6 +652,7 @@ class PolicyConnector(BaseConnector, PolicyDriver):
session.delete(_action)
def get_subject_data(self, policy_id, data_id=None, category_id=None):
+ LOG.info("driver {} {} {}".format(policy_id, data_id, category_id))
with self.get_session_for_read() as session:
query = session.query(SubjectData)
if data_id:
@@ -658,6 +660,7 @@ class PolicyConnector(BaseConnector, PolicyDriver):
else:
query = query.filter_by(policy_id=policy_id, category_id=category_id)
ref_list = query.all()
+ LOG.info("ref_list={}".format(ref_list))
return {
"policy_id": policy_id,
"category_id": category_id,
@@ -979,10 +982,7 @@ class PolicyConnector(BaseConnector, PolicyDriver):
query = session.query(Rule)
query = query.filter_by(policy_id=policy_id, meta_rule_id=meta_rule_id)
ref_list = query.all()
- LOG.info("add_rule {}".format(ref_list))
- LOG.info("add_rule {}".format(value))
rules = list(map(lambda x: x.rule, ref_list))
- LOG.info("add_rule rules={}".format(rules))
if not rules or value not in rules:
LOG.info("add_rule IN IF")
ref = Rule.from_dict(
diff --git a/moonv4/moon_interface/moon_interface/api/rules.py b/moonv4/moon_interface/moon_interface/api/rules.py
index 81639a37..7757d275 100644
--- a/moonv4/moon_interface/moon_interface/api/rules.py
+++ b/moonv4/moon_interface/moon_interface/api/rules.py
@@ -62,13 +62,34 @@ class Rules(Resource):
: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": ["subject_data_id1", "object_data_id1", "action_data_id1"],
- "rule_id2": ["subject_data_id2", "object_data_id2", "action_data_id2"],
+ "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
diff --git a/moonv4/moon_interface/tests/apitests/populate_default_values.py b/moonv4/moon_interface/tests/apitests/populate_default_values.py
index 5ad6098f..0e3438db 100644
--- a/moonv4/moon_interface/tests/apitests/populate_default_values.py
+++ b/moonv4/moon_interface/tests/apitests/populate_default_values.py
@@ -56,7 +56,7 @@ def create_model():
def create_policy(model_id, meta_rule_list):
if args.verbose:
logger.warning("Creating policy {}".format(scenario.policy_name))
- policy_id = add_policy(name=scenario.policy_name)
+ policy_id = add_policy(name=scenario.policy_name, genre=scenario.policy_genre)
update_policy(policy_id, model_id)
@@ -90,23 +90,52 @@ def create_policy(model_id, meta_rule_list):
scenario.actions[name] = add_action(policy_id, name=name)
for subject_name in scenario.subject_assignments:
- for subject_category_name in scenario.subject_assignments[subject_name]:
- subject_id = scenario.subjects[subject_name]
- subject_cat_id = scenario.subject_categories[subject_category_name]
- subject_data_id = scenario.subject_data[subject_category_name][scenario.subject_assignments[subject_name][subject_category_name]]
- add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
+ if type(scenario.subject_assignments[subject_name]) in (list, tuple):
+ for items in scenario.subject_assignments[subject_name]:
+ for subject_category_name in items:
+ subject_id = scenario.subjects[subject_name]
+ subject_cat_id = scenario.subject_categories[subject_category_name]
+ for data in scenario.subject_assignments[subject_name]:
+ subject_data_id = scenario.subject_data[subject_category_name][data[subject_category_name]]
+ add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
+ else:
+ for subject_category_name in scenario.subject_assignments[subject_name]:
+ subject_id = scenario.subjects[subject_name]
+ subject_cat_id = scenario.subject_categories[subject_category_name]
+ subject_data_id = scenario.subject_data[subject_category_name][scenario.subject_assignments[subject_name][subject_category_name]]
+ add_subject_assignments(policy_id, subject_id, subject_cat_id, subject_data_id)
+
for object_name in scenario.object_assignments:
- for object_category_name in scenario.object_assignments[object_name]:
- object_id = scenario.objects[object_name]
- object_cat_id = scenario.object_categories[object_category_name]
- object_data_id = scenario.object_data[object_category_name][scenario.object_assignments[object_name][object_category_name]]
- add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
+ if type(scenario.object_assignments[object_name]) in (list, tuple):
+ for items in scenario.object_assignments[object_name]:
+ for object_category_name in items:
+ object_id = scenario.objects[object_name]
+ object_cat_id = scenario.object_categories[object_category_name]
+ for data in scenario.object_assignments[object_name]:
+ object_data_id = scenario.object_data[object_category_name][data[object_category_name]]
+ add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
+ else:
+ for object_category_name in scenario.object_assignments[object_name]:
+ object_id = scenario.objects[object_name]
+ object_cat_id = scenario.object_categories[object_category_name]
+ object_data_id = scenario.object_data[object_category_name][scenario.object_assignments[object_name][object_category_name]]
+ add_object_assignments(policy_id, object_id, object_cat_id, object_data_id)
+
for action_name in scenario.action_assignments:
- for action_category_name in scenario.action_assignments[action_name]:
- action_id = scenario.actions[action_name]
- action_cat_id = scenario.action_categories[action_category_name]
- action_data_id = scenario.action_data[action_category_name][scenario.action_assignments[action_name][action_category_name]]
- add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
+ if type(scenario.action_assignments[action_name]) in (list, tuple):
+ for items in scenario.action_assignments[action_name]:
+ for action_category_name in items:
+ action_id = scenario.actions[action_name]
+ action_cat_id = scenario.action_categories[action_category_name]
+ for data in scenario.action_assignments[action_name]:
+ action_data_id = scenario.action_data[action_category_name][data[action_category_name]]
+ add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
+ else:
+ for action_category_name in scenario.action_assignments[action_name]:
+ action_id = scenario.actions[action_name]
+ action_cat_id = scenario.action_categories[action_category_name]
+ action_data_id = scenario.action_data[action_category_name][scenario.action_assignments[action_name][action_category_name]]
+ add_action_assignments(policy_id, action_id, action_cat_id, action_data_id)
for meta_rule_name in scenario.rules:
meta_rule_value = scenario.meta_rule[meta_rule_name]
diff --git a/moonv4/moon_interface/tests/apitests/scenario/rbac.py b/moonv4/moon_interface/tests/apitests/scenario/rbac.py
index a43bd1f4..89fd7de8 100644
--- a/moonv4/moon_interface/tests/apitests/scenario/rbac.py
+++ b/moonv4/moon_interface/tests/apitests/scenario/rbac.py
@@ -2,6 +2,7 @@
pdp_name = "pdp1"
policy_name = "RBAC policy example"
model_name = "RBAC"
+policy_genre = "authz"
subjects = {"user0": "", "user1": "", }
objects = {"vm0": "", "vm1": "", }
@@ -11,13 +12,13 @@ subject_categories = {"role": "", }
object_categories = {"id": "", }
action_categories = {"action-type": "", }
-subject_data = {"role": {"admin": "", "employee": ""}}
-object_data = {"id": {"vm0": "", "vm1": ""}}
-action_data = {"action-type": {"vm-action": "", }}
+subject_data = {"role": {"admin": "", "employee": "", "*": ""}}
+object_data = {"id": {"vm0": "", "vm1": "", "*": ""}}
+action_data = {"action-type": {"vm-action": "", "*": ""}}
-subject_assignments = {"user0": {"role": "employee"}, "user1": {"role": "employee"}, }
-object_assignments = {"vm0": {"id": "vm0"}, "vm1": {"id": "vm1"}}
-action_assignments = {"start": {"action-type": "vm-action"}, "stop": {"action-type": "vm-action"}}
+subject_assignments = {"user0": ({"role": "employee"}, {"role": "*"}), "user1": ({"role": "employee"}, {"role": "*"}), }
+object_assignments = {"vm0": ({"id": "vm0"}, {"id": "*"}), "vm1": ({"id": "vm1"}, {"id": "*"})}
+action_assignments = {"start": ({"action-type": "vm-action"}, {"action-type": "*"}), "stop": ({"action-type": "vm-action"}, {"action-type": "*"})}
meta_rule = {
"rbac": {"id": "", "value": ("role", "id", "action-type")},
@@ -28,13 +29,13 @@ rules = {
{
"rule": ("admin", "vm0", "vm-action"),
"instructions": (
- {"decision": "grant"} # "grant" to immediately exit, "continue" to wait for the result of next policy
+ {"decision": "grant"}, # "grant" to immediately exit, "continue" to wait for the result of next policy
)
},
{
- "rule": ("admin", "vm1", "vm-action"),
+ "rule": ("employee", "vm1", "vm-action"),
"instructions": (
- {"decision": "grant"}
+ {"decision": "grant"},
)
},
)
diff --git a/moonv4/moon_interface/tests/apitests/scenario/session.py b/moonv4/moon_interface/tests/apitests/scenario/session.py
index 6b7e0f18..97d7aec3 100644
--- a/moonv4/moon_interface/tests/apitests/scenario/session.py
+++ b/moonv4/moon_interface/tests/apitests/scenario/session.py
@@ -2,6 +2,7 @@
pdp_name = "pdp1"
policy_name = "Session policy example"
model_name = "Session"
+policy_genre = "session"
subjects = {"user0": "", "user1": "", }
objects = {"admin": "", "employee": "", }
@@ -12,12 +13,16 @@ object_categories = {"role": "", }
action_categories = {"session-action": "", }
subject_data = {"subjectid": {"user0": "", "user1": ""}}
-object_data = {"role": {"admin": "", "employee": ""}}
-action_data = {"session-action": {"activate": "", "deactivate": ""}}
+object_data = {"role": {"admin": "", "employee": "", "*": ""}}
+action_data = {"session-action": {"activate": "", "deactivate": "", "*": ""}}
-subject_assignments = {"user0": {"subjectid": "user0"}, "user1": {"subjectid": "user1"}, }
-object_assignments = {"admin": {"role": "admin"}, "employee": {"role": "employee"}}
-action_assignments = {"activate": {"session-action": "activate"}, "deactivate": {"session-action": "deactivate"}}
+subject_assignments = {"user0": ({"subjectid": "user0"}, ), "user1": ({"subjectid": "user1"}, ), }
+object_assignments = {"admin": ({"role": "admin"}, {"role": "*"}),
+ "employee": ({"role": "employee"}, {"role": "employee"})
+ }
+action_assignments = {"activate": ({"session-action": "activate"}, {"session-action": "*"}, ),
+ "deactivate": ({"session-action": "deactivate"}, {"session-action": "*"}, )
+ }
meta_rule = {
"session": {"id": "", "value": ("subjectid", "role", "session-action")},
@@ -26,7 +31,7 @@ meta_rule = {
rules = {
"session": (
{
- "rule": ("user0", "admin", "activate"),
+ "rule": ("user0", "employee", "*"),
"instructions": (
{
"update": {
@@ -34,11 +39,11 @@ rules = {
"target": "rbac:role:admin" # add the role admin to the current user
}
},
- {"chain": [{"security_pipeline": "rbac"}]} # chain with the meta_rule named rbac
+ {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
)
},
{
- "rule": ("user1", "employee", "deactivate"),
+ "rule": ("user1", "employee", "*"),
"instructions": (
{
"update": {
@@ -46,7 +51,7 @@ rules = {
"target": "rbac:role:employee" # delete the role employee from the current user
}
},
- {"chain": [{"security_pipeline": "rbac"}]} # chain with the meta_rule named rbac
+ {"chain": {"name": "rbac"}} # chain with the meta_rule named rbac
)
},
)
diff --git a/moonv4/moon_interface/tests/apitests/set_authz.py b/moonv4/moon_interface/tests/apitests/set_authz.py
index 38b63509..f515e4eb 100644
--- a/moonv4/moon_interface/tests/apitests/set_authz.py
+++ b/moonv4/moon_interface/tests/apitests/set_authz.py
@@ -41,10 +41,13 @@ for rule in rules:
url = "http://172.18.0.11:38001/authz/{}/{}".format(keystone_project_id, "/".join(rule))
req = requests.get(url)
print("\033[1m{}\033[m {}".format(url, req.status_code))
- j = req.json()
- # print(j)
- if j.get("authz"):
- print("\t\033[32m{}\033[m {}".format(j.get("authz"), j.get("error", "")))
+ try:
+ j = req.json()
+ except Exception as e:
+ print(req.text)
else:
- print("\t\033[31m{}\033[m {}".format(j.get("authz"), j.get("error", "")))
+ if j.get("authz"):
+ print("\t\033[32m{}\033[m {}".format(j.get("authz"), j.get("error", "")))
+ else:
+ print("\t\033[31m{}\033[m {}".format(j.get("authz"), j.get("error", "")))
diff --git a/moonv4/moon_interface/tests/apitests/utils/policies.py b/moonv4/moon_interface/tests/apitests/utils/policies.py
index bf75734f..969ab70b 100644
--- a/moonv4/moon_interface/tests/apitests/utils/policies.py
+++ b/moonv4/moon_interface/tests/apitests/utils/policies.py
@@ -63,8 +63,9 @@ def check_policy(policy_id=None):
assert policy_template["name"] == result['policies'][policy_id]["name"]
-def add_policy(name="test_policy"):
+def add_policy(name="test_policy", genre="authz"):
policy_template["name"] = name
+ policy_template["genre"] = genre
req = requests.post(URL.format("/policies"), json=policy_template, headers=HEADERS)
assert req.status_code == 200
result = req.json()
diff --git a/moonv4/moon_orchestrator/conf/plugins/session.py b/moonv4/moon_orchestrator/conf/plugins/session.py
new file mode 100644
index 00000000..6fa2cfe2
--- /dev/null
+++ b/moonv4/moon_orchestrator/conf/plugins/session.py
@@ -0,0 +1,67 @@
+# 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
+import time
+import hashlib
+from oslo_config import cfg
+from oslo_log import log as logging
+import oslo_messaging
+from moon_orchestrator.dockers import DockerBase
+
+LOG = logging.getLogger(__name__)
+CONF = cfg.CONF
+DOMAIN = "moon_orchestrator"
+
+__CWD__ = os.path.dirname(os.path.abspath(__file__))
+# TODO (asteroide): select the right template folder
+TEMPLATES_FOLDER = os.path.join(__CWD__, "..", "conf", "dockers")
+# TODO (asteroide): add specific configuration options for that plugin
+
+
+class AuthzFunction(DockerBase):
+
+ id = "moon_session_function"
+ __build = """RUN mkdir -p /etc/moon/
+COPY conf /etc/moon/
+ADD dist/{py_pkg}.tar.gz /root
+WORKDIR /root/{py_pkg}
+RUN pip3 install -r requirements.txt
+RUN pip3 install .
+"""
+
+ def __init__(self, uuid, conf_file="", docker=None, network_config=None):
+ self.id = "session_"+hashlib.sha224(uuid.encode("utf-8")).hexdigest()
+ super(AuthzFunction, self).__init__(
+ name="moon_authz",
+ run_cmd=["python3", "-m", "moon_authz", uuid],
+ conf_file=conf_file,
+ docker=docker,
+ network_config=network_config,
+ build_cmd=self.__build,
+ id=self.id,
+ tag=""
+ # tag=CONF.security_function.container
+ )
+ # note(asteroide): time to let the new docker boot
+ time.sleep(3)
+ # self.get_status()
+
+ def get_status(self):
+ return True
+ # transport = oslo_messaging.get_transport(CONF)
+ # target = oslo_messaging.Target(topic=self.id, version='1.0')
+ # client = oslo_messaging.RPCClient(transport, target)
+ # LOG.info("Calling Status on {}".format(self.id))
+ # ret = client.call({"component_id": self.id}, 'get_status', args=None)
+ # LOG.info(ret)
+ # return ret
+
+
+def run(uuid, conf_file="", docker=None, network_config=None):
+ return AuthzFunction(uuid,
+ conf_file=conf_file,
+ docker=docker,
+ network_config=network_config)
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py b/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py
index 3572d615..2ed5b266 100644
--- a/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py
+++ b/moonv4/moon_orchestrator/moon_orchestrator/api/containers.py
@@ -109,7 +109,7 @@ class Containers(object):
"meta_rule_id": meta_rule,
"genre": policy_value['genre'],
"keystone_project_id": keystone_project_id,
- "container_id": "authz_"+hashlib.sha224(pre_container_id.encode("utf-8")).hexdigest()
+ "container_id": policy_value['genre']+"_"+hashlib.sha224(pre_container_id.encode("utf-8")).hexdigest()
})
return {"containers": self.components[ctx["id"]]}
# function_components = []
diff --git a/moonv4/moon_orchestrator/moon_orchestrator/server.py b/moonv4/moon_orchestrator/moon_orchestrator/server.py
index 4fc9d5fd..e6d28c23 100644
--- a/moonv4/moon_orchestrator/moon_orchestrator/server.py
+++ b/moonv4/moon_orchestrator/moon_orchestrator/server.py
@@ -62,7 +62,7 @@ class DockerManager:
:param uuid: the uuid of the intra_extension linked to that component
:return: the created component
"""
- component_id = "authz_"+hashlib.sha224(uuid.encode("utf-8")).hexdigest()
+ component_id = component+"_"+hashlib.sha224(uuid.encode("utf-8")).hexdigest()
if component_id not in CONTAINERS:
plug = load_plugin(component)
LOG.info("Creating {} with id {}".format(component, uuid))
diff --git a/moonv4/moon_secrouter/moon_secrouter/api/route.py b/moonv4/moon_secrouter/moon_secrouter/api/route.py
index ccdff08b..7cce1353 100644
--- a/moonv4/moon_secrouter/moon_secrouter/api/route.py
+++ b/moonv4/moon_secrouter/moon_secrouter/api/route.py
@@ -200,7 +200,12 @@ class Cache(object):
for container_id, container_values, in CACHE.containers.items():
for container_value in container_values:
if container_value["meta_rule_id"] == meta_rule_id:
- container_ids.append(container_value["container_id"])
+ container_ids.append(
+ {
+ "container_id": container_value["container_id"],
+ "genre": container_value["genre"]
+ }
+ )
break
self.__CONTAINER_CHAINING[keystone_project_id] = container_ids
@@ -227,7 +232,7 @@ CACHE = Cache()
class AuthzRequest:
result = None
- req_max_delay = 5
+ req_max_delay = 2
def __init__(self, ctx, args):
self.ctx = ctx
@@ -235,7 +240,7 @@ class AuthzRequest:
self.request_id = ctx["request_id"]
self.container_chaining = CACHE.container_chaining[self.ctx['id']]
ctx["container_chaining"] = copy.deepcopy(self.container_chaining)
- self.pdp_container = str(self.container_chaining[0])
+ self.pdp_container = self.container_chaining[0]["container_id"]
self.run()
def run(self):
@@ -256,8 +261,16 @@ class AuthzRequest:
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"
diff --git a/moonv4/moon_utilities/moon_utilities/security_functions.py b/moonv4/moon_utilities/moon_utilities/security_functions.py
index f7cbdf2c..5d66d927 100644
--- a/moonv4/moon_utilities/moon_utilities/security_functions.py
+++ b/moonv4/moon_utilities/moon_utilities/security_functions.py
@@ -168,8 +168,10 @@ def notify(request_id, container_id, payload, event_type="authz"):
'request_id': request_id,
'container_id': container_id
}
- result = __n_notifier.critical(ctxt, event_type, payload=payload)
- return result
+ __n_notifier.critical(ctxt, event_type, payload=payload)
+ # FIXME (asteroide): the notification mus be done 2 times otherwise the notification
+ # may not be sent (need to search why)
+ __n_notifier.critical(ctxt, event_type, payload=payload)
def call(endpoint, ctx=None, method="get_status", **kwargs):
@@ -249,34 +251,66 @@ class Context:
self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header]
self.__pdp_set[header]["target"] = self.__add_target(header)
# TODO (asteroide): the following information must be retrieve somewhere
- self.__pdp_set[header]["instruction"] = list()
- self.__pdp_set[header]["effect"] = "deny"
+ self.__pdp_set[header]["effect"] = "unset"
self.__pdp_set["effect"] = "deny"
+ @staticmethod
+ def update_target(context):
+ from moon_db.core import PDPManager, ModelManager, PolicyManager
+ # result = dict()
+ current_request = context['current_request']
+ _subject = current_request.get("subject")
+ _object = current_request.get("object")
+ _action = current_request.get("action")
+ meta_rule_id = context['headers'][context['index']]
+ policy_id = PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ meta_rules = ModelManager.get_meta_rules("admin")
+ # for meta_rule_id in meta_rules:
+ for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
+ if sub_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ context["pdp_set"][meta_rule_id]["target"][sub_cat] = []
+ for assign in PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
+ for assign in assign["assignments"]:
+ if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]:
+ context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign)
+ for obj_cat in meta_rules[meta_rule_id]['object_categories']:
+ if obj_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ context["pdp_set"][meta_rule_id]["target"][obj_cat] = []
+ for assign in PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
+ for assign in assign["assignments"]:
+ if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]:
+ context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign)
+ for act_cat in meta_rules[meta_rule_id]['action_categories']:
+ if act_cat not in context["pdp_set"][meta_rule_id]["target"]:
+ context["pdp_set"][meta_rule_id]["target"][act_cat] = []
+ for assign in PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
+ for assign in assign["assignments"]:
+ if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]:
+ context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign)
+ # context["pdp_set"][meta_rule_id]["target"].update(result)
+
def __add_target(self, meta_rule_id):
result = dict()
_subject = self.__current_request["subject"]
_object = self.__current_request["object"]
_action = self.__current_request["action"]
meta_rules = self.ModelManager.get_meta_rules("admin")
- for header in self.__headers:
- policy_id = self.PolicyManager.get_policy_from_meta_rules("admin", header)
- for meta_rule_id in meta_rules:
- for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
- if sub_cat not in result:
- result[sub_cat] = []
- for assign in self.PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
- result[sub_cat].extend(assign["assignments"])
- for obj_cat in meta_rules[meta_rule_id]['object_categories']:
- if obj_cat not in result:
- result[obj_cat] = []
- for assign in self.PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
- result[obj_cat].extend(assign["assignments"])
- for act_cat in meta_rules[meta_rule_id]['action_categories']:
- if act_cat not in result:
- result[act_cat] = []
- for assign in self.PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
- result[act_cat].extend(assign["assignments"])
+ policy_id = self.PolicyManager.get_policy_from_meta_rules("admin", meta_rule_id)
+ for sub_cat in meta_rules[meta_rule_id]['subject_categories']:
+ if sub_cat not in result:
+ result[sub_cat] = []
+ for assign in self.PolicyManager.get_subject_assignments("admin", policy_id, _subject, sub_cat).values():
+ result[sub_cat].extend(assign["assignments"])
+ for obj_cat in meta_rules[meta_rule_id]['object_categories']:
+ if obj_cat not in result:
+ result[obj_cat] = []
+ for assign in self.PolicyManager.get_object_assignments("admin", policy_id, _object, obj_cat).values():
+ result[obj_cat].extend(assign["assignments"])
+ for act_cat in meta_rules[meta_rule_id]['action_categories']:
+ if act_cat not in result:
+ result[act_cat] = []
+ for assign in self.PolicyManager.get_action_assignments("admin", policy_id, _action, act_cat).values():
+ result[act_cat].extend(assign["assignments"])
return result
def __repr__(self):