mirror of
https://github.com/ansible/awx.git
synced 2026-03-05 02:31:03 -03:30
Fix organization not showing all galaxy credentials for org admin (#13676)
* Fix organization not showing all galaxy credentials for org admin * Add basic test to ensure counts * refactored approach to allow removal of redundant code * Allow configurable prefetch_related * implicitly get related fields * Removed extra queryset code
This commit is contained in:
@@ -510,6 +510,9 @@ class SubListAPIView(ParentMixin, ListAPIView):
|
|||||||
# And optionally (user must have given access permission on parent object
|
# And optionally (user must have given access permission on parent object
|
||||||
# to view sublist):
|
# to view sublist):
|
||||||
# parent_access = 'read'
|
# parent_access = 'read'
|
||||||
|
# filter_read_permission sets whether or not to override the default intersection behavior
|
||||||
|
# implemented here
|
||||||
|
filter_read_permission = True
|
||||||
|
|
||||||
def get_description_context(self):
|
def get_description_context(self):
|
||||||
d = super(SubListAPIView, self).get_description_context()
|
d = super(SubListAPIView, self).get_description_context()
|
||||||
@@ -524,8 +527,14 @@ class SubListAPIView(ParentMixin, ListAPIView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
parent = self.get_parent_object()
|
parent = self.get_parent_object()
|
||||||
self.check_parent_access(parent)
|
self.check_parent_access(parent)
|
||||||
qs = self.request.user.get_queryset(self.model).distinct()
|
|
||||||
sublist_qs = self.get_sublist_queryset(parent)
|
sublist_qs = self.get_sublist_queryset(parent)
|
||||||
|
if not self.filter_read_permission:
|
||||||
|
access_class = access_registry[self.model]
|
||||||
|
if access_class.prefetch_related:
|
||||||
|
return sublist_qs.prefetch_related(*access_class.prefetch_related)
|
||||||
|
if access_class.select_related:
|
||||||
|
return sublist_qs.select_related(*access_class.select_related)
|
||||||
|
qs = self.request.user.get_queryset(self.model).distinct()
|
||||||
return qs & sublist_qs
|
return qs & sublist_qs
|
||||||
|
|
||||||
def get_sublist_queryset(self, parent):
|
def get_sublist_queryset(self, parent):
|
||||||
|
|||||||
@@ -2581,16 +2581,7 @@ class JobTemplateCredentialsList(SubListCreateAttachDetachAPIView):
|
|||||||
serializer_class = serializers.CredentialSerializer
|
serializer_class = serializers.CredentialSerializer
|
||||||
parent_model = models.JobTemplate
|
parent_model = models.JobTemplate
|
||||||
relationship = 'credentials'
|
relationship = 'credentials'
|
||||||
|
filter_read_permission = False
|
||||||
def get_queryset(self):
|
|
||||||
# Return the full list of credentials
|
|
||||||
parent = self.get_parent_object()
|
|
||||||
self.check_parent_access(parent)
|
|
||||||
sublist_qs = getattrd(parent, self.relationship)
|
|
||||||
sublist_qs = sublist_qs.prefetch_related(
|
|
||||||
'created_by', 'modified_by', 'admin_role', 'use_role', 'read_role', 'admin_role__parents', 'admin_role__members'
|
|
||||||
)
|
|
||||||
return sublist_qs
|
|
||||||
|
|
||||||
def is_valid_relation(self, parent, sub, created=False):
|
def is_valid_relation(self, parent, sub, created=False):
|
||||||
if sub.unique_hash() in [cred.unique_hash() for cred in parent.credentials.all()]:
|
if sub.unique_hash() in [cred.unique_hash() for cred in parent.credentials.all()]:
|
||||||
@@ -2780,6 +2771,7 @@ class JobTemplateInstanceGroupsList(SubListAttachDetachAPIView):
|
|||||||
serializer_class = serializers.InstanceGroupSerializer
|
serializer_class = serializers.InstanceGroupSerializer
|
||||||
parent_model = models.JobTemplate
|
parent_model = models.JobTemplate
|
||||||
relationship = 'instance_groups'
|
relationship = 'instance_groups'
|
||||||
|
filter_read_permission = False
|
||||||
|
|
||||||
|
|
||||||
class JobTemplateAccessList(ResourceAccessList):
|
class JobTemplateAccessList(ResourceAccessList):
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
|
|||||||
serializer_class = InstanceGroupSerializer
|
serializer_class = InstanceGroupSerializer
|
||||||
parent_model = Organization
|
parent_model = Organization
|
||||||
relationship = 'instance_groups'
|
relationship = 'instance_groups'
|
||||||
|
filter_read_permission = False
|
||||||
|
|
||||||
|
|
||||||
class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
|
class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
|
||||||
@@ -214,6 +215,7 @@ class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
|
|||||||
serializer_class = CredentialSerializer
|
serializer_class = CredentialSerializer
|
||||||
parent_model = Organization
|
parent_model = Organization
|
||||||
relationship = 'galaxy_credentials'
|
relationship = 'galaxy_credentials'
|
||||||
|
filter_read_permission = False
|
||||||
|
|
||||||
def is_valid_relation(self, parent, sub, created=False):
|
def is_valid_relation(self, parent, sub, created=False):
|
||||||
if sub.kind != 'galaxy_api_token':
|
if sub.kind != 'galaxy_api_token':
|
||||||
|
|||||||
@@ -329,3 +329,21 @@ def test_galaxy_credential_association(alice, admin, organization, post, get):
|
|||||||
'Public Galaxy 4',
|
'Public Galaxy 4',
|
||||||
'Public Galaxy 5',
|
'Public Galaxy 5',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_org_admin_credential_count(org_admin, admin, organization, post, get):
|
||||||
|
galaxy = CredentialType.defaults['galaxy_api_token']()
|
||||||
|
galaxy.save()
|
||||||
|
|
||||||
|
for i in range(3):
|
||||||
|
cred = Credential.objects.create(credential_type=galaxy, name=f'test_{i}', inputs={'url': 'https://galaxy.ansible.com/'})
|
||||||
|
url = reverse('api:organization_galaxy_credentials_list', kwargs={'pk': organization.pk})
|
||||||
|
post(url, {'associate': True, 'id': cred.pk}, user=admin, expect=204)
|
||||||
|
# org admin should see all associated galaxy credentials
|
||||||
|
resp = get(url, user=org_admin)
|
||||||
|
assert resp.data['count'] == 3
|
||||||
|
# removing one to validate new count
|
||||||
|
post(url, {'disassociate': True, 'id': Credential.objects.get(name='test_1').pk}, user=admin, expect=204)
|
||||||
|
resp_new = get(url, user=org_admin)
|
||||||
|
assert resp_new.data['count'] == 2
|
||||||
|
|||||||
Reference in New Issue
Block a user