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'),
        ])
Example #2
0
    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()
Example #3
0
    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',
        }
Example #4
0
    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',
            },
        ]
Example #5
0
    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")
Example #6
0
File: views.py Project: zh-h/netbox
 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,
     })
Example #7
0
 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,
     })
Example #8
0
    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'),
        ])
Example #9
0
    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
Example #10
0
    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")
Example #11
0
 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!")
Example #12
0
 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!")
Example #13
0
    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()
Example #14
0
    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
Example #15
0
    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
Example #16
0
    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()
Example #17
0
    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()
Example #18
0
    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)
Example #19
0
    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)
Example #20
0
    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()
Example #21
0
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)
Example #22
0
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)
Example #23
0
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)