1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00
Jeremy Stretch 9b39ba169c Merge branch 'develop' into api2
Conflicts:
	netbox/dcim/api/serializers.py
	netbox/dcim/api/urls.py
	netbox/dcim/api/views.py
	netbox/dcim/filters.py
	netbox/dcim/tables.py
	requirements.txt
2017-03-02 16:01:25 -05:00

130 lines
4.2 KiB
Python

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from django import forms
from django.db.models import Count
from dcim.models import Device
from utilities.forms import BootstrapMixin, BulkEditForm, BulkImportForm, CSVDataField, FilterChoiceField, SlugField
from .models import Secret, SecretRole, UserKey
def validate_rsa_key(key, is_secret=True):
"""
Validate the format and type of an RSA key.
"""
try:
key = RSA.importKey(key)
except ValueError:
raise forms.ValidationError("Invalid RSA key. Please ensure that your key is in PEM (base64) format.")
except Exception as e:
raise forms.ValidationError("Invalid key detected: {}".format(e))
if is_secret and not key.has_private():
raise forms.ValidationError("This looks like a public key. Please provide your private RSA key.")
elif not is_secret and key.has_private():
raise forms.ValidationError("This looks like a private key. Please provide your public RSA key.")
try:
PKCS1_OAEP.new(key)
except:
raise forms.ValidationError("Error validating RSA key. Please ensure that your key supports PKCS#1 OAEP.")
#
# Secret roles
#
class SecretRoleForm(BootstrapMixin, forms.ModelForm):
slug = SlugField()
class Meta:
model = SecretRole
fields = ['name', 'slug']
#
# Secrets
#
class SecretForm(BootstrapMixin, forms.ModelForm):
plaintext = forms.CharField(max_length=65535, required=False, label='Plaintext',
widget=forms.PasswordInput())
plaintext2 = forms.CharField(max_length=65535, required=False, label='Plaintext (verify)',
widget=forms.PasswordInput())
class Meta:
model = Secret
fields = ['role', 'name', 'plaintext', 'plaintext2']
def clean(self):
if self.cleaned_data['plaintext'] != self.cleaned_data['plaintext2']:
raise forms.ValidationError({
'plaintext2': "The two given plaintext values do not match. Please check your input."
})
class SecretFromCSVForm(forms.ModelForm):
device = forms.ModelChoiceField(queryset=Device.objects.all(), required=False, to_field_name='name',
error_messages={'invalid_choice': 'Device not found.'})
role = forms.ModelChoiceField(queryset=SecretRole.objects.all(), to_field_name='name',
error_messages={'invalid_choice': 'Invalid secret role.'})
plaintext = forms.CharField()
class Meta:
model = Secret
fields = ['device', 'role', 'name', 'plaintext']
def save(self, *args, **kwargs):
s = super(SecretFromCSVForm, self).save(*args, **kwargs)
s.plaintext = str(self.cleaned_data['plaintext'])
return s
class SecretImportForm(BootstrapMixin, BulkImportForm):
csv = CSVDataField(csv_form=SecretFromCSVForm)
class SecretBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(queryset=Secret.objects.all(), widget=forms.MultipleHiddenInput)
role = forms.ModelChoiceField(queryset=SecretRole.objects.all(), required=False)
name = forms.CharField(max_length=100, required=False)
class Meta:
nullable_fields = ['name']
class SecretFilterForm(BootstrapMixin, forms.Form):
q = forms.CharField(required=False, label='Search')
role = FilterChoiceField(
queryset=SecretRole.objects.annotate(filter_count=Count('secrets')),
to_field_name='slug'
)
#
# UserKeys
#
class UserKeyForm(BootstrapMixin, forms.ModelForm):
class Meta:
model = UserKey
fields = ['public_key']
help_texts = {
'public_key': "Enter your public RSA key. Keep the private one with you; you'll need it for decryption.",
}
def clean_public_key(self):
key = self.cleaned_data['public_key']
# Validate the RSA key format.
validate_rsa_key(key, is_secret=False)
return key
class ActivateUserKeyForm(forms.Form):
_selected_action = forms.ModelMultipleChoiceField(queryset=UserKey.objects.all(), label='User Keys')
secret_key = forms.CharField(label='Your private key', widget=forms.Textarea(attrs={'class': 'vLargeTextField'}))