mirror of
https://github.com/ansible/awx.git
synced 2026-03-21 02:47:35 -02:30
Ability to add child groups to groups.
This commit is contained in:
@@ -421,6 +421,16 @@ class Group(CommonModelNameNotUnique):
|
|||||||
inventory = Inventory.objects.get(pk=data['inventory'])
|
inventory = Inventory.objects.get(pk=data['inventory'])
|
||||||
return Inventory._has_permission_types(user, inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
return Inventory._has_permission_types(user, inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_user_administrate(cls, user, obj):
|
||||||
|
# here this controls whether the user can attach subgroups
|
||||||
|
return Inventory._has_permission_types(user, obj.inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_user_read(cls, user, obj):
|
||||||
|
return Inventory.can_user_read(user, obj.inventory)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
import lib.urls
|
import lib.urls
|
||||||
return reverse(lib.urls.views_GroupsDetail, args=(self.pk,))
|
return reverse(lib.urls.views_GroupsDetail, args=(self.pk,))
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class GroupSerializer(BaseSerializer):
|
|||||||
related = serializers.SerializerMethodField('get_related')
|
related = serializers.SerializerMethodField('get_related')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Host
|
model = Group
|
||||||
fields = ('url', 'id', 'name', 'description', 'creation_date', 'inventory')
|
fields = ('url', 'id', 'name', 'description', 'creation_date', 'inventory')
|
||||||
|
|
||||||
def get_related(self, obj):
|
def get_related(self, obj):
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ class InventoryTest(BaseTest):
|
|||||||
new_group_c = dict(name='web4', inventory=inv.pk)
|
new_group_c = dict(name='web4', inventory=inv.pk)
|
||||||
new_group_d = dict(name='web5', inventory=inv.pk)
|
new_group_d = dict(name='web5', inventory=inv.pk)
|
||||||
new_group_e = dict(name='web6', inventory=inv.pk)
|
new_group_e = dict(name='web6', inventory=inv.pk)
|
||||||
|
groups = '/api/v1/groups/'
|
||||||
|
|
||||||
data0 = self.post(groups, data=invalid, expect=400, auth=self.get_super_credentials())
|
data0 = self.post(groups, data=invalid, expect=400, auth=self.get_super_credentials())
|
||||||
data0 = self.post(groups, data=new_group_a, expect=201, auth=self.get_super_credentials())
|
data0 = self.post(groups, data=new_group_a, expect=201, auth=self.get_super_credentials())
|
||||||
|
|
||||||
@@ -269,43 +271,81 @@ class InventoryTest(BaseTest):
|
|||||||
###################################################
|
###################################################
|
||||||
# VARIABLES -> GROUPS
|
# VARIABLES -> GROUPS
|
||||||
|
|
||||||
|
vars_a = dict(asdf=7777, dog='droopy', cat='battlecat', unstructured=dict(a=[1,1,1],b=dict(x=1,y=2)))
|
||||||
|
vars_b = dict(asdf=8888, dog='snoopy', cat='cheshire', unstructured=dict(a=[2,2,2],b=dict(x=3,y=4)))
|
||||||
|
vars_c = dict(asdf=9999, dog='pluto', cat='five', unstructured=dict(a=[3,3,3],b=dict(z=5)))
|
||||||
|
groups = Group.objects.all()
|
||||||
|
|
||||||
|
vdata1_url = "/api/v1/groups/%s/variable_data/" % (groups[0].pk)
|
||||||
|
vdata2_url = "/api/v1/groups/%s/variable_data/" % (groups[1].pk)
|
||||||
|
|
||||||
# a super user can associate variable objects with groups
|
# a super user can associate variable objects with groups
|
||||||
|
got = self.get(vdata1_url, expect=200, auth=self.get_super_credentials())
|
||||||
|
self.assertEquals(got, {})
|
||||||
|
put = self.put(vdata1_url, data=vars_a, expect=200, auth=self.get_super_credentials())
|
||||||
|
self.assertEquals(put, vars_a)
|
||||||
|
|
||||||
# an org admin can associate variable objects with groups
|
# an org admin can associate variable objects with groups
|
||||||
|
put = self.put(vdata1_url, data=vars_b, expect=200, auth=self.get_normal_credentials())
|
||||||
|
|
||||||
# a normal user cannot associate variable objects with groups
|
# a normal user cannot associate variable objects with groups
|
||||||
|
put = self.put(vdata1_url, data=vars_b, expect=403, auth=self.get_nobody_credentials())
|
||||||
|
|
||||||
# a normal user with inventory edit permissions can associate variable objects with groups
|
# a normal user with inventory edit permissions can associate variable objects with groups
|
||||||
|
put = self.put(vdata1_url, data=vars_c, expect=200, auth=self.get_normal_credentials())
|
||||||
|
self.assertEquals(put, vars_c)
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
# SUBGROUPS
|
# SUBGROUPS
|
||||||
|
|
||||||
|
groups = Group.objects.all()
|
||||||
|
|
||||||
|
# just some more groups for kicks
|
||||||
|
inv = Inventory.objects.get(pk=1)
|
||||||
|
Group.objects.create(name='group-X1', inventory=inv)
|
||||||
|
Group.objects.create(name='group-X2', inventory=inv)
|
||||||
|
Group.objects.create(name='group-X3', inventory=inv)
|
||||||
|
Group.objects.create(name='group-X4', inventory=inv)
|
||||||
|
Group.objects.create(name='group-X5', inventory=inv)
|
||||||
|
|
||||||
|
Permission.objects.create(
|
||||||
|
inventory = inv,
|
||||||
|
user = self.other_django_user,
|
||||||
|
permission_type = PERM_INVENTORY_WRITE
|
||||||
|
)
|
||||||
|
|
||||||
# a super user can set subgroups
|
# a super user can set subgroups
|
||||||
|
subgroups_url = '/api/v1/groups/1/children/'
|
||||||
|
child_url = '/api/v1/groups/2/'
|
||||||
|
subgroups_url2 = '/api/v1/groups/3/children/'
|
||||||
|
subgroups_url3 = '/api/v1/groups/4/children/'
|
||||||
|
subgroups_url4 = '/api/v1/groups/5/children/'
|
||||||
|
got = self.get(child_url, expect=200, auth=self.get_super_credentials())
|
||||||
|
self.post(subgroups_url, data=got, expect=204, auth=self.get_super_credentials())
|
||||||
|
kids = Group.objects.get(pk=1).children.all()
|
||||||
|
self.assertEqual(len(kids), 1)
|
||||||
|
checked = self.get(subgroups_url, expect=200, auth=self.get_super_credentials())
|
||||||
|
self.assertEquals(checked['count'], 1)
|
||||||
|
|
||||||
# an org admin can set subgroups
|
# an org admin can set subgroups
|
||||||
|
self.post(subgroups_url2, data=got, expect=204, auth=self.get_normal_credentials())
|
||||||
|
# double post causes conflict error
|
||||||
|
self.post(subgroups_url2, data=got, expect=409, auth=self.get_normal_credentials())
|
||||||
|
checked = self.get(subgroups_url2, expect=200, auth=self.get_normal_credentials())
|
||||||
|
|
||||||
# a normal user cannot set subgroups
|
# a normal user cannot set subgroups
|
||||||
|
self.post(subgroups_url3, data=got, expect=403, auth=self.get_nobody_credentials())
|
||||||
|
|
||||||
# a normal user with inventory edit permissions can associate subgroups
|
# a normal user with inventory edit permissions can associate subgroups
|
||||||
|
self.post(subgroups_url3, data=got, expect=204, auth=self.get_other_credentials())
|
||||||
# FIXME: go back and put in GET requests after all the post stuff
|
checked = self.get(subgroups_url3, expect=200, auth=self.get_normal_credentials())
|
||||||
|
self.assertEqual(checked['count'], 1)
|
||||||
#########################################################
|
|
||||||
# GROUP CHILDREN ACCESS
|
|
||||||
|
|
||||||
# a super user can see the children attached to a group
|
|
||||||
|
|
||||||
# a org admin can see the children attached to a group
|
|
||||||
|
|
||||||
# a user who is on a team who has read permissions on an inventory can see the children attached to a group
|
|
||||||
|
|
||||||
# a regular user cannot see children attached to a group
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# DISASSOCIATION TESTS
|
# DISASSOCIATION TESTS
|
||||||
# hosts from inventory
|
# hosts from inventory
|
||||||
# groups from inventory
|
# groups from inventory
|
||||||
# subgroups from groups
|
# children from groups
|
||||||
# others?
|
# others?
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|||||||
@@ -366,6 +366,38 @@ class GroupsList(BaseList):
|
|||||||
).distinct()
|
).distinct()
|
||||||
return admin_of | has_user_perms | has_team_perms
|
return admin_of | has_user_perms | has_team_perms
|
||||||
|
|
||||||
|
class GroupsChildrenList(BaseSubList):
|
||||||
|
|
||||||
|
model = Group
|
||||||
|
serializer_class = GroupSerializer
|
||||||
|
permission_classes = (CustomRbac,)
|
||||||
|
parent_model = Group
|
||||||
|
relationship = 'children'
|
||||||
|
postable = True
|
||||||
|
inject_primary_key_on_post_as = 'parent'
|
||||||
|
|
||||||
|
def _get_queryset(self):
|
||||||
|
|
||||||
|
# FIXME: this is the mostly the same as GroupsList, share code similar to how done with Host and Group objects.
|
||||||
|
|
||||||
|
parent = Group.objects.get(pk=self.kwargs['pk'])
|
||||||
|
|
||||||
|
# FIXME: verify read permissions on this object are still required at a higher level
|
||||||
|
|
||||||
|
base = parent.children
|
||||||
|
if self.request.user.is_superuser:
|
||||||
|
return base.all()
|
||||||
|
admin_of = base.filter(inventory__organization__admins__in = [ self.request.user ]).distinct()
|
||||||
|
has_user_perms = base.filter(
|
||||||
|
inventory__permissions__user__in = [ self.request.user ],
|
||||||
|
inventory__permissions__permission_type__in = PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
|
||||||
|
).distinct()
|
||||||
|
has_team_perms = base.filter(
|
||||||
|
inventory__permissions__team__in = self.request.user.teams.all(),
|
||||||
|
inventory__permissions__permission_type__in = PERMISSION_TYPES_ALLOWING_INVENTORY_READ,
|
||||||
|
).distinct()
|
||||||
|
return admin_of | has_user_perms | has_team_perms
|
||||||
|
|
||||||
class GroupsDetail(BaseDetail):
|
class GroupsDetail(BaseDetail):
|
||||||
|
|
||||||
model = Group
|
model = Group
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ views_InventoryGroupsList = views.InventoryGroupsList.as_view()
|
|||||||
views_GroupsList = views.GroupsList.as_view()
|
views_GroupsList = views.GroupsList.as_view()
|
||||||
views_GroupsDetail = views.GroupsDetail.as_view()
|
views_GroupsDetail = views.GroupsDetail.as_view()
|
||||||
views_GroupsVariableDetail = views.GroupsVariableDetail.as_view()
|
views_GroupsVariableDetail = views.GroupsVariableDetail.as_view()
|
||||||
|
views_GroupsChildrenList = views.GroupsChildrenList.as_view()
|
||||||
|
|
||||||
# host service
|
# host service
|
||||||
views_HostsList = views.HostsList.as_view()
|
views_HostsList = views.HostsList.as_view()
|
||||||
@@ -117,6 +118,7 @@ urlpatterns = patterns('',
|
|||||||
# group service
|
# group service
|
||||||
url(r'^api/v1/groups/$', views_GroupsList),
|
url(r'^api/v1/groups/$', views_GroupsList),
|
||||||
url(r'^api/v1/groups/(?P<pk>[0-9]+)/$', views_GroupsDetail),
|
url(r'^api/v1/groups/(?P<pk>[0-9]+)/$', views_GroupsDetail),
|
||||||
|
url(r'^api/v1/groups/(?P<pk>[0-9]+)/children/$', views_GroupsChildrenList),
|
||||||
|
|
||||||
# variable data
|
# variable data
|
||||||
url(r'^api/v1/hosts/(?P<pk>[0-9]+)/variable_data/$', views_HostsVariableDetail),
|
url(r'^api/v1/hosts/(?P<pk>[0-9]+)/variable_data/$', views_HostsVariableDetail),
|
||||||
|
|||||||
Reference in New Issue
Block a user