mirror of
				https://github.com/netbox-community/netbox.git
				synced 2024-05-10 07:54:54 +00:00 
			
		
		
		
	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
		
			
				
	
	
		
			130 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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'}))
 |