mirror of
https://github.com/ansible/awx.git
synced 2026-03-22 11:25:08 -02:30
Fix object-level permission bugs with DAB RBAC system (#15284)
* Fix object-level permission bugs with DAB RBAC system * Fix NT organization change regression * Mark tests to AAP number
This commit is contained in:
@@ -598,7 +598,7 @@ class InstanceGroupAccess(BaseAccess):
|
|||||||
- a superuser
|
- a superuser
|
||||||
- admin role on the Instance group
|
- admin role on the Instance group
|
||||||
I can add/delete Instance Groups:
|
I can add/delete Instance Groups:
|
||||||
- a superuser(system administrator)
|
- a superuser(system administrator), because these are not org-scoped
|
||||||
I can use Instance Groups when I have:
|
I can use Instance Groups when I have:
|
||||||
- use_role on the instance group
|
- use_role on the instance group
|
||||||
"""
|
"""
|
||||||
@@ -627,7 +627,7 @@ class InstanceGroupAccess(BaseAccess):
|
|||||||
def can_delete(self, obj):
|
def can_delete(self, obj):
|
||||||
if obj.name in [settings.DEFAULT_EXECUTION_QUEUE_NAME, settings.DEFAULT_CONTROL_PLANE_QUEUE_NAME]:
|
if obj.name in [settings.DEFAULT_EXECUTION_QUEUE_NAME, settings.DEFAULT_CONTROL_PLANE_QUEUE_NAME]:
|
||||||
return False
|
return False
|
||||||
return self.user.is_superuser
|
return self.user.has_obj_perm(obj, 'delete')
|
||||||
|
|
||||||
|
|
||||||
class UserAccess(BaseAccess):
|
class UserAccess(BaseAccess):
|
||||||
@@ -2628,7 +2628,7 @@ class ScheduleAccess(UnifiedCredentialsMixin, BaseAccess):
|
|||||||
|
|
||||||
class NotificationTemplateAccess(BaseAccess):
|
class NotificationTemplateAccess(BaseAccess):
|
||||||
"""
|
"""
|
||||||
I can see/use a notification_template if I have permission to
|
Run standard logic from DAB RBAC
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = NotificationTemplate
|
model = NotificationTemplate
|
||||||
@@ -2649,10 +2649,7 @@ class NotificationTemplateAccess(BaseAccess):
|
|||||||
|
|
||||||
@check_superuser
|
@check_superuser
|
||||||
def can_change(self, obj, data):
|
def can_change(self, obj, data):
|
||||||
if obj.organization is None:
|
return self.user.has_obj_perm(obj, 'change') and self.check_related('organization', Organization, data, obj=obj, role_field='notification_admin_role')
|
||||||
# only superusers are allowed to edit orphan notification templates
|
|
||||||
return False
|
|
||||||
return self.check_related('organization', Organization, data, obj=obj, role_field='notification_admin_role', mandatory=True)
|
|
||||||
|
|
||||||
def can_admin(self, obj, data):
|
def can_admin(self, obj, data):
|
||||||
return self.can_change(obj, data)
|
return self.can_change(obj, data)
|
||||||
@@ -2662,9 +2659,7 @@ class NotificationTemplateAccess(BaseAccess):
|
|||||||
|
|
||||||
@check_superuser
|
@check_superuser
|
||||||
def can_start(self, obj, validate_license=True):
|
def can_start(self, obj, validate_license=True):
|
||||||
if obj.organization is None:
|
return self.can_change(obj, None)
|
||||||
return False
|
|
||||||
return self.user in obj.organization.notification_admin_role
|
|
||||||
|
|
||||||
|
|
||||||
class NotificationAccess(BaseAccess):
|
class NotificationAccess(BaseAccess):
|
||||||
|
|||||||
@@ -32,13 +32,6 @@ def node_type_instance():
|
|||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def instance_group(job_factory):
|
|
||||||
ig = InstanceGroup(name="east")
|
|
||||||
ig.save()
|
|
||||||
return ig
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def containerized_instance_group(instance_group, kube_credential):
|
def containerized_instance_group(instance_group, kube_credential):
|
||||||
ig = InstanceGroup(name="container")
|
ig = InstanceGroup(name="container")
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from awx.main.migrations._dab_rbac import setup_managed_role_definitions
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models.projects import Project
|
from awx.main.models.projects import Project
|
||||||
from awx.main.models.ha import Instance
|
from awx.main.models.ha import Instance, InstanceGroup
|
||||||
|
|
||||||
from rest_framework.test import (
|
from rest_framework.test import (
|
||||||
APIRequestFactory,
|
APIRequestFactory,
|
||||||
@@ -730,6 +730,11 @@ def jt_linked(organization, project, inventory, machine_credential, credential,
|
|||||||
return jt
|
return jt
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def instance_group():
|
||||||
|
return InstanceGroup.objects.create(name="east")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def workflow_job_template(organization):
|
def workflow_job_template(organization):
|
||||||
wjt = WorkflowJobTemplate.objects.create(name='test-workflow_job_template', organization=organization)
|
wjt = WorkflowJobTemplate.objects.create(name='test-workflow_job_template', organization=organization)
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from awx.main.access import InstanceGroupAccess, NotificationTemplateAccess
|
||||||
|
|
||||||
|
from ansible_base.rbac.models import RoleDefinition
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_instance_group_object_role_delete(rando, instance_group, setup_managed_roles):
|
||||||
|
"""Basic functionality of IG object-level admin role function AAP-25506"""
|
||||||
|
rd = RoleDefinition.objects.get(name='InstanceGroup Admin')
|
||||||
|
rd.give_permission(rando, instance_group)
|
||||||
|
access = InstanceGroupAccess(rando)
|
||||||
|
assert access.can_delete(instance_group)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_notification_template_object_role_change(rando, notification_template, setup_managed_roles):
|
||||||
|
"""Basic functionality of NT object-level admin role function AAP-25493"""
|
||||||
|
rd = RoleDefinition.objects.get(name='NotificationTemplate Admin')
|
||||||
|
rd.give_permission(rando, notification_template)
|
||||||
|
access = NotificationTemplateAccess(rando)
|
||||||
|
assert access.can_change(notification_template, {'name': 'new name'})
|
||||||
@@ -99,7 +99,9 @@ def test_notification_template_access_org_user(notification_template, user):
|
|||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_notificaiton_template_orphan_access_org_admin(notification_template, organization, org_admin):
|
def test_notificaiton_template_orphan_access_org_admin(notification_template, organization, org_admin):
|
||||||
notification_template.organization = None
|
notification_template.organization = None
|
||||||
|
notification_template.save(update_fields=['organization'])
|
||||||
access = NotificationTemplateAccess(org_admin)
|
access = NotificationTemplateAccess(org_admin)
|
||||||
|
assert not org_admin.has_obj_perm(notification_template, 'change')
|
||||||
assert not access.can_change(notification_template, {'organization': organization.id})
|
assert not access.can_change(notification_template, {'organization': organization.id})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user