Skip to content

Commit

Permalink
Fix LDAPServerFieldURI number in domain
Browse files Browse the repository at this point in the history
- API error if LDAPServerFieldURI contains a number in the top level domain
- Add custom regex in LDAPServerFieldURI class that is passed to django
  URLValidator
- The custom regex allows for numbers to be present in the top level domain
- Unit tests check that valid URIs pass through URLValidator, and that
  invalid URIs raise the correct exception
- Related to issue ansible#3646
  • Loading branch information
Seth Foster committed Sep 20, 2019
1 parent 154cda7 commit 9e6e25c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
3 changes: 3 additions & 0 deletions awx/conf/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,14 @@ class URLField(CharField):

def __init__(self, **kwargs):
schemes = kwargs.pop('schemes', None)
regex = kwargs.pop('regex', None)
self.allow_plain_hostname = kwargs.pop('allow_plain_hostname', False)
super(URLField, self).__init__(**kwargs)
validator_kwargs = dict(message=_('Enter a valid URL'))
if schemes is not None:
validator_kwargs['schemes'] = schemes
if regex is not None:
validator_kwargs['regex'] = regex
self.validators.append(URLValidator(**validator_kwargs))

def to_representation(self, value):
Expand Down
23 changes: 23 additions & 0 deletions awx/sso/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# Django
from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django.core.validators import URLValidator, _lazy_re_compile

# Django Auth LDAP
import django_auth_ldap.config
Expand Down Expand Up @@ -233,12 +234,34 @@ def _default_from_required_settings(self):

class LDAPServerURIField(fields.URLField):

tld_re = (
r'\.' # dot
r'(?!-)' # can't start with a dash
r'(?:[a-z' + URLValidator.ul + r'0-9' + '-]{2,63}' # domain label, this line was changed from the original URLValidator
r'|xn--[a-z0-9]{1,59})' # or punycode label
r'(?<!-)' # can't end with a dash
r'\.?' # may have a trailing dot
)

host_re = '(' + URLValidator.hostname_re + URLValidator.domain_re + tld_re + '|localhost)'

regex = _lazy_re_compile(
r'^(?:[a-z0-9\.\-\+]*)://' # scheme is validated separately
r'(?:[^\s:@/]+(?::[^\s:@/]*)?@)?' # user:pass authentication
r'(?:' + URLValidator.ipv4_re + '|' + URLValidator.ipv6_re + '|' + host_re + ')'
r'(?::\d{2,5})?' # port
r'(?:[/?#][^\s]*)?' # resource path
r'\Z', re.IGNORECASE)

def __init__(self, **kwargs):

kwargs.setdefault('schemes', ('ldap', 'ldaps'))
kwargs.setdefault('allow_plain_hostname', True)
kwargs.setdefault('regex', LDAPServerURIField.regex)
super(LDAPServerURIField, self).__init__(**kwargs)

def run_validators(self, value):

for url in filter(None, re.split(r'[, ]', (value or ''))):
super(LDAPServerURIField, self).run_validators(url)
return value
Expand Down
18 changes: 18 additions & 0 deletions awx/sso/tests/unit/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
SAMLOrgAttrField,
SAMLTeamAttrField,
LDAPGroupTypeParamsField,
LDAPServerURIField
)


Expand Down Expand Up @@ -114,3 +115,20 @@ def test_internal_value_invalid(self, group_type, data, expected):
with pytest.raises(ValidationError) as e:
field.to_internal_value(data)
assert e.value.detail == expected


class TestLDAPServerURIField():

@pytest.mark.parametrize("ldap_uri, exception, expected", [
(r'ldap://servername.com:444', None, r'ldap://servername.com:444'),
(r'ldap://servername.so3:444', None, r'ldap://servername.so3:444'),
(r'ldaps://servername3.s300:344', None, r'ldaps://servername3.s300:344'),
(r'ldap://servername.-so3:444', ValidationError, None),
])
def test_run_validators_valid(self, ldap_uri, exception, expected):
field = LDAPServerURIField()
if exception is None:
assert field.run_validators(ldap_uri) == expected
else:
with pytest.raises(exception):
field.run_validators(ldap_uri)

0 comments on commit 9e6e25c

Please sign in to comment.