mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-09 01:49:35 -06:00
Fixes #20498: Apply validation regex to URL custom fields
The validation_regex field was not being enforced for URL type custom fields. This fix adds regex validation in two places: 1. to_form_field() - Applies regex validator to form fields (UI validation) 2. validate() - Applies regex check in model validation (API/programmatic) Note: The original issue reported UI validation only, but this fix also adds API validation for consistency with text field behavior and to ensure data integrity across all entry points.
This commit is contained in:
parent
e251ea10b5
commit
6747c82a1a
@ -535,6 +535,15 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
|||||||
# URL
|
# URL
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_URL:
|
elif self.type == CustomFieldTypeChoices.TYPE_URL:
|
||||||
field = LaxURLField(assume_scheme='https', required=required, initial=initial)
|
field = LaxURLField(assume_scheme='https', required=required, initial=initial)
|
||||||
|
if self.validation_regex:
|
||||||
|
field.validators = [
|
||||||
|
RegexValidator(
|
||||||
|
regex=self.validation_regex,
|
||||||
|
message=mark_safe(_("Values must match this regex: <code>{regex}</code>").format(
|
||||||
|
regex=escape(self.validation_regex)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# JSON
|
# JSON
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_JSON:
|
elif self.type == CustomFieldTypeChoices.TYPE_JSON:
|
||||||
@ -684,6 +693,13 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
|||||||
if self.validation_regex and not re.match(self.validation_regex, value):
|
if self.validation_regex and not re.match(self.validation_regex, value):
|
||||||
raise ValidationError(_("Value must match regex '{regex}'").format(regex=self.validation_regex))
|
raise ValidationError(_("Value must match regex '{regex}'").format(regex=self.validation_regex))
|
||||||
|
|
||||||
|
# Validate URL field
|
||||||
|
elif self.type == CustomFieldTypeChoices.TYPE_URL:
|
||||||
|
if type(value) is not str:
|
||||||
|
raise ValidationError(_("Value must be a string."))
|
||||||
|
if self.validation_regex and not re.match(self.validation_regex, value):
|
||||||
|
raise ValidationError(_("Value must match regex '{regex}'").format(regex=self.validation_regex))
|
||||||
|
|
||||||
# Validate integer
|
# Validate integer
|
||||||
elif self.type == CustomFieldTypeChoices.TYPE_INTEGER:
|
elif self.type == CustomFieldTypeChoices.TYPE_INTEGER:
|
||||||
if type(value) is not int:
|
if type(value) is not int:
|
||||||
|
|||||||
@ -1300,6 +1300,28 @@ class CustomFieldAPITest(APITestCase):
|
|||||||
response = self.client.patch(url, data, format='json', **self.header)
|
response = self.client.patch(url, data, format='json', **self.header)
|
||||||
self.assertHttpStatus(response, status.HTTP_200_OK)
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
def test_url_regex_validation(self):
|
||||||
|
"""
|
||||||
|
Test that validation_regex is applied to URL custom fields (fixes #20498).
|
||||||
|
"""
|
||||||
|
site2 = Site.objects.get(name='Site 2')
|
||||||
|
url = reverse('dcim-api:site-detail', kwargs={'pk': site2.pk})
|
||||||
|
self.add_permissions('dcim.change_site')
|
||||||
|
|
||||||
|
cf_url = CustomField.objects.get(name='url_field')
|
||||||
|
cf_url.validation_regex = r'^https://' # Require HTTPS
|
||||||
|
cf_url.save()
|
||||||
|
|
||||||
|
# Test invalid URL (http instead of https)
|
||||||
|
data = {'custom_fields': {'url_field': 'http://example.com'}}
|
||||||
|
response = self.client.patch(url, data, format='json', **self.header)
|
||||||
|
self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# Test valid URL (https)
|
||||||
|
data = {'custom_fields': {'url_field': 'https://example.com'}}
|
||||||
|
response = self.client.patch(url, data, format='json', **self.header)
|
||||||
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
||||||
|
|
||||||
def test_uniqueness_validation(self):
|
def test_uniqueness_validation(self):
|
||||||
# Create a unique custom field
|
# Create a unique custom field
|
||||||
cf_text = CustomField.objects.get(name='text_field')
|
cf_text = CustomField.objects.get(name='text_field')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user