Url validation (#6045)

* Add new setting INVENTREE_STRICT_URLS

- Enforce schema prefix to URL validation
- Default  = True

* Implement new validation

* Also implement for DRF serializers
This commit is contained in:
Oliver 2023-12-06 17:17:15 +11:00 committed by GitHub
parent c778c067f5
commit 238902e4f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 0 deletions

View File

@ -11,6 +11,7 @@ from djmoney.forms.fields import MoneyField
from djmoney.models.fields import MoneyField as ModelMoneyField
from djmoney.models.validators import MinMoneyValidator
from rest_framework.fields import URLField as RestURLField
from rest_framework.fields import empty
import InvenTree.helpers
@ -29,6 +30,20 @@ class InvenTreeRestURLField(RestURLField):
super().__init__(**kwargs)
self.validators[-1].schemes = allowable_url_schemes()
def run_validation(self, data=empty):
"""Override default validation behaviour for this field type"""
import common.models
strict_urls = common.models.InvenTreeSetting.get_setting('INVENTREE_STRICT_URLS', True, cache=False)
if not strict_urls and data is not empty:
if '://' not in data:
# Validate as if there were a schema provided
data = 'http://' + data
return super().run_validation(data=data)
class InvenTreeURLField(models.URLField):
"""Custom URL field which has custom scheme validators."""

View File

@ -203,6 +203,37 @@ class ValidatorTest(TestCase):
with self.assertRaises(django_exceptions.ValidationError):
validate_overage("aaaa")
def test_url_validation(self):
"""Test for AllowedURLValidator"""
from common.models import InvenTreeSetting
from part.models import Part, PartCategory
# Without strict URL validation
InvenTreeSetting.set_setting('INVENTREE_STRICT_URLS', False, None)
n = Part.objects.count()
cat = PartCategory.objects.first()
# Should pass, even without a schema
Part.objects.create(
name=f'Part {n}',
description='Link without schema',
category=cat,
link='www.google.com',
)
# With strict URL validation
InvenTreeSetting.set_setting('INVENTREE_STRICT_URLS', True, None)
with self.assertRaises(ValidationError):
Part.objects.create(
name=f'Part {n + 1}',
description='Link without schema',
category=cat,
link='www.google.com',
)
class FormatTest(TestCase):
"""Unit tests for custom string formatting functionality"""

View File

@ -60,9 +60,23 @@ def allowable_url_schemes():
class AllowedURLValidator(validators.URLValidator):
"""Custom URL validator to allow for custom schemes."""
def __call__(self, value):
"""Validate the URL."""
import common.models
self.schemes = allowable_url_schemes()
# Determine if 'strict' URL validation is required (i.e. if the URL must have a schema prefix)
strict_urls = common.models.InvenTreeSetting.get_setting('INVENTREE_STRICT_URLS', True, cache=False)
if not strict_urls:
# Allow URLs which do not have a provided schema
if '://' not in value:
# Validate as if it were http
value = 'http://' + value
super().__call__(value)

View File

@ -1175,6 +1175,13 @@ class InvenTreeSetting(BaseInvenTreeSetting):
'default': '',
},
'INVENTREE_STRICT_URLS': {
'name': _('Strict URL Validation'),
'description': _('Require schema specification when validating URLs'),
'validator': bool,
'default': True,
},
'INVENTREE_REQUIRE_CONFIRM': {
'name': _('Require confirm'),
'description': _('Require explicit user confirmation for certain action.'),

View File

@ -24,6 +24,7 @@
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE" icon="fa-server" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DOWNLOAD_FROM_URL_USER_AGENT" icon="fa-server" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_REQUIRE_CONFIRM" icon="fa-check" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_STRICT_URLS" icon="fa-link" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_TREE_DEPTH" icon="fa-sitemap" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_BACKUP_ENABLE" icon="fa-hdd" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_BACKUP_DAYS" icon="fa-calendar-alt" %}