mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 04:10:44 -03:30
Start RBAC unit testing system to test is_implicit_parent
This commit is contained in:
parent
bb292f817b
commit
169384ddbe
@ -96,31 +96,37 @@ def resolve_role_field(obj, field):
|
||||
return ret
|
||||
|
||||
|
||||
def is_implicit_parent(role, instance):
|
||||
def is_implicit_parent(parent_role, child_role):
|
||||
'''
|
||||
Determine if the parent_role is an implicit parent as defined by
|
||||
the model definition. This does not include any role parents that
|
||||
might have been set by the user.
|
||||
'''
|
||||
# Get the list of implicit parents that were defined at the class level.
|
||||
# We have to take this list from the class property to avoid including parents
|
||||
# that may have been added since the creation of the ImplicitRoleField
|
||||
implicit_parents = getattr(instance.content_object.__class__, instance.role_field).field.parent_role
|
||||
implicit_parents = getattr(
|
||||
child_role.content_object.__class__, child_role.role_field
|
||||
).field.parent_role
|
||||
if type(implicit_parents) != list:
|
||||
implicit_parents = [implicit_parents]
|
||||
|
||||
# Check to see if the role matches any in the implicit parents list
|
||||
for implicit_parent_path in implicit_parents:
|
||||
if '.' in implicit_parent_path:
|
||||
# Walk over multiple related objects to obtain the implicit parent
|
||||
obj = instance.content_object
|
||||
for next_field in implicit_parent_path.split('.')[:-1]:
|
||||
obj = getattr(obj, next_field)
|
||||
if obj is None:
|
||||
return True
|
||||
if role == getattr(obj, implicit_parent_path.split('.')[-1]):
|
||||
related_obj = child_role.content_object
|
||||
for next_field in implicit_parent_path.split('.'):
|
||||
related_obj = getattr(related_obj, next_field)
|
||||
if related_obj is None:
|
||||
break
|
||||
if related_obj and parent_role == related_obj:
|
||||
return True
|
||||
elif implicit_parent_path.startswith('singleton:'):
|
||||
# Ignore any singleton parents we find.
|
||||
if role.is_singleton() and role.singleton_name == implicit_parent_path[10:]:
|
||||
# Singleton role isn't an object role, `singleton_name` uniquely identifies it
|
||||
if parent_role.is_singleton() and parent_role.singleton_name == implicit_parent_path[10:]:
|
||||
return True
|
||||
else:
|
||||
# Direct field on the content object
|
||||
if role == getattr(instance.content_object, implicit_parent_path):
|
||||
if parent_role == getattr(child_role.content_object, implicit_parent_path):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@ -181,7 +181,7 @@ def rbac_activity_stream(instance, sender, **kwargs):
|
||||
elif sender.__name__ == 'Role_parents':
|
||||
role = kwargs['model'].objects.filter(pk__in=kwargs['pk_set']).first()
|
||||
# don't record implicit creation / parents in activity stream
|
||||
if role is not None and is_implicit_parent(role, instance):
|
||||
if role is not None and is_implicit_parent(parent_role=role, child_role=instance):
|
||||
return
|
||||
else:
|
||||
role = instance
|
||||
|
||||
103
awx/main/tests/unit/models/test_rbac_unit.py
Normal file
103
awx/main/tests/unit/models/test_rbac_unit.py
Normal file
@ -0,0 +1,103 @@
|
||||
import pytest
|
||||
import mock
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from awx.main.models.rbac import (
|
||||
Role,
|
||||
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||
ROLE_SINGLETON_SYSTEM_AUDITOR
|
||||
)
|
||||
from awx.main.models import Organization, JobTemplate, Project
|
||||
|
||||
from awx.main.fields import (
|
||||
ImplicitRoleField,
|
||||
is_implicit_parent
|
||||
)
|
||||
|
||||
|
||||
def apply_fake_roles(obj):
|
||||
'''
|
||||
Creates an un-saved role for all the implicit role fields on an object
|
||||
'''
|
||||
for fd in obj._meta.fields:
|
||||
if not isinstance(fd, ImplicitRoleField):
|
||||
continue
|
||||
r = Role(role_field=fd.name)
|
||||
setattr(obj, fd.name, r)
|
||||
with mock.patch('django.contrib.contenttypes.fields.GenericForeignKey.get_content_type') as mck_ct:
|
||||
mck_ct.return_value = ContentType(model=obj._meta.model_name)
|
||||
r.content_object = obj
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def system_administrator():
|
||||
return Role(
|
||||
role_field=ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||
singleton_name=ROLE_SINGLETON_SYSTEM_ADMINISTRATOR
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def system_auditor():
|
||||
return Role(
|
||||
role_field=ROLE_SINGLETON_SYSTEM_AUDITOR,
|
||||
singleton_name=ROLE_SINGLETON_SYSTEM_AUDITOR
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def organization():
|
||||
o = Organization(name='unit-test-org')
|
||||
apply_fake_roles(o)
|
||||
return o
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def project(organization):
|
||||
p = Project(name='unit-test-proj', organization=organization)
|
||||
apply_fake_roles(p)
|
||||
return p
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def job_template(project):
|
||||
jt = JobTemplate(name='unit-test-jt', project=project)
|
||||
apply_fake_roles(jt)
|
||||
return jt
|
||||
|
||||
|
||||
class TestIsImplicitParent:
|
||||
'''
|
||||
Tests to confirm that `is_implicit_parent` gives the right answers
|
||||
'''
|
||||
def test_sys_admin_implicit_parent(self, organization, system_administrator):
|
||||
assert is_implicit_parent(
|
||||
parent_role=system_administrator,
|
||||
child_role=organization.admin_role
|
||||
)
|
||||
|
||||
|
||||
def test_admin_is_parent_of_member_role(self, organization):
|
||||
assert is_implicit_parent(
|
||||
parent_role=organization.admin_role,
|
||||
child_role=organization.member_role
|
||||
)
|
||||
|
||||
def test_member_is_not_parent_of_admin_role(self, organization):
|
||||
assert not is_implicit_parent(
|
||||
parent_role=organization.member_role,
|
||||
child_role=organization.admin_role
|
||||
)
|
||||
|
||||
def test_second_level_implicit_parent_role(self, job_template, organization):
|
||||
assert is_implicit_parent(
|
||||
parent_role=organization.admin_role,
|
||||
child_role=job_template.admin_role
|
||||
)
|
||||
|
||||
def test_second_level_is_not_an_implicit_parent_role(self, job_template, organization):
|
||||
assert not is_implicit_parent(
|
||||
parent_role=organization.member_role,
|
||||
child_role=job_template.admin_role
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user