From f5e4f5679625dd4834f9deaebda3cb2d6eac2520 Mon Sep 17 00:00:00 2001 From: Alan Rominger Date: Tue, 2 Apr 2024 15:30:01 -0400 Subject: [PATCH] Fix missing role membership when giving creator permissions --- awx/main/models/rbac.py | 26 ++++++++++++++++++- .../dab_rbac/test_translation_layer.py | 9 ++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/awx/main/models/rbac.py b/awx/main/models/rbac.py index d99f52f4dded..ff38686efb02 100644 --- a/awx/main/models/rbac.py +++ b/awx/main/models/rbac.py @@ -602,13 +602,37 @@ def give_or_remove_permission(role, actor, giving=True): rd.give_or_remove_permission(actor, obj, giving=giving) +class SyncEnabled(threading.local): + def __init__(self): + self.enabled = True + + +rbac_sync_enabled = SyncEnabled() + + +@contextlib.contextmanager +def disable_rbac_sync(): + try: + previous_value = rbac_sync_enabled.enabled + rbac_sync_enabled.enabled = False + yield + finally: + rbac_sync_enabled.enabled = previous_value + + def give_creator_permissions(user, obj): - RoleDefinition.objects.give_creator_permissions(user, obj) + assignment = RoleDefinition.objects.give_creator_permissions(user, obj) + if assignment: + with disable_rbac_sync(): + old_role = get_role_from_object_role(assignment.object_role) + old_role.members.add(user) def sync_members_to_new_rbac(instance, action, model, pk_set, reverse, **kwargs): if action.startswith('pre_'): return + if not rbac_sync_enabled.enabled: + return if action == 'post_add': is_giving = True diff --git a/awx/main/tests/functional/dab_rbac/test_translation_layer.py b/awx/main/tests/functional/dab_rbac/test_translation_layer.py index 8d55c6e3ce40..18a1db402833 100644 --- a/awx/main/tests/functional/dab_rbac/test_translation_layer.py +++ b/awx/main/tests/functional/dab_rbac/test_translation_layer.py @@ -1,6 +1,6 @@ import pytest -from awx.main.models.rbac import get_role_from_object_role +from awx.main.models.rbac import get_role_from_object_role, give_creator_permissions from awx.main.models import User, Organization, WorkflowJobTemplate, WorkflowJobTemplateNode from awx.api.versioning import reverse @@ -74,3 +74,10 @@ def test_workflow_approval_list(get, post, admin_user): r = get(url=reverse('api:workflow_approval_list'), user=admin_user, expect=200) assert r.data['count'] >= 1 + + +@pytest.mark.django_db +def test_creator_permission(rando, admin_user, inventory): + give_creator_permissions(rando, inventory) + assert rando in inventory.admin_role + assert rando in inventory.admin_role.members.all()