mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fix bulk creation of Secrets via API
This commit is contained in:
@ -50,8 +50,15 @@ class WritableSecretSerializer(serializers.ModelSerializer):
|
||||
|
||||
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', None):
|
||||
if data.get('name'):
|
||||
validator = UniqueTogetherValidator(queryset=Secret.objects.all(), fields=('device', 'role', 'name'))
|
||||
validator.set_context(self)
|
||||
validator(data)
|
||||
|
@ -56,17 +56,13 @@ class SecretViewSet(ModelViewSet):
|
||||
|
||||
master_key = None
|
||||
|
||||
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 get_serializer_context(self):
|
||||
|
||||
# Make the master key available to the serializer for encrypting plaintext values
|
||||
context = super(SecretViewSet, self).get_serializer_context()
|
||||
context['master_key'] = self.master_key
|
||||
|
||||
return context
|
||||
|
||||
def initial(self, request, *args, **kwargs):
|
||||
|
||||
@ -128,12 +124,6 @@ class SecretViewSet(ModelViewSet):
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(**self._get_encrypted_fields(serializer))
|
||||
|
||||
def perform_update(self, serializer):
|
||||
serializer.save(**self._get_encrypted_fields(serializer))
|
||||
|
||||
|
||||
class GetSessionKeyViewSet(ViewSet):
|
||||
"""
|
||||
|
@ -164,9 +164,9 @@ class SecretTest(HttpStatusMixin, APITestCase):
|
||||
}
|
||||
|
||||
self.plaintext = {
|
||||
'secret1': 'Secret#1Plaintext',
|
||||
'secret2': 'Secret#2Plaintext',
|
||||
'secret3': 'Secret#3Plaintext',
|
||||
'secret1': 'Secret #1 Plaintext',
|
||||
'secret2': 'Secret #2 Plaintext',
|
||||
'secret3': 'Secret #3 Plaintext',
|
||||
}
|
||||
|
||||
site = Site.objects.create(name='Test Site 1', slug='test-site-1')
|
||||
@ -213,7 +213,8 @@ class SecretTest(HttpStatusMixin, APITestCase):
|
||||
data = {
|
||||
'device': self.device.pk,
|
||||
'role': self.secretrole1.pk,
|
||||
'plaintext': 'Secret#4Plaintext',
|
||||
'name': 'Test Secret 4',
|
||||
'plaintext': 'Secret #4 Plaintext',
|
||||
}
|
||||
|
||||
url = reverse('secrets-api:secret-list')
|
||||
@ -233,16 +234,19 @@ class SecretTest(HttpStatusMixin, APITestCase):
|
||||
{
|
||||
'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',
|
||||
},
|
||||
]
|
||||
|
Reference in New Issue
Block a user