1
0
mirror of https://github.com/github/octodns.git synced 2024-05-11 05:55:00 +00:00

Validations to ensure Record.name and Zone.name have no whitespace

This commit is contained in:
Ross McFarland
2023-05-19 09:57:56 -07:00
parent eca3e108e3
commit cfa7abaee5
6 changed files with 39 additions and 1 deletions

View File

@@ -1,3 +1,7 @@
## v1.0.0.rc2 - 2023-??-?? -
* Record and Zone validation now ensures there's no whitespace in names
## v1.0.0.rc0 - 2023-05-16 - First of the ones
#### Noteworthy changes

View File

@@ -41,6 +41,10 @@ class Record(EqualityTupleMixin):
# convert the error into a reason
reasons.append(str(e))
name = str(name)
if ' ' in name or '\t' in name:
reasons.append('invalid record, whitespace is not allowed')
fqdn = f'{name}.{zone.name}' if name else zone.name
try:
_type = data['type']

View File

@@ -13,7 +13,7 @@ class ValidationError(RecordException):
@classmethod
def build_message(cls, fqdn, reasons):
reasons = '\n - '.join(reasons)
return f'Invalid record {idna_decode(fqdn)}\n - {reasons}'
return f'Invalid record "{idna_decode(fqdn)}"\n - {reasons}'
def __init__(self, fqdn, reasons):
super().__init__(self.build_message(fqdn, reasons))

View File

@@ -28,6 +28,9 @@ class Zone(object):
def __init__(self, name, sub_zones):
if not name[-1] == '.':
raise Exception(f'Invalid zone name {name}, missing ending dot')
elif ' ' in name or '\t' in name:
raise Exception(f'Invalid zone name {name}, whitespace not allowed')
# internally everything is idna
self.name = idna_encode(str(name)) if name else name
# we'll keep a decoded version around for logs and errors

View File

@@ -398,6 +398,28 @@ class TestRecordValidation(TestCase):
zone = Zone('unit.tests.', [])
def test_base(self):
# no spaces
for name in (
' ',
' leading',
'trailing ',
'in the middle',
'\t',
'\tleading',
'trailing\t',
'in\tthe\tmiddle',
):
with self.assertRaises(ValidationError) as ctx:
Record.new(
self.zone,
name,
{'ttl': 300, 'type': 'A', 'value': '1.2.3.4'},
)
reason = ctx.exception.reasons[0]
self.assertEqual(
'invalid record, whitespace is not allowed', reason
)
# name = '@'
with self.assertRaises(ValidationError) as ctx:
name = '@'

View File

@@ -186,6 +186,11 @@ class TestZone(TestCase):
Zone('not.allowed', [])
self.assertTrue('missing ending dot' in str(ctx.exception))
def test_whitespace(self):
with self.assertRaises(Exception) as ctx:
Zone('space not allowed.', [])
self.assertTrue('whitespace not allowed' in str(ctx.exception))
def test_sub_zones(self):
# NS for exactly the sub is allowed