Beispiel #1
0
        def test_bulk_create_objects(self):
            """
            POST a set of objects in a single request.
            """
            # Add object-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['add'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            initial_count = self._get_queryset().count()
            response = self.client.post(self._get_list_url(),
                                        self.create_data,
                                        format='json',
                                        **self.header)
            self.assertHttpStatus(response, status.HTTP_201_CREATED)
            self.assertEqual(len(response.data), len(self.create_data))
            self.assertEqual(self._get_queryset().count(),
                             initial_count + len(self.create_data))
            for i, obj in enumerate(response.data):
                for field in self.create_data[i]:
                    if field not in self.validation_excluded_fields:
                        self.assertIn(
                            field, obj,
                            f"Bulk create field '{field}' missing from object {i} in response"
                        )
            for i, obj in enumerate(response.data):
                self.assertInstanceEqual(
                    self._get_queryset().get(pk=obj['id']),
                    self.create_data[i],
                    exclude=self.validation_excluded_fields,
                    api=True)
Beispiel #2
0
        def test_edit_object_with_constrained_permission(self):
            instance1, instance2 = self._get_queryset().all()[:2]

            # Assign constrained permission
            obj_perm = ObjectPermission(constraints={'pk': instance1.pk},
                                        actions=['change'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with a permitted object
            self.assertHttpStatus(
                self.client.get(self._get_url('edit', instance1)), 200)

            # Try GET with a non-permitted object
            self.assertHttpStatus(
                self.client.get(self._get_url('edit', instance2)), 404)

            # Try to edit a permitted object
            request = {
                'path': self._get_url('edit', instance1),
                'data': post_data(self.form_data),
            }
            self.assertHttpStatus(self.client.post(**request), 302)
            self.assertInstanceEqual(self._get_queryset().get(pk=instance1.pk),
                                     self.form_data)

            # Try to edit a non-permitted object
            request = {
                'path': self._get_url('edit', instance2),
                'data': post_data(self.form_data),
            }
            self.assertHttpStatus(self.client.post(**request), 404)
Beispiel #3
0
        def test_bulk_edit_objects_with_permission(self):
            pk_list = list(self._get_queryset().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 model-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['change'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try POST with model-level permission
            self.assertHttpStatus(
                self.client.post(self._get_url('bulk_edit'), data), 302)
            for i, instance in enumerate(
                    self._get_queryset().filter(pk__in=pk_list)):
                self.assertInstanceEqual(instance, self.bulk_edit_data)
Beispiel #4
0
        def test_delete_object(self):
            """
            DELETE a single object identified by its numeric ID.
            """
            instance = self._get_queryset().first()
            url = self._get_detail_url(instance)

            # Add object-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['delete'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            response = self.client.delete(url, **self.header)
            self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
            self.assertFalse(
                self._get_queryset().filter(pk=instance.pk).exists())

            # Verify ObjectChange creation
            if hasattr(self.model, 'to_objectchange'):
                objectchanges = ObjectChange.objects.filter(
                    changed_object_type=ContentType.objects.get_for_model(
                        instance),
                    changed_object_id=instance.pk)
                self.assertEqual(len(objectchanges), 1)
                self.assertEqual(objectchanges[0].action,
                                 ObjectChangeActionChoices.ACTION_DELETE)
Beispiel #5
0
        def test_bulk_delete_objects(self):
            """
            DELETE a set of objects in a single request.
            """
            # Add object-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['delete'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Target the three most recently created objects to avoid triggering recursive deletions
            # (e.g. with MPTT objects)
            id_list = self._get_queryset().order_by('-id').values_list(
                'id', flat=True)[:3]
            self.assertEqual(
                len(id_list), 3,
                "Insufficient number of objects to test bulk deletion")
            data = [{"id": id} for id in id_list]

            initial_count = self._get_queryset().count()
            response = self.client.delete(self._get_list_url(),
                                          data,
                                          format='json',
                                          **self.header)
            self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
            self.assertEqual(self._get_queryset().count(), initial_count - 3)
Beispiel #6
0
        def test_create_multiple_objects_with_permission(self):
            initial_count = self._get_queryset().count()
            request = {
                'path': self._get_url('add'),
                'data': post_data(self.bulk_create_data),
            }

            # Assign non-constrained permission
            obj_perm = ObjectPermission(
                name='Test permission',
                actions=['add'],
            )
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Bulk create objects
            response = self.client.post(**request)
            self.assertHttpStatus(response, 302)
            self.assertEqual(initial_count + self.bulk_create_count,
                             self._get_queryset().count())
            for instance in self._get_queryset().order_by(
                    '-pk')[:self.bulk_create_count]:
                self.assertInstanceEqual(instance, self.bulk_create_data)
Beispiel #7
0
        def test_delete_object_with_permission(self):
            instance = self._get_queryset().first()

            # Assign model-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['delete'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with model-level permission
            self.assertHttpStatus(
                self.client.get(self._get_url('delete', instance)), 200)

            # Try POST with model-level permission
            request = {
                'path': self._get_url('delete', instance),
                'data': post_data({'confirm': True}),
            }
            self.assertHttpStatus(self.client.post(**request), 302)
            with self.assertRaises(ObjectDoesNotExist):
                self._get_queryset().get(pk=instance.pk)

            # Verify ObjectChange creation
            objectchanges = ObjectChange.objects.filter(
                changed_object_type=ContentType.objects.get_for_model(
                    instance),
                changed_object_id=instance.pk)
            self.assertEqual(len(objectchanges), 1)
            self.assertEqual(objectchanges[0].action,
                             ObjectChangeActionChoices.ACTION_DELETE)
Beispiel #8
0
        def test_create_object(self):
            """
            POST a single object with permission.
            """
            # Add object-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['add'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            initial_count = self._get_queryset().count()
            response = self.client.post(self._get_list_url(),
                                        self.create_data[0],
                                        format='json',
                                        **self.header)
            self.assertHttpStatus(response, status.HTTP_201_CREATED)
            self.assertEqual(self._get_queryset().count(), initial_count + 1)
            instance = self._get_queryset().get(pk=response.data['id'])
            self.assertInstanceEqual(instance,
                                     self.create_data[0],
                                     exclude=self.validation_excluded_fields,
                                     api=True)

            # Verify ObjectChange creation
            if hasattr(self.model, 'to_objectchange'):
                objectchanges = ObjectChange.objects.filter(
                    changed_object_type=ContentType.objects.get_for_model(
                        instance),
                    changed_object_id=instance.pk)
                self.assertEqual(len(objectchanges), 1)
                self.assertEqual(objectchanges[0].action,
                                 ObjectChangeActionChoices.ACTION_CREATE)
Beispiel #9
0
        def test_create_object_with_permission(self):
            initial_count = self._get_queryset().count()

            # Assign unconstrained permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['add'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with model-level permission
            self.assertHttpStatus(self.client.get(self._get_url('add')), 200)

            # Try POST with model-level permission
            request = {
                'path': self._get_url('add'),
                'data': post_data(self.form_data),
            }
            self.assertHttpStatus(self.client.post(**request), 302)
            self.assertEqual(initial_count + 1, self._get_queryset().count())
            instance = self._get_queryset().order_by('pk').last()
            self.assertInstanceEqual(instance, self.form_data)

            # Verify ObjectChange creation
            objectchanges = ObjectChange.objects.filter(
                changed_object_type=ContentType.objects.get_for_model(
                    instance),
                changed_object_id=instance.pk)
            self.assertEqual(len(objectchanges), 1)
            self.assertEqual(objectchanges[0].action,
                             ObjectChangeActionChoices.ACTION_CREATE)
Beispiel #10
0
        def test_edit_object_with_permission(self):
            instance = self._get_queryset().first()

            # Assign model-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['change'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with model-level permission
            self.assertHttpStatus(
                self.client.get(self._get_url('edit', instance)), 200)

            # Try POST with model-level permission
            request = {
                'path': self._get_url('edit', instance),
                'data': post_data(self.form_data),
            }
            self.assertHttpStatus(self.client.post(**request), 302)
            self.assertInstanceEqual(self._get_queryset().get(pk=instance.pk),
                                     self.form_data)

            # Verify ObjectChange creation
            objectchanges = ObjectChange.objects.filter(
                changed_object_type=ContentType.objects.get_for_model(
                    instance),
                changed_object_id=instance.pk)
            self.assertEqual(len(objectchanges), 1)
            self.assertEqual(objectchanges[0].action,
                             ObjectChangeActionChoices.ACTION_UPDATE)
Beispiel #11
0
        def test_graphql_list_objects(self):
            url = reverse('graphql')
            field_name = f'{self._get_graphql_base_name()}_list'
            query = self._build_query(field_name)

            # Non-authenticated requests should fail
            with disable_warnings('django.request'):
                self.assertHttpStatus(
                    self.client.post(url, data={'query': query}),
                    status.HTTP_403_FORBIDDEN)

            # Add object-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['view'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            response = self.client.post(url,
                                        data={'query': query},
                                        **self.header)
            self.assertHttpStatus(response, status.HTTP_200_OK)
            data = json.loads(response.content)
            self.assertNotIn('errors', data)
            self.assertGreater(len(data['data'][field_name]), 0)
Beispiel #12
0
        def test_get_object(self):
            """
            GET a single object as an authenticated user with permission to view the object.
            """
            self.assertGreaterEqual(self._get_queryset().count(), 2,
                                    f"Test requires the creation of at least two {self.model} instances")
            instance1, instance2 = self._get_queryset()[:2]

            # Add object-level permission
            obj_perm = ObjectPermission(
                name='Test permission',
                constraints={'pk': instance1.pk},
                actions=['view']
            )
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(ContentType.objects.get_for_model(self.model))

            # Try GET to permitted object
            url = self._get_detail_url(instance1)
            self.assertHttpStatus(self.client.get(url, **self.header), status.HTTP_200_OK)

            # Try GET to non-permitted object
            url = self._get_detail_url(instance2)
            self.assertHttpStatus(self.client.get(url, **self.header), status.HTTP_404_NOT_FOUND)
Beispiel #13
0
        def test_bulk_update_objects(self):
            """
            PATCH a set of objects in a single request.
            """
            if self.bulk_update_data is None:
                self.skipTest("Bulk update data not set")

            # Add object-level permission
            obj_perm = ObjectPermission(
                name='Test permission',
                actions=['change']
            )
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(ContentType.objects.get_for_model(self.model))

            id_list = self._get_queryset().values_list('id', flat=True)[:3]
            self.assertEqual(len(id_list), 3, "Insufficient number of objects to test bulk update")
            data = [
                {'id': id, **self.bulk_update_data} for id in id_list
            ]

            response = self.client.patch(self._get_list_url(), data, format='json', **self.header)
            self.assertHttpStatus(response, status.HTTP_200_OK)
            for i, obj in enumerate(response.data):
                for field in self.bulk_update_data:
                    self.assertIn(field, obj, f"Bulk update field '{field}' missing from object {i} in response")
            for instance in self._get_queryset().filter(pk__in=id_list):
                self.assertInstanceEqual(instance, self.bulk_update_data, api=True)
Beispiel #14
0
        def test_update_object(self):
            """
            PATCH a single object identified by its numeric ID.
            """
            instance = self._get_queryset().first()
            url = self._get_detail_url(instance)
            update_data = self.update_data or getattr(self, 'create_data')[0]

            # Add object-level permission
            obj_perm = ObjectPermission(
                name='Test permission',
                actions=['change']
            )
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(ContentType.objects.get_for_model(self.model))

            response = self.client.patch(url, update_data, format='json', **self.header)
            self.assertHttpStatus(response, status.HTTP_200_OK)
            instance.refresh_from_db()
            self.assertInstanceEqual(
                instance,
                update_data,
                exclude=self.validation_excluded_fields,
                api=True
            )
Beispiel #15
0
    def setUpTestData(cls):

        groups = (
            Group(name='Group 1'),
            Group(name='Group 2'),
            Group(name='Group 3'),
        )
        Group.objects.bulk_create(groups)

        users = (
            User(username='******', is_active=True),
            User(username='******', is_active=True),
            User(username='******', is_active=True),
        )
        User.objects.bulk_create(users)

        object_type = ContentType.objects.get(app_label='dcim', model='device')

        for i in range(0, 3):
            objectpermission = ObjectPermission(
                name=f'Permission {i+1}',
                actions=['view', 'add', 'change', 'delete'],
                constraints={'name': f'TEST{i+1}'})
            objectpermission.save()
            objectpermission.object_types.add(object_type)
            objectpermission.groups.add(groups[i])
            objectpermission.users.add(users[i])

        cls.create_data = [
            {
                'name': 'Permission 4',
                'object_types': ['dcim.site'],
                'groups': [groups[0].pk],
                'users': [users[0].pk],
                'actions': ['view', 'add', 'change', 'delete'],
                'constraints': {
                    'name': 'TEST4'
                },
            },
            {
                'name': 'Permission 5',
                'object_types': ['dcim.site'],
                'groups': [groups[1].pk],
                'users': [users[1].pk],
                'actions': ['view', 'add', 'change', 'delete'],
                'constraints': {
                    'name': 'TEST5'
                },
            },
            {
                'name': 'Permission 6',
                'object_types': ['dcim.site'],
                'groups': [groups[2].pk],
                'users': [users[2].pk],
                'actions': ['view', 'add', 'change', 'delete'],
                'constraints': {
                    'name': 'TEST6'
                },
            },
        ]
Beispiel #16
0
 def add_permissions(self, *names):
     """
     Assign a set of permissions to the test user. Accepts permission names in the form <app>.<action>_<model>.
     """
     for name in names:
         ct, action = resolve_permission_ct(name)
         obj_perm = ObjectPermission(name=name, actions=[action])
         obj_perm.save()
         obj_perm.users.add(self.user)
         obj_perm.object_types.add(ct)
Beispiel #17
0
        def test_list_objects_with_permission(self):

            # Add model-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        actions=['view'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with model-level permission
            self.assertHttpStatus(self.client.get(self._get_url('list')), 200)
Beispiel #18
0
        def test_get_object_with_permission(self):
            instance = self._get_queryset().first()

            # Add model-level permission
            obj_perm = ObjectPermission(actions=['view'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with model-level permission
            self.assertHttpStatus(self.client.get(instance.get_absolute_url()),
                                  200)
Beispiel #19
0
    def configure_user(self, request, user):
        logger = logging.getLogger('netbox.authentication.RemoteUserBackend')
        if not settings.REMOTE_AUTH_GROUP_SYNC_ENABLED:
            # Assign default groups to the user
            group_list = []
            for name in settings.REMOTE_AUTH_DEFAULT_GROUPS:
                try:
                    group_list.append(Group.objects.get(name=name))
                except Group.DoesNotExist:
                    logging.error(
                        f"Could not assign group {name} to remotely-authenticated user {user}: Group not found"
                    )
            if group_list:
                user.groups.add(*group_list)
                logger.debug(
                    f"Assigned groups to remotely-authenticated user {user}: {group_list}"
                )

            # Assign default object permissions to the user
            permissions_list = []
            for permission_name, constraints in settings.REMOTE_AUTH_DEFAULT_PERMISSIONS.items(
            ):
                try:
                    object_type, action = resolve_permission_ct(
                        permission_name)
                    # TODO: Merge multiple actions into a single ObjectPermission per content type
                    obj_perm = ObjectPermission(actions=[action],
                                                constraints=constraints)
                    obj_perm.save()
                    obj_perm.users.add(user)
                    obj_perm.object_types.add(object_type)
                    permissions_list.append(permission_name)
                except ValueError:
                    logging.error(
                        f"Invalid permission name: '{permission_name}'. Permissions must be in the form "
                        "<app>.<action>_<model>. (Example: dcim.add_site)")
            if permissions_list:
                logger.debug(
                    f"Assigned permissions to remotely-authenticated user {user}: {permissions_list}"
                )
        else:
            logger.debug(
                f"Skipped initial assignment of permissions and groups to remotely-authenticated user {user} as Group sync is enabled"
            )

        return user
Beispiel #20
0
        def test_bulk_import_objects_with_constrained_permission(self):
            initial_count = self._get_queryset().count()
            data = {
                'csv': self._get_csv_data(),
            }

            # Assign constrained permission
            obj_perm = ObjectPermission(
                name='Test permission',
                constraints={'pk': 0},  # Dummy permission to deny all
                actions=['add'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Attempt to import non-permitted objects
            self.assertHttpStatus(
                self.client.post(self._get_url('import'), data), 200)
            self.assertEqual(self._get_queryset().count(), initial_count)

            # Update permission constraints
            obj_perm.constraints = {
                'pk__gt': 0
            }  # Dummy permission to allow all
            obj_perm.save()

            # Import permitted objects
            self.assertHttpStatus(
                self.client.post(self._get_url('import'), data), 200)
            self.assertEqual(self._get_queryset().count(),
                             initial_count + len(self.csv_data) - 1)
Beispiel #21
0
        def test_create_multiple_objects_with_constrained_permission(self):
            initial_count = self._get_queryset().count()
            request = {
                'path': self._get_url('add'),
                'data': post_data(self.bulk_create_data),
            }

            # Assign constrained permission
            obj_perm = ObjectPermission(
                name='Test permission',
                actions=['add'],
                constraints={'pk': 0}  # Dummy constraint to deny all
            )
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Attempt to make the request with unmet constraints
            self.assertHttpStatus(self.client.post(**request), 200)
            self.assertEqual(self._get_queryset().count(), initial_count)

            # Update the ObjectPermission to allow creation
            obj_perm.constraints = {
                'pk__gt': 0
            }  # Dummy constraint to allow all
            obj_perm.save()

            response = self.client.post(**request)
            self.assertHttpStatus(response, 302)
            self.assertEqual(initial_count + self.bulk_create_count,
                             self._get_queryset().count())
            for instance in self._get_queryset().order_by(
                    '-pk')[:self.bulk_create_count]:
                self.assertInstanceEqual(instance, self.bulk_create_data)
Beispiel #22
0
        def test_bulk_rename_objects_with_constrained_permission(self):
            objects = self._get_queryset().all()[:3]
            pk_list = [obj.pk for obj in objects]
            data = {
                'pk': pk_list,
                '_apply': True,  # Form button
            }
            data.update(self.rename_data)

            # Assign constrained permission
            obj_perm = ObjectPermission(name='Test permission',
                                        constraints={'name__regex': '[^X]$'},
                                        actions=['change'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Attempt to bulk edit permitted objects into a non-permitted state
            response = self.client.post(self._get_url('bulk_rename'), data)
            self.assertHttpStatus(response, 200)

            # Update permission constraints
            obj_perm.constraints = {'pk__gt': 0}
            obj_perm.save()

            # Bulk rename permitted objects
            self.assertHttpStatus(
                self.client.post(self._get_url('bulk_rename'), data), 302)
            for i, instance in enumerate(
                    self._get_queryset().filter(pk__in=pk_list)):
                self.assertEqual(instance.name, f'{objects[i].name}X')
Beispiel #23
0
        def test_bulk_delete_objects_with_constrained_permission(self):
            initial_count = self._get_queryset().count()
            pk_list = self._get_queryset().values_list('pk', flat=True)
            data = {
                'pk': pk_list,
                'confirm': True,
                '_confirm': True,  # Form button
            }

            # Assign constrained permission
            obj_perm = ObjectPermission(
                name='Test permission',
                constraints={'pk': 0},  # Dummy permission to deny all
                actions=['delete'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Attempt to bulk delete non-permitted objects
            self.assertHttpStatus(
                self.client.post(self._get_url('bulk_delete'), data), 302)
            self.assertEqual(self._get_queryset().count(), initial_count)

            # Update permission constraints
            obj_perm.constraints = {
                'pk__gt': 0
            }  # Dummy permission to allow all
            obj_perm.save()

            # Bulk delete permitted objects
            self.assertHttpStatus(
                self.client.post(self._get_url('bulk_delete'), data), 302)
            self.assertEqual(self._get_queryset().count(), 0)
Beispiel #24
0
        def test_list_objects_with_constrained_permission(self):
            instance1, instance2 = self._get_queryset().all()[:2]

            # Add object-level permission
            obj_perm = ObjectPermission(name='Test permission',
                                        constraints={'pk': instance1.pk},
                                        actions=['view'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with object-level permission
            response = self.client.get(self._get_url('list'))
            self.assertHttpStatus(response, 200)
            content = str(response.content)
            self.assertIn(instance1.get_absolute_url(), content)
            self.assertNotIn(instance2.get_absolute_url(), content)
Beispiel #25
0
        def test_get_object_with_constrained_permission(self):
            instance1, instance2 = self._get_queryset().all()[:2]

            # Add object-level permission
            obj_perm = ObjectPermission(constraints={'pk': instance1.pk},
                                        actions=['view'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET to permitted object
            self.assertHttpStatus(
                self.client.get(instance1.get_absolute_url()), 200)

            # Try GET to non-permitted object
            self.assertHttpStatus(
                self.client.get(instance2.get_absolute_url()), 404)
Beispiel #26
0
        def test_list_objects_with_permission(self):

            # Add model-level permission
            obj_perm = ObjectPermission(actions=['view'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try GET with model-level permission
            self.assertHttpStatus(self.client.get(self._get_url('list')), 200)

            # Built-in CSV export
            if hasattr(self.model, 'csv_headers'):
                response = self.client.get('{}?export'.format(
                    self._get_url('list')))
                self.assertHttpStatus(response, 200)
                self.assertEqual(response.get('Content-Type'), 'text/csv')
    def test_list_objects(self):
        url = reverse('ipam-api:prefix-list')

        # Attempt to list objects without permission
        response = self.client.get(url, **self.header)
        self.assertEqual(response.status_code, 403)

        # Assign object permission
        obj_perm = ObjectPermission(constraints={'site__name': 'Site 1'},
                                    actions=['view'])
        obj_perm.save()
        obj_perm.users.add(self.user)
        obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix))

        # Retrieve all objects. Only permitted objects should be returned.
        response = self.client.get(url, **self.header)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['count'], 3)
Beispiel #28
0
        def test_delete_object(self):
            """
            DELETE a single object identified by its numeric ID.
            """
            instance = self._get_queryset().first()
            url = self._get_detail_url(instance)

            # Add object-level permission
            obj_perm = ObjectPermission(actions=['delete'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            response = self.client.delete(url, **self.header)
            self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
            self.assertFalse(
                self._get_queryset().filter(pk=instance.pk).exists())
Beispiel #29
0
        def test_bulk_delete_objects_with_permission(self):
            pk_list = self._get_queryset().values_list('pk', flat=True)
            data = {
                'pk': pk_list,
                'confirm': True,
                '_confirm': True,  # Form button
            }

            # Assign unconstrained permission
            obj_perm = ObjectPermission(actions=['delete'])
            obj_perm.save()
            obj_perm.users.add(self.user)
            obj_perm.object_types.add(
                ContentType.objects.get_for_model(self.model))

            # Try POST with model-level permission
            self.assertHttpStatus(
                self.client.post(self._get_url('bulk_delete'), data), 302)
            self.assertEqual(self._get_queryset().count(), 0)
Beispiel #30
0
    def test_edit_object(self):

        # Attempt to edit an object without permission
        data = {'site': self.sites[0].pk}
        url = reverse('ipam-api:prefix-detail',
                      kwargs={'pk': self.prefixes[0].pk})
        response = self.client.patch(url, data, format='json', **self.header)
        self.assertEqual(response.status_code, 403)

        # Assign object permission
        obj_perm = ObjectPermission(
            name='Test permission',
            constraints={'site__name': 'Site 1'},
            actions=['change']
        )
        obj_perm.save()
        obj_perm.users.add(self.user)
        obj_perm.object_types.add(ContentType.objects.get_for_model(Prefix))

        # Attempt to edit a non-permitted object
        data = {'site': self.sites[0].pk}
        url = reverse('ipam-api:prefix-detail',
                      kwargs={'pk': self.prefixes[3].pk})
        response = self.client.patch(url, data, format='json', **self.header)
        self.assertEqual(response.status_code, 404)

        # Edit a permitted object
        data['status'] = 'reserved'
        url = reverse('ipam-api:prefix-detail',
                      kwargs={'pk': self.prefixes[0].pk})
        response = self.client.patch(url, data, format='json', **self.header)
        self.assertEqual(response.status_code, 200)

        # Attempt to modify a permitted object to a non-permitted object
        data['site'] = self.sites[1].pk
        url = reverse('ipam-api:prefix-detail',
                      kwargs={'pk': self.prefixes[0].pk})
        response = self.client.patch(url, data, format='json', **self.header)
        self.assertEqual(response.status_code, 403)