Check for circular references when expanding implied roles
closes-bug #1536321 Change-Id: I30d4f54135864d10093437a0541d6f40255e40e2
This commit is contained in:
parent
dc01e06ab4
commit
2a5599811e
|
@ -28,7 +28,7 @@ from keystone.common import driver_hints
|
|||
from keystone.common import manager
|
||||
from keystone import exception
|
||||
from keystone.i18n import _
|
||||
from keystone.i18n import _LI
|
||||
from keystone.i18n import _LI, _LE
|
||||
from keystone import notifications
|
||||
|
||||
|
||||
|
@ -612,8 +612,10 @@ class Manager(manager.Manager):
|
|||
implied_roles_cache = {}
|
||||
role_refs_to_check = list(role_refs)
|
||||
ref_results = list(role_refs)
|
||||
checked_role_refs = list()
|
||||
while(role_refs_to_check):
|
||||
next_ref = role_refs_to_check.pop()
|
||||
checked_role_refs.append(next_ref)
|
||||
next_role_id = next_ref['role_id']
|
||||
if next_role_id in implied_roles_cache:
|
||||
implied_roles = implied_roles_cache[next_role_id]
|
||||
|
@ -625,8 +627,13 @@ class Manager(manager.Manager):
|
|||
implied_ref = (
|
||||
_make_implied_ref_copy(
|
||||
next_ref, implied_role['implied_role_id']))
|
||||
ref_results.append(implied_ref)
|
||||
role_refs_to_check.append(implied_ref)
|
||||
if implied_ref in checked_role_refs:
|
||||
msg = _LE('Circular reference found '
|
||||
'role inference rules - %(prior_role_id)s.')
|
||||
LOG.error(msg, {'prior_role_id': next_ref['role_id']})
|
||||
else:
|
||||
ref_results.append(implied_ref)
|
||||
role_refs_to_check.append(implied_ref)
|
||||
except exception.NotImplemented:
|
||||
LOG.error('Role driver does not support implied roles.')
|
||||
|
||||
|
|
|
@ -6560,6 +6560,37 @@ class ImpliedRoleTests(AssignmentTestHelperMixin):
|
|||
}
|
||||
self.execute_assignment_plan(test_plan)
|
||||
|
||||
def test_circular_inferences(self):
|
||||
"""Test that implied roles are expanded out."""
|
||||
test_plan = {
|
||||
'entities': {'domains': {'users': 1, 'projects': 1},
|
||||
'roles': 4},
|
||||
# Three level tree of implied roles
|
||||
'implied_roles': [{'role': 0, 'implied_roles': [1]},
|
||||
{'role': 1, 'implied_roles': [2, 3]},
|
||||
{'role': 3, 'implied_roles': [0]}],
|
||||
'assignments': [{'user': 0, 'role': 0, 'project': 0}],
|
||||
'tests': [
|
||||
# List all direct assignments for user[0], this should just
|
||||
# show the one top level role assignment
|
||||
{'params': {'user': 0},
|
||||
'results': [{'user': 0, 'role': 0, 'project': 0}]},
|
||||
# Listing in effective mode should show the implied roles
|
||||
# expanded out
|
||||
{'params': {'user': 0, 'effective': True},
|
||||
'results': [{'user': 0, 'role': 0, 'project': 0},
|
||||
{'user': 0, 'role': 0, 'project': 0,
|
||||
'indirect': {'role': 3}},
|
||||
{'user': 0, 'role': 1, 'project': 0,
|
||||
'indirect': {'role': 0}},
|
||||
{'user': 0, 'role': 2, 'project': 0,
|
||||
'indirect': {'role': 1}},
|
||||
{'user': 0, 'role': 3, 'project': 0,
|
||||
'indirect': {'role': 1}}]},
|
||||
]
|
||||
}
|
||||
self.execute_assignment_plan(test_plan)
|
||||
|
||||
def test_role_assignments_directed_graph_of_implied_roles(self):
|
||||
"""Test that a role can have multiple, different prior roles."""
|
||||
test_plan = {
|
||||
|
@ -6570,7 +6601,7 @@ class ImpliedRoleTests(AssignmentTestHelperMixin):
|
|||
'implied_roles': [{'role': 0, 'implied_roles': [1, 2]},
|
||||
{'role': 1, 'implied_roles': [3, 4]},
|
||||
{'role': 5, 'implied_roles': 4}],
|
||||
# The use gets both top level roles
|
||||
# The user gets both top level roles
|
||||
'assignments': [{'user': 0, 'role': 0, 'project': 0},
|
||||
{'user': 0, 'role': 5, 'project': 0}],
|
||||
'tests': [
|
||||
|
|
Loading…
Reference in New Issue