def setUp(self): user = create_test_user(permissions=['secrets.view_secret']) self.client = Client() self.client.force_login(user) site = Site(name='Site 1', slug='site-1') site.save() manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1') manufacturer.save() devicetype = DeviceType(manufacturer=manufacturer, model='Device Type 1') devicetype.save() devicerole = DeviceRole(name='Device Role 1', slug='device-role-1') devicerole.save() device = Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole) device.save() secretrole = SecretRole(name='Secret Role 1', slug='secret-role-1') secretrole.save() Secret.objects.bulk_create([ Secret(device=device, role=secretrole, name='Secret 1', ciphertext=b'1234567890'), Secret(device=device, role=secretrole, name='Secret 2', ciphertext=b'1234567890'), Secret(device=device, role=secretrole, name='Secret 3', ciphertext=b'1234567890'), ])
def setUpTestData(cls): site = Site.objects.create(name='Site 1', slug='site-1') manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1') device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') devices = ( Device(device_type=device_type, name='Device 1', site=site, device_role=device_role), Device(device_type=device_type, name='Device 2', site=site, device_role=device_role), Device(device_type=device_type, name='Device 3', site=site, device_role=device_role), ) Device.objects.bulk_create(devices) roles = ( SecretRole(name='Secret Role 1', slug='secret-role-1'), SecretRole(name='Secret Role 2', slug='secret-role-2'), SecretRole(name='Secret Role 3', slug='secret-role-3'), ) SecretRole.objects.bulk_create(roles) secrets = ( Secret(device=devices[0], role=roles[0], name='Secret 1', plaintext='SECRET DATA'), Secret(device=devices[1], role=roles[1], name='Secret 2', plaintext='SECRET DATA'), Secret(device=devices[2], role=roles[2], name='Secret 3', plaintext='SECRET DATA'), ) # Must call save() to encrypt Secrets for s in secrets: s.save()
def setUpTestData(cls): site = Site.objects.create(name='Site 1', slug='site-1') manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1') devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') devices = ( Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole), Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole), Device(name='Device 3', site=site, device_type=devicetype, device_role=devicerole), ) Device.objects.bulk_create(devices) secretroles = ( SecretRole(name='Secret Role 1', slug='secret-role-1'), SecretRole(name='Secret Role 2', slug='secret-role-2'), ) SecretRole.objects.bulk_create(secretroles) # Create one secret per device to allow bulk-editing of names (which must be unique per device/role) Secret.objects.bulk_create(( Secret(assigned_object=devices[0], role=secretroles[0], name='Secret 1', ciphertext=b'1234567890'), Secret(assigned_object=devices[1], role=secretroles[0], name='Secret 2', ciphertext=b'1234567890'), Secret(assigned_object=devices[2], role=secretroles[0], name='Secret 3', ciphertext=b'1234567890'), )) cls.form_data = { 'assigned_object_type': 'dcim.device', 'assigned_object_id': devices[1].pk, 'role': secretroles[1].pk, 'name': 'Secret X', } cls.bulk_edit_data = { 'role': secretroles[1].pk, 'name': 'New name', }
def setUp(self): super().setUp() # Create a UserKey for the test user userkey = UserKey(user=self.user, public_key=PUBLIC_KEY) userkey.save() # Create a SessionKey for the user self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) # Append the session key to the test client's request header self.header['HTTP_X_SESSION_KEY'] = base64.b64encode(session_key.key) site = Site.objects.create(name='Site 1', slug='site-1') manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1') devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') device = Device.objects.create(name='Device 1', site=site, device_type=devicetype, device_role=devicerole) secret_roles = ( SecretRole(name='Secret Role 1', slug='secret-role-1'), SecretRole(name='Secret Role 2', slug='secret-role-2'), ) SecretRole.objects.bulk_create(secret_roles) secrets = ( Secret(device=device, role=secret_roles[0], name='Secret 1', plaintext='ABC'), Secret(device=device, role=secret_roles[0], name='Secret 2', plaintext='DEF'), Secret(device=device, role=secret_roles[0], name='Secret 3', plaintext='GHI'), ) for secret in secrets: secret.encrypt(self.master_key) secret.save() self.create_data = [ { 'device': device.pk, 'role': secret_roles[1].pk, 'name': 'Secret 4', 'plaintext': 'JKL', }, { 'device': device.pk, 'role': secret_roles[1].pk, 'name': 'Secret 5', 'plaintext': 'MNO', }, { 'device': device.pk, 'role': secret_roles[1].pk, 'name': 'Secret 6', 'plaintext': 'PQR', }, ]
def test_01_encrypt_decrypt(self): """ Test basic encryption and decryption functionality using a random master key. """ plaintext = "FooBar123" secret_key = generate_random_key() s = Secret(plaintext=plaintext) s.encrypt(secret_key) # Ensure plaintext is deleted upon encryption self.assertIsNone(s.plaintext, "Plaintext must be None after encrypting.") # Enforce minimum ciphertext length self.assertGreaterEqual(len(s.ciphertext), 80, "Ciphertext must be at least 80 bytes (16B IV + 64B+ ciphertext") # Ensure proper hashing algorithm is used hasher, iterations, salt, sha256 = s.hash.split('$') self.assertEqual(hasher, 'pbkdf2_sha256', "Hashing algorithm has been modified to: {}".format(hasher)) self.assertGreaterEqual(int(iterations), SecretValidationHasher.iterations, "Insufficient iteration count ({}) for hash".format(iterations)) self.assertGreaterEqual(len(salt), 12, "Hash salt is too short ({} chars)".format(len(salt))) # Test hash validation self.assertTrue(s.validate(plaintext), "Plaintext does not validate against the generated hash") self.assertFalse(s.validate(""), "Empty plaintext validated against hash") self.assertFalse(s.validate("Invalid plaintext"), "Invalid plaintext validated against hash") # Test decryption s.decrypt(secret_key) self.assertEqual(plaintext, s.plaintext, "Decrypting Secret returned incorrect plaintext")
def _get_encrypted_fields(self, serializer): """ Since we can't call encrypt() on the serializer like we can on the Secret model, we need to calculate the ciphertext and hash values by encrypting a dummy copy. These can be passed to the serializer's save() method. """ s = Secret(plaintext=serializer.validated_data['plaintext']) s.encrypt(self.master_key) return ({ 'ciphertext': s.ciphertext, 'hash': s.hash, })
def setUp(self): user = create_test_user(permissions=[ 'secrets.view_secret', 'secrets.add_secret', ]) # Set up a master key userkey = UserKey(user=user, public_key=PUBLIC_KEY) userkey.save() master_key = userkey.get_master_key(PRIVATE_KEY) self.session_key = SessionKey(userkey=userkey) self.session_key.save(master_key) self.client = Client() self.client.force_login(user) site = Site(name='Site 1', slug='site-1') site.save() manufacturer = Manufacturer(name='Manufacturer 1', slug='manufacturer-1') manufacturer.save() devicetype = DeviceType(manufacturer=manufacturer, model='Device Type 1') devicetype.save() devicerole = DeviceRole(name='Device Role 1', slug='device-role-1') devicerole.save() device = Device(name='Device 1', site=site, device_type=devicetype, device_role=devicerole) device.save() secretrole = SecretRole(name='Secret Role 1', slug='secret-role-1') secretrole.save() Secret.objects.bulk_create([ Secret(device=device, role=secretrole, name='Secret 1', ciphertext=b'1234567890'), Secret(device=device, role=secretrole, name='Secret 2', ciphertext=b'1234567890'), Secret(device=device, role=secretrole, name='Secret 3', ciphertext=b'1234567890'), ])
def validate(self, data): # Encrypt plaintext data using the master key provided from the view context if data.get('plaintext'): s = Secret(plaintext=data['plaintext']) s.encrypt(self.context['master_key']) data['ciphertext'] = s.ciphertext data['hash'] = s.hash super().validate(data) return data
def test_01_encrypt_decrypt(self): """ Test basic encryption and decryption functionality using a random master key. """ plaintext = string.printable * 2 secret_key = generate_random_key() s = Secret(plaintext=plaintext) s.encrypt(secret_key) # Ensure plaintext is deleted upon encryption self.assertIsNone(s.plaintext, "Plaintext must be None after encrypting.") # Enforce minimum ciphertext length self.assertGreaterEqual(len(s.ciphertext), 80, "Ciphertext must be at least 80 bytes (16B IV + 64B+ ciphertext") # Ensure proper hashing algorithm is used hasher, iterations, salt, sha256 = s.hash.split('$') self.assertEqual(hasher, 'pbkdf2_sha256', "Hashing algorithm has been modified to: {}".format(hasher)) self.assertGreaterEqual(int(iterations), SecretValidationHasher.iterations, "Insufficient iteration count ({}) for hash".format(iterations)) self.assertGreaterEqual(len(salt), 12, "Hash salt is too short ({} chars)".format(len(salt))) # Test hash validation self.assertTrue(s.validate(plaintext), "Plaintext does not validate against the generated hash") self.assertFalse(s.validate(""), "Empty plaintext validated against hash") self.assertFalse(s.validate("Invalid plaintext"), "Invalid plaintext validated against hash") # Test decryption s.decrypt(secret_key) self.assertEqual(plaintext, s.plaintext, "Decrypting Secret returned incorrect plaintext")
def test_02_ciphertext_uniqueness(self): """ Generate 50 Secrets using the same plaintext and check for duplicate IVs or payloads. """ plaintext = "1234567890abcdef" ivs = [] ciphertexts = [] for i in range(1, 51): s = Secret(plaintext=plaintext) s.encrypt(self.secret_key) ivs.append(s.ciphertext[0:16]) ciphertexts.append(s.ciphertext[16:32]) duplicate_ivs = [i for i, x in enumerate(ivs) if ivs.count(x) > 1] self.assertEqual(duplicate_ivs, [], "One or more duplicate IVs found!") duplicate_ciphertexts = [i for i, x in enumerate(ciphertexts) if ciphertexts.count(x) > 1] self.assertEqual(duplicate_ciphertexts, [], "One or more duplicate ciphertexts (first blocks) found!")
def test_02_ciphertext_uniqueness(self): """ Generate 50 Secrets using the same plaintext and check for duplicate IVs or payloads. """ plaintext = "1234567890abcdef" secret_key = generate_random_key() ivs = [] ciphertexts = [] for i in range(1, 51): s = Secret(plaintext=plaintext) s.encrypt(secret_key) ivs.append(s.ciphertext[0:16]) ciphertexts.append(s.ciphertext[16:32]) duplicate_ivs = [i for i, x in enumerate(ivs) if ivs.count(x) > 1] self.assertEqual(duplicate_ivs, [], "One or more duplicate IVs found!") duplicate_ciphertexts = [i for i, x in enumerate(ciphertexts) if ciphertexts.count(x) > 1] self.assertEqual(duplicate_ciphertexts, [], "One or more duplicate ciphertexts (first blocks) found!")
def setUp(self): user = User.objects.create(username='******', is_superuser=True) token = Token.objects.create(user=user) userkey = UserKey(user=user, public_key=PUBLIC_KEY) userkey.save() self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) self.header = { 'HTTP_AUTHORIZATION': 'Token {}'.format(token.key), 'HTTP_X_SESSION_KEY': base64.b64encode(session_key.key), } self.plaintext = { 'secret1': 'Secret #1 Plaintext', 'secret2': 'Secret #2 Plaintext', 'secret3': 'Secret #3 Plaintext', } site = Site.objects.create(name='Test Site 1', slug='test-site-1') manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device Type 1') devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1') self.device = Device.objects.create( name='Test Device 1', site=site, device_type=devicetype, device_role=devicerole ) self.secretrole1 = SecretRole.objects.create(name='Test Secret Role 1', slug='test-secret-role-1') self.secretrole2 = SecretRole.objects.create(name='Test Secret Role 2', slug='test-secret-role-2') self.secret1 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 1', plaintext=self.plaintext['secret1'] ) self.secret1.encrypt(self.master_key) self.secret1.save() self.secret2 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 2', plaintext=self.plaintext['secret2'] ) self.secret2.encrypt(self.master_key) self.secret2.save() self.secret3 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 3', plaintext=self.plaintext['secret3'] ) self.secret3.encrypt(self.master_key) self.secret3.save()
def validate(self, data): # Encrypt plaintext data using the master key provided from the view context if data.get('plaintext'): s = Secret(plaintext=data['plaintext']) s.encrypt(self.context['master_key']) data['ciphertext'] = s.ciphertext data['hash'] = s.hash # Validate uniqueness of name if one has been provided. if data.get('name'): validator = UniqueTogetherValidator(queryset=Secret.objects.all(), fields=('device', 'role', 'name')) validator.set_context(self) validator(data) # Enforce model validation super(SecretSerializer, self).validate(data) return data
def validate(self, data): # Encrypt plaintext data using the master key provided from the view context if data.get('plaintext'): s = Secret(plaintext=data['plaintext']) s.encrypt(self.context['master_key']) data['ciphertext'] = s.ciphertext data['hash'] = s.hash # Validate uniqueness of name if one has been provided. if data.get('name'): validator = UniqueTogetherValidator(queryset=Secret.objects.all(), fields=('device', 'role', 'name')) validator.set_context(self) validator(data) # Enforce model validation super().validate(data) return data
def setUp(self): user = User.objects.create(username='******', is_superuser=True) token = Token.objects.create(user=user) userkey = UserKey(user=user, public_key=PUBLIC_KEY) userkey.save() self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) self.header = { 'HTTP_AUTHORIZATION': 'Token {}'.format(token.key), 'HTTP_X_SESSION_KEY': base64.b64encode(session_key.key), } self.plaintext = { 'secret1': 'Secret #1 Plaintext', 'secret2': 'Secret #2 Plaintext', 'secret3': 'Secret #3 Plaintext', } site = Site.objects.create(name='Test Site 1', slug='test-site-1') manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device Type 1') devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1') self.device = Device.objects.create(name='Test Device 1', site=site, device_type=devicetype, device_role=devicerole) self.secretrole1 = SecretRole.objects.create(name='Test Secret Role 1', slug='test-secret-role-1') self.secretrole2 = SecretRole.objects.create(name='Test Secret Role 2', slug='test-secret-role-2') self.secret1 = Secret(device=self.device, role=self.secretrole1, name='Test Secret 1', plaintext=self.plaintext['secret1']) self.secret1.encrypt(self.master_key) self.secret1.save() self.secret2 = Secret(device=self.device, role=self.secretrole1, name='Test Secret 2', plaintext=self.plaintext['secret2']) self.secret2.encrypt(self.master_key) self.secret2.save() self.secret3 = Secret(device=self.device, role=self.secretrole1, name='Test Secret 3', plaintext=self.plaintext['secret3']) self.secret3.encrypt(self.master_key) self.secret3.save()
def setUp(self): # Create a non-superuser test user self.user = create_test_user('testuser', permissions=( 'secrets.add_secret', 'secrets.change_secret', 'secrets.delete_secret', 'secrets.view_secret', )) self.token = Token.objects.create(user=self.user) self.header = {'HTTP_AUTHORIZATION': 'Token {}'.format(self.token.key)} userkey = UserKey(user=self.user, public_key=PUBLIC_KEY) userkey.save() self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) self.header = { 'HTTP_AUTHORIZATION': 'Token {}'.format(self.token.key), 'HTTP_X_SESSION_KEY': base64.b64encode(session_key.key), } self.plaintexts = ( 'Secret #1 Plaintext', 'Secret #2 Plaintext', 'Secret #3 Plaintext', ) site = Site.objects.create(name='Test Site 1', slug='test-site-1') manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device Type 1') devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1') self.device = Device.objects.create( name='Test Device 1', site=site, device_type=devicetype, device_role=devicerole ) self.secretrole1 = SecretRole.objects.create(name='Test Secret Role 1', slug='test-secret-role-1') self.secretrole2 = SecretRole.objects.create(name='Test Secret Role 2', slug='test-secret-role-2') self.secret1 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 1', plaintext=self.plaintexts[0] ) self.secret1.encrypt(self.master_key) self.secret1.save() self.secret2 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 2', plaintext=self.plaintexts[1] ) self.secret2.encrypt(self.master_key) self.secret2.save() self.secret3 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 3', plaintext=self.plaintexts[2] ) self.secret3.encrypt(self.master_key) self.secret3.save()
def test_minimum_length(self): """ Test enforcement of the minimum length for ciphertexts. """ plaintext = 'A' # One-byte plaintext secret = Secret(plaintext=plaintext) secret.encrypt(self.secret_key) # 16B IV + 2B length + 1B secret + 61B padding = 80 bytes self.assertEqual(len(secret.ciphertext), 80) self.assertIsNone(secret.plaintext) secret.decrypt(self.secret_key) self.assertEqual(secret.plaintext, plaintext)
def test_maximum_length(self): """ Test encrypting a plaintext value of the maximum length. """ plaintext = '0123456789abcdef' * 4096 plaintext = plaintext[:65535] # 65,535 chars secret = Secret(plaintext=plaintext) secret.encrypt(self.secret_key) # 16B IV + 2B length + 65535B secret + 15B padding = 65568 bytes self.assertEqual(len(secret.ciphertext), 65568) self.assertIsNone(secret.plaintext) secret.decrypt(self.secret_key) self.assertEqual(secret.plaintext, plaintext)
def setUpTestData(cls): site = Site.objects.create(name='Site 1', slug='site-1') manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1') device_role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1') devices = ( Device(device_type=device_type, name='Device 1', site=site, device_role=device_role), Device(device_type=device_type, name='Device 2', site=site, device_role=device_role), Device(device_type=device_type, name='Device 3', site=site, device_role=device_role), ) Device.objects.bulk_create(devices) cluster_type = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1') cluster = Cluster.objects.create(name='Cluster 1', type=cluster_type) virtual_machines = ( VirtualMachine(name='Virtual Machine 1', cluster=cluster), VirtualMachine(name='Virtual Machine 2', cluster=cluster), VirtualMachine(name='Virtual Machine 3', cluster=cluster), ) VirtualMachine.objects.bulk_create(virtual_machines) roles = ( SecretRole(name='Secret Role 1', slug='secret-role-1'), SecretRole(name='Secret Role 2', slug='secret-role-2'), SecretRole(name='Secret Role 3', slug='secret-role-3'), ) SecretRole.objects.bulk_create(roles) secrets = ( Secret(assigned_object=devices[0], role=roles[0], name='Secret 1', plaintext='SECRET DATA'), Secret(assigned_object=devices[1], role=roles[1], name='Secret 2', plaintext='SECRET DATA'), Secret(assigned_object=devices[2], role=roles[2], name='Secret 3', plaintext='SECRET DATA'), Secret(assigned_object=virtual_machines[0], role=roles[0], name='Secret 4', plaintext='SECRET DATA'), Secret(assigned_object=virtual_machines[1], role=roles[1], name='Secret 5', plaintext='SECRET DATA'), Secret(assigned_object=virtual_machines[2], role=roles[2], name='Secret 6', plaintext='SECRET DATA'), ) # Must call save() to encrypt Secrets for s in secrets: s.save()
class SecretTest(HttpStatusMixin, APITestCase): def setUp(self): user = User.objects.create(username='******', is_superuser=True) token = Token.objects.create(user=user) userkey = UserKey(user=user, public_key=PUBLIC_KEY) userkey.save() self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) self.header = { 'HTTP_AUTHORIZATION': 'Token {}'.format(token.key), 'HTTP_X_SESSION_KEY': base64.b64encode(session_key.key), } self.plaintext = { 'secret1': 'Secret #1 Plaintext', 'secret2': 'Secret #2 Plaintext', 'secret3': 'Secret #3 Plaintext', } site = Site.objects.create(name='Test Site 1', slug='test-site-1') manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device Type 1') devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1') self.device = Device.objects.create( name='Test Device 1', site=site, device_type=devicetype, device_role=devicerole ) self.secretrole1 = SecretRole.objects.create(name='Test Secret Role 1', slug='test-secret-role-1') self.secretrole2 = SecretRole.objects.create(name='Test Secret Role 2', slug='test-secret-role-2') self.secret1 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 1', plaintext=self.plaintext['secret1'] ) self.secret1.encrypt(self.master_key) self.secret1.save() self.secret2 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 2', plaintext=self.plaintext['secret2'] ) self.secret2.encrypt(self.master_key) self.secret2.save() self.secret3 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 3', plaintext=self.plaintext['secret3'] ) self.secret3.encrypt(self.master_key) self.secret3.save() def test_get_secret(self): url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.get(url, **self.header) self.assertEqual(response.data['plaintext'], self.plaintext['secret1']) def test_list_secrets(self): url = reverse('secrets-api:secret-list') response = self.client.get(url, **self.header) self.assertEqual(response.data['count'], 3) def test_create_secret(self): data = { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 4', 'plaintext': 'Secret #4 Plaintext', } url = reverse('secrets-api:secret-list') response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(response.data['plaintext'], data['plaintext']) self.assertEqual(Secret.objects.count(), 4) secret4 = Secret.objects.get(pk=response.data['id']) secret4.decrypt(self.master_key) self.assertEqual(secret4.role_id, data['role']) self.assertEqual(secret4.plaintext, data['plaintext']) def test_create_secret_bulk(self): data = [ { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 4', 'plaintext': 'Secret #4 Plaintext', }, { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 5', 'plaintext': 'Secret #5 Plaintext', }, { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 6', 'plaintext': 'Secret #6 Plaintext', }, ] url = reverse('secrets-api:secret-list') response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(Secret.objects.count(), 6) self.assertEqual(response.data[0]['plaintext'], data[0]['plaintext']) self.assertEqual(response.data[1]['plaintext'], data[1]['plaintext']) self.assertEqual(response.data[2]['plaintext'], data[2]['plaintext']) def test_update_secret(self): data = { 'device': self.device.pk, 'role': self.secretrole2.pk, 'plaintext': 'NewPlaintext', } url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.put(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) self.assertEqual(response.data['plaintext'], data['plaintext']) self.assertEqual(Secret.objects.count(), 3) secret1 = Secret.objects.get(pk=response.data['id']) secret1.decrypt(self.master_key) self.assertEqual(secret1.role_id, data['role']) self.assertEqual(secret1.plaintext, data['plaintext']) def test_delete_secret(self): url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.delete(url, **self.header) self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) self.assertEqual(Secret.objects.count(), 2)
class SecretTest(HttpStatusMixin, APITestCase): def setUp(self): user = User.objects.create(username='******', is_superuser=True) token = Token.objects.create(user=user) userkey = UserKey(user=user, public_key=PUBLIC_KEY) userkey.save() self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) self.header = { 'HTTP_AUTHORIZATION': 'Token {}'.format(token.key), 'HTTP_X_SESSION_KEY': base64.b64encode(session_key.key), } self.plaintext = { 'secret1': 'Secret #1 Plaintext', 'secret2': 'Secret #2 Plaintext', 'secret3': 'Secret #3 Plaintext', } site = Site.objects.create(name='Test Site 1', slug='test-site-1') manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device Type 1') devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1') self.device = Device.objects.create(name='Test Device 1', site=site, device_type=devicetype, device_role=devicerole) self.secretrole1 = SecretRole.objects.create(name='Test Secret Role 1', slug='test-secret-role-1') self.secretrole2 = SecretRole.objects.create(name='Test Secret Role 2', slug='test-secret-role-2') self.secret1 = Secret(device=self.device, role=self.secretrole1, name='Test Secret 1', plaintext=self.plaintext['secret1']) self.secret1.encrypt(self.master_key) self.secret1.save() self.secret2 = Secret(device=self.device, role=self.secretrole1, name='Test Secret 2', plaintext=self.plaintext['secret2']) self.secret2.encrypt(self.master_key) self.secret2.save() self.secret3 = Secret(device=self.device, role=self.secretrole1, name='Test Secret 3', plaintext=self.plaintext['secret3']) self.secret3.encrypt(self.master_key) self.secret3.save() def test_get_secret(self): url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.get(url, **self.header) self.assertEqual(response.data['plaintext'], self.plaintext['secret1']) def test_list_secrets(self): url = reverse('secrets-api:secret-list') response = self.client.get(url, **self.header) self.assertEqual(response.data['count'], 3) def test_create_secret(self): data = { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 4', 'plaintext': 'Secret #4 Plaintext', } url = reverse('secrets-api:secret-list') response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(response.data['plaintext'], data['plaintext']) self.assertEqual(Secret.objects.count(), 4) secret4 = Secret.objects.get(pk=response.data['id']) secret4.decrypt(self.master_key) self.assertEqual(secret4.role_id, data['role']) self.assertEqual(secret4.plaintext, data['plaintext']) def test_create_secret_bulk(self): data = [ { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 4', 'plaintext': 'Secret #4 Plaintext', }, { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 5', 'plaintext': 'Secret #5 Plaintext', }, { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 6', 'plaintext': 'Secret #6 Plaintext', }, ] url = reverse('secrets-api:secret-list') response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(Secret.objects.count(), 6) self.assertEqual(response.data[0]['plaintext'], data[0]['plaintext']) self.assertEqual(response.data[1]['plaintext'], data[1]['plaintext']) self.assertEqual(response.data[2]['plaintext'], data[2]['plaintext']) def test_update_secret(self): data = { 'device': self.device.pk, 'role': self.secretrole2.pk, 'plaintext': 'NewPlaintext', } url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.put(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) self.assertEqual(response.data['plaintext'], data['plaintext']) self.assertEqual(Secret.objects.count(), 3) secret1 = Secret.objects.get(pk=response.data['id']) secret1.decrypt(self.master_key) self.assertEqual(secret1.role_id, data['role']) self.assertEqual(secret1.plaintext, data['plaintext']) def test_delete_secret(self): url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.delete(url, **self.header) self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) self.assertEqual(Secret.objects.count(), 2)
class SecretTest(APITestCase): def setUp(self): # Create a non-superuser test user self.user = create_test_user('testuser', permissions=( 'secrets.add_secret', 'secrets.change_secret', 'secrets.delete_secret', 'secrets.view_secret', )) self.token = Token.objects.create(user=self.user) self.header = {'HTTP_AUTHORIZATION': 'Token {}'.format(self.token.key)} userkey = UserKey(user=self.user, public_key=PUBLIC_KEY) userkey.save() self.master_key = userkey.get_master_key(PRIVATE_KEY) session_key = SessionKey(userkey=userkey) session_key.save(self.master_key) self.header = { 'HTTP_AUTHORIZATION': 'Token {}'.format(self.token.key), 'HTTP_X_SESSION_KEY': base64.b64encode(session_key.key), } self.plaintexts = ( 'Secret #1 Plaintext', 'Secret #2 Plaintext', 'Secret #3 Plaintext', ) site = Site.objects.create(name='Test Site 1', slug='test-site-1') manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device Type 1') devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1') self.device = Device.objects.create( name='Test Device 1', site=site, device_type=devicetype, device_role=devicerole ) self.secretrole1 = SecretRole.objects.create(name='Test Secret Role 1', slug='test-secret-role-1') self.secretrole2 = SecretRole.objects.create(name='Test Secret Role 2', slug='test-secret-role-2') self.secret1 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 1', plaintext=self.plaintexts[0] ) self.secret1.encrypt(self.master_key) self.secret1.save() self.secret2 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 2', plaintext=self.plaintexts[1] ) self.secret2.encrypt(self.master_key) self.secret2.save() self.secret3 = Secret( device=self.device, role=self.secretrole1, name='Test Secret 3', plaintext=self.plaintexts[2] ) self.secret3.encrypt(self.master_key) self.secret3.save() def test_get_secret(self): url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) # Secret plaintext not be decrypted as the user has not been assigned to the role response = self.client.get(url, **self.header) self.assertIsNone(response.data['plaintext']) # The plaintext should be present once the user has been assigned to the role self.secretrole1.users.add(self.user) response = self.client.get(url, **self.header) self.assertEqual(response.data['plaintext'], self.plaintexts[0]) def test_list_secrets(self): url = reverse('secrets-api:secret-list') # Secret plaintext not be decrypted as the user has not been assigned to the role response = self.client.get(url, **self.header) self.assertEqual(response.data['count'], 3) for secret in response.data['results']: self.assertIsNone(secret['plaintext']) # The plaintext should be present once the user has been assigned to the role self.secretrole1.users.add(self.user) response = self.client.get(url, **self.header) self.assertEqual(response.data['count'], 3) for i, secret in enumerate(response.data['results']): self.assertEqual(secret['plaintext'], self.plaintexts[i]) def test_create_secret(self): data = { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 4', 'plaintext': 'Secret #4 Plaintext', } url = reverse('secrets-api:secret-list') response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(response.data['plaintext'], data['plaintext']) self.assertEqual(Secret.objects.count(), 4) secret4 = Secret.objects.get(pk=response.data['id']) secret4.decrypt(self.master_key) self.assertEqual(secret4.role_id, data['role']) self.assertEqual(secret4.plaintext, data['plaintext']) def test_create_secret_bulk(self): data = [ { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 4', 'plaintext': 'Secret #4 Plaintext', }, { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 5', 'plaintext': 'Secret #5 Plaintext', }, { 'device': self.device.pk, 'role': self.secretrole1.pk, 'name': 'Test Secret 6', 'plaintext': 'Secret #6 Plaintext', }, ] url = reverse('secrets-api:secret-list') response = self.client.post(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(Secret.objects.count(), 6) self.assertEqual(response.data[0]['plaintext'], data[0]['plaintext']) self.assertEqual(response.data[1]['plaintext'], data[1]['plaintext']) self.assertEqual(response.data[2]['plaintext'], data[2]['plaintext']) def test_update_secret(self): data = { 'device': self.device.pk, 'role': self.secretrole2.pk, 'plaintext': 'NewPlaintext', } url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.put(url, data, format='json', **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) self.assertEqual(response.data['plaintext'], data['plaintext']) self.assertEqual(Secret.objects.count(), 3) secret1 = Secret.objects.get(pk=response.data['id']) secret1.decrypt(self.master_key) self.assertEqual(secret1.role_id, data['role']) self.assertEqual(secret1.plaintext, data['plaintext']) def test_delete_secret(self): url = reverse('secrets-api:secret-detail', kwargs={'pk': self.secret1.pk}) response = self.client.delete(url, **self.header) self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) self.assertEqual(Secret.objects.count(), 2)