Просмотр исходного кода

Merge pull request #20625 from netbox-community/20498-url-custom-field-validation-regex

Fixes #20498: Apply validation regex to URL custom fields
bctiemann 3 месяцев назад
Родитель
Сommit
0b97df0984
2 измененных файлов с 38 добавлено и 0 удалено
  1. 16 0
      netbox/extras/models/customfields.py
  2. 22 0
      netbox/extras/tests/test_customfields.py

+ 16 - 0
netbox/extras/models/customfields.py

@@ -535,6 +535,15 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
         # URL
         elif self.type == CustomFieldTypeChoices.TYPE_URL:
             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
         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):
                     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
             elif self.type == CustomFieldTypeChoices.TYPE_INTEGER:
                 if type(value) is not int:

+ 22 - 0
netbox/extras/tests/test_customfields.py

@@ -1300,6 +1300,28 @@ class CustomFieldAPITest(APITestCase):
         response = self.client.patch(url, data, format='json', **self.header)
         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):
         # Create a unique custom field
         cf_text = CustomField.objects.get(name='text_field')