1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Extend bulk import/edit/delete view tests to support object-level permissions

This commit is contained in:
Jeremy Stretch
2020-05-22 16:04:43 -04:00
parent 5273b9d0ee
commit 77a49fa40e

View File

@ -232,12 +232,11 @@ class ViewTestCases:
@override_settings(EXEMPT_VIEW_PERMISSIONS=[]) @override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_create_object_with_object_permission(self): def test_create_object_with_object_permission(self):
initial_count = self.model.objects.count() initial_count = self.model.objects.count()
next_pk = self.model.objects.order_by('pk').last().pk + 1
# Assign object-level permission # Assign object-level permission
obj_perm = ObjectPermission( obj_perm = ObjectPermission(
model=ContentType.objects.get_for_model(self.model), model=ContentType.objects.get_for_model(self.model),
attrs={'pk__gt': next_pk}, attrs={'pk__gt': 0}, # Dummy permission to allow all
can_add=True can_add=True
) )
obj_perm.save() obj_perm.save()
@ -255,6 +254,10 @@ class ViewTestCases:
self.assertEqual(initial_count + 1, self.model.objects.count()) self.assertEqual(initial_count + 1, self.model.objects.count())
self.assertInstanceEqual(self.model.objects.order_by('pk').last(), self.form_data) self.assertInstanceEqual(self.model.objects.order_by('pk').last(), self.form_data)
# Nullify ObjectPermission to disallow new object creation
obj_perm.attrs = {'pk': 0}
obj_perm.save()
# Try to create a non-permitted object # Try to create a non-permitted object
initial_count = self.model.objects.count() initial_count = self.model.objects.count()
request = { request = {
@ -470,7 +473,6 @@ class ViewTestCases:
request = { request = {
'path': self._get_url('add'), 'path': self._get_url('add'),
'data': post_data(self.bulk_create_data), 'data': post_data(self.bulk_create_data),
'follow': False, # Do not follow 302 redirects
} }
# Attempt to make the request without required permissions # Attempt to make the request without required permissions
@ -494,35 +496,63 @@ class ViewTestCases:
""" """
csv_data = () csv_data = ()
def _get_csv_data(self):
return '\n'.join(self.csv_data)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[]) @override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_import_objects(self): def test_bulk_import_objects_without_permission(self):
data = {
'csv': self._get_csv_data(),
}
# Test GET without permission # Test GET without permission
with disable_warnings('django.request'): with disable_warnings('django.request'):
self.assertHttpStatus(self.client.get(self._get_url('import')), 403) self.assertHttpStatus(self.client.get(self._get_url('import')), 403)
# Test GET with permission # Try POST without permission
self.add_permissions( response = self.client.post(self._get_url('import'), data)
'{}.view_{}'.format(self.model._meta.app_label, self.model._meta.model_name), with disable_warnings('django.request'):
'{}.add_{}'.format(self.model._meta.app_label, self.model._meta.model_name) self.assertHttpStatus(response, 403)
)
response = self.client.get(self._get_url('import')) @override_settings(EXEMPT_VIEW_PERMISSIONS=[])
self.assertHttpStatus(response, 200) def test_bulk_import_objects_with_model_permission(self):
initial_count = self.model.objects.count()
data = {
'csv': self._get_csv_data(),
}
# Assign model-level permission
self.add_permissions(get_permission_for_model(self.model, 'add'))
# Try GET with model-level permission
self.assertHttpStatus(self.client.get(self._get_url('import')), 200)
# Test POST with permission # Test POST with permission
initial_count = self.model.objects.count() self.assertHttpStatus(self.client.post(self._get_url('import'), data), 200)
request = {
'path': self._get_url('import'),
'data': {
'csv': '\n'.join(self.csv_data)
}
}
response = self.client.post(**request)
self.assertHttpStatus(response, 200)
# Validate import of new objects
self.assertEqual(self.model.objects.count(), initial_count + len(self.csv_data) - 1) self.assertEqual(self.model.objects.count(), initial_count + len(self.csv_data) - 1)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_import_objects_with_object_permission(self):
initial_count = self.model.objects.count()
data = {
'csv': self._get_csv_data(),
}
# Assign object-level permission
obj_perm = ObjectPermission(
model=ContentType.objects.get_for_model(self.model),
attrs={'pk__gt': 0}, # Dummy permission to allow all
can_add=True
)
obj_perm.save()
obj_perm.users.add(self.user)
# Test import with object-level permission
self.assertHttpStatus(self.client.post(self._get_url('import'), data), 200)
self.assertEqual(self.model.objects.count(), initial_count + len(self.csv_data) - 1)
# TODO: Test importing non-permitted objects
class BulkEditObjectsViewTestCase(ModelViewTestCase): class BulkEditObjectsViewTestCase(ModelViewTestCase):
""" """
Edit multiple instances. Edit multiple instances.
@ -530,68 +560,128 @@ class ViewTestCases:
bulk_edit_data = {} bulk_edit_data = {}
@override_settings(EXEMPT_VIEW_PERMISSIONS=[]) @override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_edit_objects(self): def test_bulk_edit_objects_without_permission(self):
# Bulk edit the first three objects only
pk_list = self.model.objects.values_list('pk', flat=True)[:3] pk_list = self.model.objects.values_list('pk', flat=True)[:3]
data = {
'pk': pk_list,
'_apply': True, # Form button
}
request = { # Test GET without permission
'path': self._get_url('bulk_edit'), with disable_warnings('django.request'):
'data': { self.assertHttpStatus(self.client.get(self._get_url('bulk_edit')), 403)
'pk': pk_list,
'_apply': True, # Form button # Try POST without permission
}, with disable_warnings('django.request'):
'follow': False, # Do not follow 302 redirects self.assertHttpStatus(self.client.post(self._get_url('bulk_edit'), data), 403)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_edit_objects_with_model_permission(self):
pk_list = self.model.objects.values_list('pk', flat=True)[:3]
data = {
'pk': pk_list,
'_apply': True, # Form button
} }
# Append the form data to the request # Append the form data to the request
request['data'].update(post_data(self.bulk_edit_data)) data.update(post_data(self.bulk_edit_data))
# Attempt to make the request without required permissions # Assign model-level permission
with disable_warnings('django.request'): self.add_permissions(get_permission_for_model(self.model, 'change'))
self.assertHttpStatus(self.client.post(**request), 403)
# Assign the required permission and submit again
self.add_permissions(
'{}.change_{}'.format(self.model._meta.app_label, self.model._meta.model_name)
)
response = self.client.post(**request)
self.assertHttpStatus(response, 302)
# Try POST with model-level permission
self.assertHttpStatus(self.client.post(self._get_url('bulk_edit'), data), 302)
for i, instance in enumerate(self.model.objects.filter(pk__in=pk_list)): for i, instance in enumerate(self.model.objects.filter(pk__in=pk_list)):
self.assertInstanceEqual(instance, self.bulk_edit_data) self.assertInstanceEqual(instance, self.bulk_edit_data)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_edit_objects_with_object_permission(self):
pk_list = self.model.objects.values_list('pk', flat=True)[:3]
data = {
'pk': pk_list,
'_apply': True, # Form button
}
# Append the form data to the request
data.update(post_data(self.bulk_edit_data))
# Assign object-level permission
obj_perm = ObjectPermission(
model=ContentType.objects.get_for_model(self.model),
attrs={'pk__in': list(pk_list)},
can_change=True
)
obj_perm.save()
obj_perm.users.add(self.user)
# Try POST with model-level permission
self.assertHttpStatus(self.client.post(self._get_url('bulk_edit'), data), 302)
for i, instance in enumerate(self.model.objects.filter(pk__in=pk_list)):
self.assertInstanceEqual(instance, self.bulk_edit_data)
# TODO: Test editing non-permitted objects
class BulkDeleteObjectsViewTestCase(ModelViewTestCase): class BulkDeleteObjectsViewTestCase(ModelViewTestCase):
""" """
Delete multiple instances. Delete multiple instances.
""" """
@override_settings(EXEMPT_VIEW_PERMISSIONS=[]) @override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_delete_objects(self): def test_bulk_delete_objects_without_permission(self):
pk_list = self.model.objects.values_list('pk', flat=True) pk_list = self.model.objects.values_list('pk', flat=True)[:3]
data = {
request = { 'pk': pk_list,
'path': self._get_url('bulk_delete'), 'confirm': True,
'data': { '_confirm': True, # Form button
'pk': pk_list,
'confirm': True,
'_confirm': True, # Form button
},
'follow': False, # Do not follow 302 redirects
} }
# Attempt to make the request without required permissions # Test GET without permission
with disable_warnings('django.request'): with disable_warnings('django.request'):
self.assertHttpStatus(self.client.post(**request), 403) self.assertHttpStatus(self.client.get(self._get_url('bulk_delete')), 403)
# Assign the required permission and submit again # Try POST without permission
self.add_permissions( with disable_warnings('django.request'):
'{}.delete_{}'.format(self.model._meta.app_label, self.model._meta.model_name) self.assertHttpStatus(self.client.post(self._get_url('bulk_delete'), data), 403)
)
response = self.client.post(**request)
self.assertHttpStatus(response, 302)
# Check that all objects were deleted @override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_delete_objects_with_model_permission(self):
pk_list = self.model.objects.values_list('pk', flat=True)
data = {
'pk': pk_list,
'confirm': True,
'_confirm': True, # Form button
}
# Assign model-level permission
self.add_permissions(get_permission_for_model(self.model, 'delete'))
# Try POST with model-level permission
self.assertHttpStatus(self.client.post(self._get_url('bulk_delete'), data), 302)
self.assertEqual(self.model.objects.count(), 0) self.assertEqual(self.model.objects.count(), 0)
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
def test_bulk_delete_objects_with_object_permission(self):
pk_list = self.model.objects.values_list('pk', flat=True)
data = {
'pk': pk_list,
'confirm': True,
'_confirm': True, # Form button
}
# Assign object-level permission
obj_perm = ObjectPermission(
model=ContentType.objects.get_for_model(self.model),
attrs={'pk__in': list(pk_list)},
can_delete=True
)
obj_perm.save()
obj_perm.users.add(self.user)
# Try POST with object-level permission
self.assertHttpStatus(self.client.post(self._get_url('bulk_delete'), data), 302)
self.assertEqual(self.model.objects.count(), 0)
# TODO: Test deleting non-permitted objects
class PrimaryObjectViewTestCase( class PrimaryObjectViewTestCase(
GetObjectViewTestCase, GetObjectViewTestCase,
CreateObjectViewTestCase, CreateObjectViewTestCase,