Przeglądaj źródła

Closes #1739: Enabled custom fields for secrets

Jeremy Stretch 7 lat temu
rodzic
commit
0c0799f3bf

+ 1 - 0
netbox/extras/constants.py

@@ -6,6 +6,7 @@ CUSTOMFIELD_MODELS = (
     'provider', 'circuit',                                         # Circuits
     'site', 'rack', 'devicetype', 'device',                        # DCIM
     'aggregate', 'prefix', 'ipaddress', 'vlan', 'vrf', 'service',  # IPAM
+    'secret',                                                      # Secrets
     'tenant',                                                      # Tenancy
     'cluster', 'virtualmachine',                                   # Virtualization
 )

+ 5 - 2
netbox/secrets/api/serializers.py

@@ -5,6 +5,7 @@ from rest_framework.validators import UniqueTogetherValidator
 from taggit.models import Tag
 
 from dcim.api.serializers import NestedDeviceSerializer
+from extras.api.customfields import CustomFieldModelSerializer
 from secrets.models import Secret, SecretRole
 from utilities.api import TagField, ValidatedModelSerializer, WritableNestedSerializer
 
@@ -32,7 +33,7 @@ class NestedSecretRoleSerializer(WritableNestedSerializer):
 # Secrets
 #
 
-class SecretSerializer(ValidatedModelSerializer):
+class SecretSerializer(CustomFieldModelSerializer):
     device = NestedDeviceSerializer()
     role = NestedSecretRoleSerializer()
     plaintext = serializers.CharField()
@@ -40,7 +41,9 @@ class SecretSerializer(ValidatedModelSerializer):
 
     class Meta:
         model = Secret
-        fields = ['id', 'device', 'role', 'name', 'plaintext', 'hash', 'tags', 'created', 'last_updated']
+        fields = [
+            'id', 'device', 'role', 'name', 'plaintext', 'hash', 'tags', 'custom_fields', 'created', 'last_updated',
+        ]
         validators = []
 
     def validate(self, data):

+ 2 - 1
netbox/secrets/filters.py

@@ -4,6 +4,7 @@ import django_filters
 from django.db.models import Q
 
 from dcim.models import Device
+from extras.filters import CustomFieldFilterSet
 from utilities.filters import NumericInFilter
 from .models import Secret, SecretRole
 
@@ -15,7 +16,7 @@ class SecretRoleFilter(django_filters.FilterSet):
         fields = ['name', 'slug']
 
 
-class SecretFilter(django_filters.FilterSet):
+class SecretFilter(CustomFieldFilterSet, django_filters.FilterSet):
     id__in = NumericInFilter(name='id', lookup_expr='in')
     q = django_filters.CharFilter(
         method='search',

+ 6 - 5
netbox/secrets/forms.py

@@ -7,8 +7,8 @@ from django.db.models import Count
 from taggit.forms import TagField
 
 from dcim.models import Device
-from extras.forms import AddRemoveTagsForm
-from utilities.forms import BootstrapMixin, BulkEditForm, FilterChoiceField, FlexibleModelChoiceField, SlugField
+from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldForm
+from utilities.forms import BootstrapMixin, FilterChoiceField, FlexibleModelChoiceField, SlugField
 from .models import Secret, SecretRole, UserKey
 
 
@@ -59,7 +59,7 @@ class SecretRoleCSVForm(forms.ModelForm):
 # Secrets
 #
 
-class SecretForm(BootstrapMixin, forms.ModelForm):
+class SecretForm(BootstrapMixin, CustomFieldForm):
     plaintext = forms.CharField(
         max_length=65535,
         required=False,
@@ -129,7 +129,7 @@ class SecretCSVForm(forms.ModelForm):
         return s
 
 
-class SecretBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
+class SecretBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     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)
@@ -138,7 +138,8 @@ class SecretBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
         nullable_fields = ['name']
 
 
-class SecretFilterForm(BootstrapMixin, forms.Form):
+class SecretFilterForm(BootstrapMixin, CustomFieldFilterForm):
+    model = Secret
     q = forms.CharField(required=False, label='Search')
     role = FilterChoiceField(
         queryset=SecretRole.objects.annotate(filter_count=Count('secrets')),

+ 8 - 1
netbox/secrets/models.py

@@ -8,12 +8,14 @@ from Crypto.Util import strxor
 from django.conf import settings
 from django.contrib.auth.hashers import make_password, check_password
 from django.contrib.auth.models import Group, User
+from django.contrib.contenttypes.fields import GenericRelation
 from django.core.exceptions import ValidationError
 from django.db import models
 from django.urls import reverse
 from django.utils.encoding import force_bytes, python_2_unicode_compatible
 from taggit.managers import TaggableManager
 
+from extras.models import CustomFieldModel
 from utilities.models import ChangeLoggedModel
 from .exceptions import InvalidKey
 from .hashers import SecretValidationHasher
@@ -311,7 +313,7 @@ class SecretRole(ChangeLoggedModel):
 
 
 @python_2_unicode_compatible
-class Secret(ChangeLoggedModel):
+class Secret(ChangeLoggedModel, CustomFieldModel):
     """
     A Secret stores an AES256-encrypted copy of sensitive data, such as passwords or secret keys. An irreversible
     SHA-256 hash is stored along with the ciphertext for validation upon decryption. Each Secret is assigned to a
@@ -343,6 +345,11 @@ class Secret(ChangeLoggedModel):
         max_length=128,
         editable=False
     )
+    custom_field_values = GenericRelation(
+        to='extras.CustomFieldValue',
+        content_type_field='obj_type',
+        object_id_field='obj_id'
+    )
 
     tags = TaggableManager()
 

+ 2 - 1
netbox/templates/secrets/secret.html

@@ -69,7 +69,7 @@
                 </tr>
             </table>
         </div>
-        {% include 'extras/inc/tags_panel.html' with tags=secret.tags.all url='secrets:secret_list' %}
+        {% include 'inc/custom_fields_panel.html' with custom_fields=secret.get_custom_fields %}
 	</div>
 	<div class="col-md-6">
         {% if secret|decryptable_by:request.user %}
@@ -101,6 +101,7 @@
                 You do not have permission to decrypt this secret.
             </div>
         {% endif %}
+        {% include 'extras/inc/tags_panel.html' with tags=secret.tags.all url='secrets:secret_list' %}
     </div>
 </div>
 

+ 8 - 0
netbox/templates/secrets/secret_edit.html

@@ -54,6 +54,14 @@
                     {% render_field form.plaintext2 %}
                 </div>
             </div>
+            {% if form.custom_fields %}
+                <div class="panel panel-default">
+                    <div class="panel-heading"><strong>Custom Fields</strong></div>
+                    <div class="panel-body">
+                        {% render_custom_fields form %}
+                    </div>
+                </div>
+            {% endif %}
             <div class="panel panel-default">
                 <div class="panel-heading"><strong>Tags</strong></div>
                 <div class="panel-body">