| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- from django.contrib.auth import get_user_model
- from django.contrib.auth.models import Group
- from django.contrib.contenttypes.models import ContentType
- from django.urls import reverse
- from users.models import ObjectPermission, Token
- from utilities.testing import APIViewTestCases, APITestCase, create_test_user
- from utilities.utils import deepmerge
- User = get_user_model()
- class AppTest(APITestCase):
- def test_root(self):
- url = reverse('users-api:api-root')
- response = self.client.get(f'{url}?format=api', **self.header)
- self.assertEqual(response.status_code, 200)
- class UserTest(APIViewTestCases.APIViewTestCase):
- model = User
- view_namespace = 'users'
- brief_fields = ['display', 'id', 'url', 'username']
- validation_excluded_fields = ['password']
- create_data = [
- {
- 'username': 'User_4',
- 'password': 'password4',
- },
- {
- 'username': 'User_5',
- 'password': 'password5',
- },
- {
- 'username': 'User_6',
- 'password': 'password6',
- },
- ]
- bulk_update_data = {
- 'email': 'test@example.com',
- }
- @classmethod
- def setUpTestData(cls):
- users = (
- User(username='User_1', password='password1'),
- User(username='User_2', password='password2'),
- User(username='User_3', password='password3'),
- )
- User.objects.bulk_create(users)
- def test_that_password_is_changed(self):
- """
- Test that password is changed
- """
- 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))
- user_credentials = {
- 'username': 'user1',
- 'password': 'abc123',
- }
- user = User.objects.create_user(**user_credentials)
- data = {
- 'password': 'newpassword'
- }
- url = reverse('users-api:user-detail', kwargs={'pk': user.id})
- response = self.client.patch(url, data, format='json', **self.header)
- self.assertEqual(response.status_code, 200)
- updated_user = User.objects.get(id=user.id)
- self.assertTrue(updated_user.check_password(data['password']))
- class GroupTest(APIViewTestCases.APIViewTestCase):
- model = Group
- view_namespace = 'users'
- brief_fields = ['display', 'id', 'name', 'url']
- create_data = [
- {
- 'name': 'Group 4',
- },
- {
- 'name': 'Group 5',
- },
- {
- 'name': 'Group 6',
- },
- ]
- @classmethod
- def setUpTestData(cls):
- users = (
- Group(name='Group 1'),
- Group(name='Group 2'),
- Group(name='Group 3'),
- )
- Group.objects.bulk_create(users)
- def test_bulk_update_objects(self):
- """
- Disabled test. There's no attribute we can set in bulk for Groups.
- """
- return
- class TokenTest(
- # No GraphQL support for Token
- APIViewTestCases.GetObjectViewTestCase,
- APIViewTestCases.ListObjectsViewTestCase,
- APIViewTestCases.CreateObjectViewTestCase,
- APIViewTestCases.UpdateObjectViewTestCase,
- APIViewTestCases.DeleteObjectViewTestCase
- ):
- model = Token
- brief_fields = ['display', 'id', 'key', 'url', 'write_enabled']
- bulk_update_data = {
- 'description': 'New description',
- }
- def setUp(self):
- super().setUp()
- # Apply grant_token permission to enable the creation of Tokens for other Users
- self.add_permissions('users.grant_token')
- @classmethod
- def setUpTestData(cls):
- users = (
- create_test_user('User 1'),
- create_test_user('User 2'),
- create_test_user('User 3'),
- )
- tokens = (
- Token(user=users[0]),
- Token(user=users[1]),
- Token(user=users[2]),
- )
- # Use save() instead of bulk_create() to ensure keys get automatically generated
- for token in tokens:
- token.save()
- cls.create_data = [
- {
- 'user': users[0].pk,
- },
- {
- 'user': users[1].pk,
- },
- {
- 'user': users[2].pk,
- },
- ]
- def test_provision_token_valid(self):
- """
- Test the provisioning of a new REST API token given a valid username and password.
- """
- user_credentials = {
- 'username': 'user1',
- 'password': 'abc123',
- }
- user = User.objects.create_user(**user_credentials)
- data = {
- **user_credentials,
- 'description': 'My API token',
- 'expires': '2099-12-31T23:59:59Z',
- }
- url = reverse('users-api:token_provision')
- response = self.client.post(url, data, format='json', **self.header)
- self.assertEqual(response.status_code, 201)
- self.assertIn('key', response.data)
- self.assertEqual(len(response.data['key']), 40)
- self.assertEqual(response.data['description'], data['description'])
- self.assertEqual(response.data['expires'], data['expires'])
- token = Token.objects.get(user=user)
- self.assertEqual(token.key, response.data['key'])
- def test_provision_token_invalid(self):
- """
- Test the behavior of the token provisioning view when invalid credentials are supplied.
- """
- data = {
- 'username': 'nonexistentuser',
- 'password': 'abc123',
- }
- url = reverse('users-api:token_provision')
- response = self.client.post(url, data, format='json', **self.header)
- self.assertEqual(response.status_code, 403)
- def test_provision_token_other_user(self):
- """
- Test provisioning a Token for a different User with & without the grant_token permission.
- """
- # Clear grant_token permission assigned by setUpTestData
- ObjectPermission.objects.filter(users=self.user).delete()
- self.add_permissions('users.add_token')
- user2 = User.objects.create_user(username='testuser2')
- data = {
- 'user': user2.id,
- }
- url = reverse('users-api:token-list')
- # Attempt to create a new Token for User2 *without* the grant_token permission
- response = self.client.post(url, data, format='json', **self.header)
- self.assertEqual(response.status_code, 403)
- # Assign grant_token permission and successfully create a new Token for User2
- self.add_permissions('users.grant_token')
- response = self.client.post(url, data, format='json', **self.header)
- self.assertEqual(response.status_code, 201)
- class ObjectPermissionTest(
- # No GraphQL support for ObjectPermission
- APIViewTestCases.GetObjectViewTestCase,
- APIViewTestCases.ListObjectsViewTestCase,
- APIViewTestCases.CreateObjectViewTestCase,
- APIViewTestCases.UpdateObjectViewTestCase,
- APIViewTestCases.DeleteObjectViewTestCase
- ):
- model = ObjectPermission
- brief_fields = ['actions', 'display', 'enabled', 'groups', 'id', 'name', 'object_types', 'url', 'users']
- @classmethod
- def setUpTestData(cls):
- groups = (
- Group(name='Group 1'),
- Group(name='Group 2'),
- Group(name='Group 3'),
- )
- Group.objects.bulk_create(groups)
- users = (
- User(username='User 1', is_active=True),
- User(username='User 2', is_active=True),
- User(username='User 3', is_active=True),
- )
- User.objects.bulk_create(users)
- object_type = ContentType.objects.get(app_label='dcim', model='device')
- for i in range(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'},
- },
- ]
- cls.bulk_update_data = {
- 'description': 'New description',
- }
- class UserConfigTest(APITestCase):
- def test_get(self):
- """
- Retrieve user configuration via GET request.
- """
- userconfig = self.user.config
- url = reverse('users-api:userconfig-list')
- response = self.client.get(url, **self.header)
- self.assertEqual(response.data, {})
- data = {
- "a": 123,
- "b": 456,
- "c": 789,
- }
- userconfig.data = data
- userconfig.save()
- response = self.client.get(url, **self.header)
- self.assertEqual(response.data, data)
- def test_patch(self):
- """
- Set user config via PATCH requests.
- """
- userconfig = self.user.config
- url = reverse('users-api:userconfig-list')
- data = {
- "a": {
- "a1": "X",
- "a2": "Y",
- },
- "b": {
- "b1": "Z",
- }
- }
- response = self.client.patch(url, data=data, format='json', **self.header)
- self.assertDictEqual(response.data, data)
- userconfig.refresh_from_db()
- self.assertDictEqual(userconfig.data, data)
- update_data = {
- "c": 123
- }
- response = self.client.patch(url, data=update_data, format='json', **self.header)
- new_data = deepmerge(data, update_data)
- self.assertDictEqual(response.data, new_data)
- userconfig.refresh_from_db()
- self.assertDictEqual(userconfig.data, new_data)
|