mirror of
https://github.com/ansible/awx.git
synced 2026-03-24 04:15:02 -02:30
Fixup attach logic for inventory hosts/groups on subcollections. Pass serializer errors through on conflict scenarios.
This commit is contained in:
@@ -111,7 +111,7 @@ class BaseSubList(BaseList):
|
|||||||
# attempt to deserialize the object
|
# attempt to deserialize the object
|
||||||
ser = self.__class__.serializer_class(data=request.DATA)
|
ser = self.__class__.serializer_class(data=request.DATA)
|
||||||
if not ser.is_valid():
|
if not ser.is_valid():
|
||||||
return Response(status=status.HTTP_400_BAD_REQUEST, data=python_json.dumps(dict(msg='invalid post data')))
|
return Response(status=status.HTTP_400_BAD_REQUEST, data=ser.errors)
|
||||||
|
|
||||||
# ask the usual access control settings
|
# ask the usual access control settings
|
||||||
if not self.__class__.model.can_user_add(request.user, ser.init_data):
|
if not self.__class__.model.can_user_add(request.user, ser.init_data):
|
||||||
@@ -126,7 +126,7 @@ class BaseSubList(BaseList):
|
|||||||
if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship):
|
if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship):
|
||||||
raise PermissionDenied()
|
raise PermissionDenied()
|
||||||
|
|
||||||
return Response(status=status.HTTP_201_CREATED, data=python_json.dumps(ser.data))
|
return Response(status=status.HTTP_201_CREATED, data=ser.data)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
|||||||
@@ -349,6 +349,14 @@ class Inventory(CommonModel):
|
|||||||
def can_user_administrate(cls, user, obj):
|
def can_user_administrate(cls, user, obj):
|
||||||
return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_ADMIN)
|
return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_ADMIN)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_user_attach(cls, user, obj, sub_obj, relationship_type):
|
||||||
|
''' whether you can add sub_obj to obj using the relationship type in a subobject view '''
|
||||||
|
if type(sub_obj) != User:
|
||||||
|
if not sub_obj.can_user_read(user, sub_obj):
|
||||||
|
return False
|
||||||
|
return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_user_read(cls, user, obj):
|
def can_user_read(cls, user, obj):
|
||||||
return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_READ)
|
return cls._has_permission_types(user, obj, PERMISSION_TYPES_ALLOWING_INVENTORY_READ)
|
||||||
@@ -381,7 +389,9 @@ class Host(CommonModelNameNotUnique):
|
|||||||
if not 'inventory' in data:
|
if not 'inventory' in data:
|
||||||
return False
|
return False
|
||||||
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)
|
rc = Inventory._has_permission_types(user, inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||||
|
return rc
|
||||||
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
import lib.urls
|
import lib.urls
|
||||||
|
|||||||
@@ -184,7 +184,6 @@ class InventoryTest(BaseTest):
|
|||||||
# HOSTS->inventories POST via subcollection
|
# HOSTS->inventories POST via subcollection
|
||||||
|
|
||||||
url = '/api/v1/inventories/1/hosts/'
|
url = '/api/v1/inventories/1/hosts/'
|
||||||
|
|
||||||
new_host_a = dict(name='web100.example.com')
|
new_host_a = dict(name='web100.example.com')
|
||||||
new_host_b = dict(name='web101.example.com')
|
new_host_b = dict(name='web101.example.com')
|
||||||
new_host_c = dict(name='web102.example.com')
|
new_host_c = dict(name='web102.example.com')
|
||||||
@@ -201,25 +200,38 @@ class InventoryTest(BaseTest):
|
|||||||
added_by_collection = self.post(url, data=new_host_c, expect=403, auth=self.get_nobody_credentials())
|
added_by_collection = self.post(url, data=new_host_c, expect=403, auth=self.get_nobody_credentials())
|
||||||
|
|
||||||
# a normal user with edit permission on the inventory can associate hosts with inventories
|
# a normal user with edit permission on the inventory can associate hosts with inventories
|
||||||
added_by_collection = self.post(url, data=new_host_d, expect=403, auth=self.get_other_credentials())
|
url5 = '/api/v1/inventories/5/hosts/'
|
||||||
|
added_by_collection = self.post(url5, data=new_host_d, expect=201, auth=self.get_other_credentials())
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# GROUPS->inventories POST via subcollection
|
# GROUPS->inventories POST via subcollection
|
||||||
|
|
||||||
|
url = '/api/v1/inventories/1/groups/'
|
||||||
|
new_group_a = dict(name='web100')
|
||||||
|
new_group_b = dict(name='web101')
|
||||||
|
new_group_c = dict(name='web102')
|
||||||
|
new_group_d = dict(name='web103')
|
||||||
|
new_group_e = dict(name='web104')
|
||||||
|
|
||||||
# a super user can associate groups with inventories
|
# a super user can associate groups with inventories
|
||||||
|
added_by_collection = self.post(url, data=new_group_a, expect=201, auth=self.get_super_credentials())
|
||||||
|
|
||||||
# an org admin can associate groups with inventories
|
# an org admin can associate groups with inventories
|
||||||
|
added_by_collection = self.post(url, data=new_group_b, expect=201, auth=self.get_normal_credentials())
|
||||||
|
|
||||||
# a normal user cannot associate groups with inventories
|
# a normal user cannot associate groups with inventories
|
||||||
|
added_by_collection = self.post(url, data=new_group_c, expect=403, auth=self.get_nobody_credentials())
|
||||||
|
|
||||||
# a normal user with edit permissions on the inventory can associate groups with inventories
|
# a normal user with edit permissions on the inventory can associate groups with inventories
|
||||||
|
url5 = '/api/v1/inventories/5/groups/'
|
||||||
|
added_by_collection = self.post(url5, data=new_group_d, expect=201, auth=self.get_other_credentials())
|
||||||
|
# make sure duplicates give 400s
|
||||||
|
added_by_collection2 = self.post(url5, data=new_group_d, expect=400, auth=self.get_other_credentials())
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# VARIABLES
|
# VARIABLES
|
||||||
|
|
||||||
# a super user can create variable objects
|
# an org admin can create variable objects (defers to inventory permissions)
|
||||||
|
|
||||||
# an org admin can create variable objects
|
|
||||||
|
|
||||||
# a normal user cannot create variable objects
|
# a normal user cannot create variable objects
|
||||||
|
|
||||||
@@ -258,50 +270,8 @@ class InventoryTest(BaseTest):
|
|||||||
|
|
||||||
# a normal user with inventory edit permissions can associate subgroups
|
# a normal user with inventory edit permissions can associate subgroups
|
||||||
|
|
||||||
######################################################
|
# FIXME: go back and put in GET requests after all the post stuff
|
||||||
# GROUP ACCESS
|
|
||||||
|
|
||||||
# a super user can get a group record
|
|
||||||
|
|
||||||
# an org admin can get a group record
|
|
||||||
|
|
||||||
# a user who is on a team who has read permissions on an inventory can get a group record
|
|
||||||
|
|
||||||
# a regular user cannot read any group records
|
|
||||||
|
|
||||||
########################################################
|
|
||||||
# HOST ACCESS
|
|
||||||
|
|
||||||
# a super user can get a host record
|
|
||||||
|
|
||||||
# an org admin can get a host record
|
|
||||||
|
|
||||||
# a user who is on a team who has read permissions on an inventory can get a host record
|
|
||||||
|
|
||||||
# a regular user cannot get a host record
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# GROUP VARIABLE ACCESS
|
|
||||||
|
|
||||||
# a super user can see the variables attached to a group
|
|
||||||
|
|
||||||
# a org admin can see the variables attached to a group
|
|
||||||
|
|
||||||
# a user who is on a team who has read permissions on an inventory can see the variables attached to a group
|
|
||||||
|
|
||||||
# a regular user cannot get a group variable record
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# HOST VARIABLE ACCESS
|
|
||||||
|
|
||||||
# a super user can see the variables attached to a host
|
|
||||||
|
|
||||||
# a org admin can see the variables attached to a host
|
|
||||||
|
|
||||||
# a user who is on a team who has read permissions on an inventory can see the variables attached to a host
|
|
||||||
|
|
||||||
# a regular user cannot see variables attached to a host
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# GROUP CHILDREN ACCESS
|
# GROUP CHILDREN ACCESS
|
||||||
|
|
||||||
@@ -314,86 +284,16 @@ class InventoryTest(BaseTest):
|
|||||||
# a regular user cannot see children attached to a group
|
# a regular user cannot see children attached to a group
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# VARIABLE RESOURCE ACCESS
|
# DISASSOCIATION TESTS
|
||||||
|
|
||||||
# a super user can see a variable record
|
|
||||||
|
|
||||||
# an org admin can see a variable record
|
|
||||||
|
|
||||||
# a user who is on a team who has read permissions on an inventory can see the variable record
|
|
||||||
|
|
||||||
# a regular user cannot see a variable record
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# SUPER USER DISASSOCIATION
|
|
||||||
|
|
||||||
# a super user can disassociate...
|
|
||||||
|
|
||||||
# hosts from inventory
|
# hosts from inventory
|
||||||
|
|
||||||
# groups from inventory
|
# groups from inventory
|
||||||
|
|
||||||
# subgroups from groups
|
# subgroups from groups
|
||||||
|
# others?
|
||||||
# the inventory task code returns valid inventory JSON.
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# ORG ADMIN DISASSOCIATION
|
|
||||||
|
|
||||||
# an org admin user can disassociate...
|
|
||||||
|
|
||||||
# hosts from inventory
|
|
||||||
|
|
||||||
# groups from inventory
|
|
||||||
|
|
||||||
# subgroups from groups
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# USER DISASSOCIATION
|
|
||||||
|
|
||||||
# a user with inventory edit permission disassociate...
|
|
||||||
|
|
||||||
# hosts from inventory
|
|
||||||
|
|
||||||
# groups from inventory
|
|
||||||
|
|
||||||
# subgroups from groups
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# USER DISASSOCIATION (2)
|
|
||||||
|
|
||||||
# a regular user cannot disassociate....
|
|
||||||
|
|
||||||
# hosts from inventory
|
|
||||||
|
|
||||||
# groups from inventory
|
|
||||||
|
|
||||||
# subgroups from inventory
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# TAGS
|
# TAGS
|
||||||
|
|
||||||
# the following objects can be tagged
|
# the following objects can be tagged and the tags can be read
|
||||||
|
|
||||||
# inventory
|
|
||||||
|
|
||||||
# host records
|
|
||||||
|
|
||||||
# group records
|
|
||||||
|
|
||||||
# variable records
|
|
||||||
|
|
||||||
# the following objects can have their tags listed
|
|
||||||
|
|
||||||
# inventory
|
|
||||||
|
|
||||||
# host records
|
|
||||||
|
|
||||||
# group records
|
|
||||||
|
|
||||||
# variable records
|
|
||||||
|
|
||||||
# the following tags can be removed
|
|
||||||
|
|
||||||
# inventory
|
# inventory
|
||||||
|
|
||||||
|
|||||||
@@ -372,4 +372,21 @@ class GroupsDetail(BaseDetail):
|
|||||||
serializer_class = GroupSerializer
|
serializer_class = GroupSerializer
|
||||||
permission_classes = (CustomRbac,)
|
permission_classes = (CustomRbac,)
|
||||||
|
|
||||||
|
class InventoryGroupsList(BaseSubList):
|
||||||
|
|
||||||
|
model = Group
|
||||||
|
serializer_class = GroupSerializer
|
||||||
|
permission_classes = (CustomRbac,)
|
||||||
|
# to allow the sub-aspect listing
|
||||||
|
parent_model = Inventory
|
||||||
|
relationship = 'groups'
|
||||||
|
# to allow posting to this resource to create resources
|
||||||
|
postable = True
|
||||||
|
# FIXME: go back and add these to other SubLists
|
||||||
|
inject_primary_key_on_post_as = 'inventory'
|
||||||
|
|
||||||
|
def _get_queryset(self):
|
||||||
|
# FIXME: more DRY methods like this
|
||||||
|
return Inventory._filter_queryset(Inventory.objects.get(pk=self.kwargs['pk']).groups)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ views_ProjectsDetail = views.OrganizationsDetail.as_view()
|
|||||||
views_InventoryList = views.InventoryList.as_view()
|
views_InventoryList = views.InventoryList.as_view()
|
||||||
views_InventoryDetail = views.InventoryDetail.as_view()
|
views_InventoryDetail = views.InventoryDetail.as_view()
|
||||||
views_InventoryHostsList = views.InventoryHostsList.as_view()
|
views_InventoryHostsList = views.InventoryHostsList.as_view()
|
||||||
|
views_InventoryGroupsList = views.InventoryGroupsList.as_view()
|
||||||
|
|
||||||
# group service
|
# group service
|
||||||
views_GroupsList = views.GroupsList.as_view()
|
views_GroupsList = views.GroupsList.as_view()
|
||||||
@@ -97,6 +98,7 @@ urlpatterns = patterns('',
|
|||||||
url(r'^api/v1/inventories/$', views_InventoryList),
|
url(r'^api/v1/inventories/$', views_InventoryList),
|
||||||
url(r'^api/v1/inventories/(?P<pk>[0-9]+)/$', views_InventoryDetail),
|
url(r'^api/v1/inventories/(?P<pk>[0-9]+)/$', views_InventoryDetail),
|
||||||
url(r'^api/v1/inventories/(?P<pk>[0-9]+)/hosts/$', views_InventoryHostsList),
|
url(r'^api/v1/inventories/(?P<pk>[0-9]+)/hosts/$', views_InventoryHostsList),
|
||||||
|
url(r'^api/v1/inventories/(?P<pk>[0-9]+)/groups/$', views_InventoryGroupsList),
|
||||||
|
|
||||||
# host service
|
# host service
|
||||||
url(r'^api/v1/hosts/$', views_HostsList),
|
url(r'^api/v1/hosts/$', views_HostsList),
|
||||||
|
|||||||
Reference in New Issue
Block a user