Check for multi level tlds

Previously we only checked for the last label of a TLD
which does not work for `co.uk` or custom internal
TLDs that deployers may use

Change-Id: I9bc8d3ac8eb48078723a96d87e023d58b933b183
This commit is contained in:
Graham Hayes 2017-10-12 15:49:43 +01:00
parent a9d882e8c4
commit 5d9f35fea6
No known key found for this signature in database
GPG Key ID: 1B263DC59F4AEFD5
6 changed files with 7241 additions and 7 deletions

File diff suppressed because it is too large Load Diff

View File

@ -275,12 +275,17 @@ class Service(service.RPCService, service.Service):
raise exceptions.InvalidZoneName('More than one label is ' raise exceptions.InvalidZoneName('More than one label is '
'required') 'required')
# Check the TLD for validity if there are entries in the database tlds = self.storage.find_tlds(context)
if self.storage.find_tlds({}): if tlds:
LOG.info(_LI("Checking for TLDs")) LOG.debug("Checking if %s has a valid TLD", zone_name)
try: allowed = False
self.storage.find_tld(context, {'name': zone_labels[-1]}) for i in range(-len(zone_labels), 0):
except exceptions.TldNotFound: last_i_labels = zone_labels[i:]
LOG.debug("Checking %s against the TLD list", last_i_labels)
if ".".join(last_i_labels) in tlds:
allowed = True
break
if not allowed:
raise exceptions.InvalidZoneName('Invalid TLD') raise exceptions.InvalidZoneName('Invalid TLD')
# Now check that the zone name is not the same as a TLD # Now check that the zone name is not the same as a TLD
@ -290,7 +295,7 @@ class Service(service.RPCService, service.Service):
context, context,
{'name': stripped_zone_name}) {'name': stripped_zone_name})
except exceptions.TldNotFound: except exceptions.TldNotFound:
pass LOG.debug("%s has a valid TLD", zone_name)
else: else:
raise exceptions.InvalidZoneName( raise exceptions.InvalidZoneName(
'Zone name cannot be the same as a TLD') 'Zone name cannot be the same as a TLD')

View File

@ -59,6 +59,8 @@ class TLDCommands(base.Commands):
def __init__(self): def __init__(self):
super(TLDCommands, self).__init__() super(TLDCommands, self).__init__()
def _startup(self):
rpc.init(cfg.CONF) rpc.init(cfg.CONF)
self.central_api = central_rpcapi.CentralAPI() self.central_api = central_rpcapi.CentralAPI()
@ -108,6 +110,7 @@ class TLDCommands(base.Commands):
help="delimiter between fields in the input file", help="delimiter between fields in the input file",
default=',', type=str) default=',', type=str)
def from_file(self, input_file=None, delimiter=None): def from_file(self, input_file=None, delimiter=None):
self._startup()
input_file = str(input_file) if input_file is not None else None input_file = str(input_file) if input_file is not None else None
if not os.path.exists(input_file): if not os.path.exists(input_file):

View File

@ -42,3 +42,6 @@ class Tld(base.DictObjectMixin, base.PersistentObjectMixin,
class TldList(base.ListObjectMixin, base.DesignateObject): class TldList(base.ListObjectMixin, base.DesignateObject):
LIST_ITEM_TYPE = Tld LIST_ITEM_TYPE = Tld
def __contains__(self, key):
return bool(list(filter(lambda tld: tld.name == key, self.objects)))

View File

@ -515,6 +515,12 @@ class CentralZoneTestCase(CentralBasic):
if d['name'] not in ('org',): if d['name'] not in ('org',):
raise exceptions.TldNotFound raise exceptions.TldNotFound
def storage_find_tlds(c):
return objects.TldList.from_list(
[objects.Tld.from_dict({'name': 'org'})]
)
self.service.storage.find_tlds = storage_find_tlds
self.service.storage.find_tld = storage_find_tld self.service.storage.find_tld = storage_find_tld
def test__is_valid_zone_name_valid(self): def test__is_valid_zone_name_valid(self):

View File

@ -0,0 +1,8 @@
---
fixes:
- |
Check for multi level tlds
Previously we only checked for the last label of a TLD
which does not work for `co.uk` or custom internal
TLDs that deployers may use