From 96df8a6d374433591aa4bf74e460aaf86a151a36 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Mon, 6 Apr 2015 14:58:26 -0400 Subject: [PATCH] Add field on inventory detail to indicate if the user has permission to run ad hoc commands. --- awx/api/serializers.py | 12 +++++++++++ awx/api/views.py | 2 +- awx/main/tests/ad_hoc.py | 43 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 861c05f35a..01b2476fa7 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -785,6 +785,18 @@ class InventorySerializer(BaseSerializerWithVariables): return ret +class InventoryDetailSerializer(InventorySerializer): + + class Meta: + fields = ('*', 'can_run_ad_hoc_commands') + + can_run_ad_hoc_commands = serializers.SerializerMethodField('get_can_run_ad_hoc_commands') + + def get_can_run_ad_hoc_commands(self, obj): + view = self.context.get('view', None) + return bool(obj and view and view.request and view.request.user and view.request.user.can_access(Inventory, 'run_ad_hoc_commands', obj)) + + class InventoryScriptSerializer(InventorySerializer): class Meta: diff --git a/awx/api/views.py b/awx/api/views.py index b842a77d93..8fa4fe52ca 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -887,7 +887,7 @@ class InventoryList(ListCreateAPIView): class InventoryDetail(RetrieveUpdateDestroyAPIView): model = Inventory - serializer_class = InventorySerializer + serializer_class = InventoryDetailSerializer def destroy(self, request, *args, **kwargs): with ignore_inventory_computed_fields(): diff --git a/awx/main/tests/ad_hoc.py b/awx/main/tests/ad_hoc.py index cfd5840f34..ad1231501f 100644 --- a/awx/main/tests/ad_hoc.py +++ b/awx/main/tests/ad_hoc.py @@ -899,6 +899,7 @@ class AdHocCommandApiTest(BaseAdHocCommandTest): # the ad hoc command(s) run against that inventory. Posting should # start a new ad hoc command and always set the inventory from the URL. url = reverse('api:inventory_ad_hoc_commands_list', args=(self.inventory.pk,)) + inventory_url = reverse('api:inventory_detail', args=(self.inventory.pk,)) with self.current_user('admin'): response = self.get(url, expect=200) self.assertEqual(response['count'], 1) @@ -909,6 +910,8 @@ class AdHocCommandApiTest(BaseAdHocCommandTest): self.put(url, {}, expect=405) self.patch(url, {}, expect=405) self.delete(url, expect=405) + response = self.get(inventory_url, expect=200) + self.assertTrue(response['can_run_ad_hoc_commands']) with self.current_user('normal'): response = self.get(url, expect=200) self.assertEqual(response['count'], 3) @@ -917,6 +920,8 @@ class AdHocCommandApiTest(BaseAdHocCommandTest): self.put(url, {}, expect=405) self.patch(url, {}, expect=405) self.delete(url, expect=405) + response = self.get(inventory_url, expect=200) + self.assertTrue(response['can_run_ad_hoc_commands']) with self.current_user('other'): self.get(url, expect=403) self.post(url, {}, expect=403) @@ -936,6 +941,44 @@ class AdHocCommandApiTest(BaseAdHocCommandTest): self.patch(url, {}, expect=401) self.delete(url, expect=401) + # Create a credential for the other user and explicitly give other + # user admin permission on the inventory (still not allowed to run ad + # hoc commands; can get the list but can't see any items). + other_cred = self.create_test_credential(user=self.other_django_user) + user_perm_url = reverse('api:user_permissions_list', args=(self.other_django_user.pk,)) + user_perm_data = { + 'name': 'Allow Other to Admin Inventory', + 'inventory': self.inventory.pk, + 'permission_type': 'admin', + } + with self.current_user('admin'): + response = self.post(user_perm_url, user_perm_data, expect=201) + user_perm_id = response['id'] + with self.current_user('other'): + response = self.get(url, expect=200) + self.assertEqual(response['count'], 0) + self.run_test_ad_hoc_command(url=url, inventory=None, credential=other_cred.pk, expect=403) + response = self.get(inventory_url, expect=200) + self.assertFalse(response['can_run_ad_hoc_commands']) + + # Update permission to allow other user to run ad hoc commands. Can + # only see his own ad hoc commands (because of credential permission). + user_perm_url = reverse('api:permission_detail', args=(user_perm_id,)) + user_perm_data.update({ + 'name': 'Allow Other to Admin Inventory and Run Ad Hoc Commands', + 'run_ad_hoc_commands': True, + }) + with self.current_user('admin'): + response = self.patch(user_perm_url, user_perm_data, expect=200) + with self.current_user('other'): + response = self.get(url, expect=200) + self.assertEqual(response['count'], 0) + self.run_test_ad_hoc_command(url=url, inventory=None, credential=other_cred.pk, expect=201) + response = self.get(url, expect=200) + self.assertEqual(response['count'], 1) + response = self.get(inventory_url, expect=200) + self.assertTrue(response['can_run_ad_hoc_commands']) + def test_host_ad_hoc_commands_list(self): with self.current_user('admin'): response = self.run_test_ad_hoc_command()