Add feature-specific object type validation

This commit is contained in:
Jeremy Stretch 2023-11-06 09:46:08 -05:00
parent bfd10ebfe9
commit aef8ff09e7
4 changed files with 54 additions and 3 deletions

View File

@ -3,6 +3,7 @@ import uuid
import django_rq import django_rq
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
@ -121,6 +122,15 @@ class Job(models.Model):
def get_status_color(self): def get_status_color(self):
return JobStatusChoices.colors.get(self.status) return JobStatusChoices.colors.get(self.status)
def clean(self):
super().clean()
# Validate the assigned object type
if self.object_type not in ContentType.objects.with_feature('jobs'):
raise ValidationError(
_("Jobs cannot be assigned to this object type ({type}).").format(type=self.object_type)
)
@property @property
def duration(self): def duration(self):
if not self.completed: if not self.completed:

View File

@ -1,9 +1,11 @@
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from core.models import ContentType
from extras.choices import * from extras.choices import *
from ..querysets import ObjectChangeQuerySet from ..querysets import ObjectChangeQuerySet
@ -103,6 +105,17 @@ class ObjectChange(models.Model):
self.user_name self.user_name
) )
def clean(self):
super().clean()
# Validate the assigned object type
if self.changed_object_type not in ContentType.objects.with_feature('change_logging'):
raise ValidationError(
_("Change logging is not supported for this object type ({type}).").format(
type=self.changed_object_type
)
)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
# Record the user's name and the object's representation as static strings # Record the user's name and the object's representation as static strings

View File

@ -559,6 +559,15 @@ class ImageAttachment(ChangeLoggedModel):
filename = self.image.name.rsplit('/', 1)[-1] filename = self.image.name.rsplit('/', 1)[-1]
return filename.split('_', 2)[2] return filename.split('_', 2)[2]
def clean(self):
super().clean()
# Validate the assigned object type
if self.content_type not in ContentType.objects.with_feature('image_attachments'):
raise ValidationError(
_("Image attachments cannot be assigned to this object type ({type}).").format(type=self.content_type)
)
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
_name = self.image.name _name = self.image.name
@ -643,9 +652,8 @@ class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ExportTemplat
def clean(self): def clean(self):
super().clean() super().clean()
# Prevent the creation of journal entries on unsupported models # Validate the assigned object type
permitted_types = ContentType.objects.with_feature('journaling') if self.assigned_object_type not in ContentType.objects.with_feature('journaling'):
if self.assigned_object_type not in permitted_types:
raise ValidationError( raise ValidationError(
_("Journaling is not supported for this object type ({type}).").format(type=self.assigned_object_type) _("Journaling is not supported for this object type ({type}).").format(type=self.assigned_object_type)
) )
@ -694,6 +702,15 @@ class Bookmark(models.Model):
return str(self.object) return str(self.object)
return super().__str__() return super().__str__()
def clean(self):
super().clean()
# Validate the assigned object type
if self.object_type not in ContentType.objects.with_feature('bookmarks'):
raise ValidationError(
_("Bookmarks cannot be assigned to this object type ({type}).").format(type=self.object_type)
)
class ConfigRevision(models.Model): class ConfigRevision(models.Model):
""" """

View File

@ -1,8 +1,10 @@
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from core.models import ContentType
from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel
from netbox.models.features import TagsMixin from netbox.models.features import TagsMixin
from tenancy.choices import * from tenancy.choices import *
@ -156,6 +158,15 @@ class ContactAssignment(ChangeLoggedModel, TagsMixin):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('tenancy:contact', args=[self.contact.pk]) return reverse('tenancy:contact', args=[self.contact.pk])
def clean(self):
super().clean()
# Validate the assigned object type
if self.content_type not in ContentType.objects.with_feature('contacts'):
raise ValidationError(
_("Contacts cannot be assigned to this object type ({type}).").format(type=self.content_type)
)
def to_objectchange(self, action): def to_objectchange(self, action):
objectchange = super().to_objectchange(action) objectchange = super().to_objectchange(action)
objectchange.related_object = self.object objectchange.related_object = self.object