diff --git a/awx/main/signals.py b/awx/main/signals.py index 8de53ee4b6..6451da0fe6 100644 --- a/awx/main/signals.py +++ b/awx/main/signals.py @@ -146,6 +146,21 @@ def sync_user_to_team_members_role(sender, reverse, model, instance, pk_set, act if action == 'pre_remove': instance.member_role.members.remove(user) +def sync_admin_to_org_admin_role(sender, reverse, model, instance, pk_set, action, **kwargs): + 'When a user is added or removed from Organization.admins, ensure that is reflected in Organization.admin_role' + if action == 'post_add' or action == 'pre_remove': + if reverse: + for org in Organization.objects.filter(id__in=pk_set).all(): + if action == 'post_add': + org.admin_role.members.add(instance) + if action == 'pre_remove': + org.admin_role.members.remove(instance) + else: + for user in User.objects.filter(id__in=pk_set).all(): + if action == 'post_add': + instance.admin_role.members.add(user) + if action == 'pre_remove': + instance.admin_role.members.remove(user) def sync_user_to_org_members_role(sender, reverse, model, instance, pk_set, action, **kwargs): 'When a user is added or removed from Organization.users, ensure that is reflected in Organization.member_role' @@ -198,6 +213,7 @@ post_save.connect(sync_superuser_status_to_rbac, sender=User) m2m_changed.connect(sync_user_to_team_members_role, Team.users.through) post_save.connect(create_user_resource, sender=User) m2m_changed.connect(sync_user_to_org_members_role, Organization.users.through) +m2m_changed.connect(sync_admin_to_org_admin_role, Organization.admins.through) # Migrate hosts, groups to parent group(s) whenever a group is deleted or # marked as inactive. diff --git a/awx/main/tests/functional/test_rbac_userresource.py b/awx/main/tests/functional/test_rbac_userresource.py index f666fb9eb0..f5e83438df 100644 --- a/awx/main/tests/functional/test_rbac_userresource.py +++ b/awx/main/tests/functional/test_rbac_userresource.py @@ -1,7 +1,7 @@ import pytest @pytest.mark.django_db -def test_user_resource_org_admin(user, organization): +def test_user_org_admin(user, organization): admin = user('orgadmin') member = user('orgmember') @@ -13,3 +13,30 @@ def test_user_resource_org_admin(user, organization): organization.admin_role.members.remove(admin) assert not member.resource.accessible_by(admin, {'write':True}) + +@pytest.mark.django_db +def test_org_user_admin(user, organization): + admin = user('orgadmin') + member = user('orgmember') + + organization.users.add(member) + assert not member.resource.accessible_by(admin, {'write':True}) + + organization.admins.add(admin) + assert member.resource.accessible_by(admin, {'write':True}) + + organization.admins.remove(admin) + assert not member.resource.accessible_by(admin, {'write':True}) + +@pytest.mark.django_db +def test_org_user_removed(user, organization): + admin = user('orgadmin') + member = user('orgmember') + + organization.admins.add(admin) + organization.users.add(member) + + assert member.resource.accessible_by(admin, {'write':True}) + + organization.users.remove(member) + assert not member.resource.accessible_by(admin, {'write':True})