diff --git a/pyramid_ldap/__init__.py b/pyramid_ldap/__init__.py index 95e4a3c..e7ca092 100644 --- a/pyramid_ldap/__init__.py +++ b/pyramid_ldap/__init__.py @@ -16,9 +16,9 @@ class ldap(object): from ldap.filter import escape_filter_chars from pyramid.exceptions import ConfigurationError -from pyramid.compat import ( - iteritems_, - text_, + +from six import ( + ensure_text, iteritems ) @@ -70,9 +70,9 @@ def query_cache(self, cache_key): def execute(self, conn, **kw): cache_key = ( - text_(self.base_dn % kw, 'utf-8'), + ensure_text(self.base_dn % kw, 'utf-8'), self.scope, - text_(self.filter_tmpl % kw, 'utf-8') + ensure_text(self.filter_tmpl % kw, 'utf-8') ) logger.debug('searching for %r' % (cache_key,)) @@ -129,13 +129,13 @@ def authenticate(self, login_unsafe, password_unsafe): :exc:`pyramid.exceptions.ConfiguratorError`. In pyramid_ldap <= version 0.2, authenticating with a login that - included the domain (e.g. CORP\exampleuser) would raise - ``ldap.FILTER_ERROR`` because the ``\`` led to an invalid search + included the domain (e.g., ``CORP\\exampleuser``) would raise + ``ldap.FILTER_ERROR`` because the ``\\`` led to an invalid search string. In pyramid_ldap >= 0.3, the string is escaped so it will not raise an exception. However, it will likely fail to authenticate user ``CORP\\5cexampleuser`` (the escaped form of login - "CORP\exampleuser"). Applications using pyramid_ldap can preprocess the - logins to make sure they are formatted correctly for their + ``CORP\\exampleuser``). Applications using pyramid_ldap can preprocess + the logins to make sure they are formatted correctly for their ``ldap.login_filter_tpl`` setting. """ if password_unsafe == '': @@ -301,7 +301,7 @@ def get_connector(request): registry = request.registry return Connector(registry, manager) - config.set_request_property(get_connector, 'ldap_connector', reify=True) + config.add_request_method(get_connector, 'ldap_connector', reify=True) intr = config.introspectable( 'pyramid_ldap setup', @@ -364,12 +364,12 @@ def __init__(self, encoding='utf-8'): def decode(self, value): """ - Uses `pyramid.compat.text_` to convert values to `unicode` in python 2 + Uses `six.ensure_text` to convert values to `unicode` in python 2 and `str` in python 3. """ try: if isinstance(value, (bytes, str)): - value = text_(value, encoding=self.encoding) + value = ensure_text(value, encoding=self.encoding) elif isinstance(value, list): value = self._decode_list(value) elif isinstance(value, tuple): @@ -390,7 +390,7 @@ def _decode_dict(self, value): # for search results. decoded = self.ldap.cidict.cidict() - for k, v in iteritems_(value): + for k, v in iteritems(value): decoded[self.decode(k)] = self.decode(v) return decoded diff --git a/pyramid_ldap/tests.py b/pyramid_ldap/tests.py index 4987b87..3e7677b 100644 --- a/pyramid_ldap/tests.py +++ b/pyramid_ldap/tests.py @@ -2,10 +2,10 @@ import unittest import sys -from pyramid.compat import ( - text_type, - text_, - ) +from six import ( + ensure_text, text_type +) + from pyramid import testing from pyramid.exceptions import ConfigurationError @@ -31,31 +31,32 @@ def _callFUT(self, val): def test_decode_str(self): result = self._callFUT('abc') self.assertEqual(type(result), text_type) - self.assertEqual(result, text_('abc')) + self.assertEqual(result, ensure_text('abc')) def test_decode_list(self): result = self._callFUT(['abc', 'def']) self.assertEqual(type(result), list) - self.assertEqual(result[0], text_('abc')) - self.assertEqual(result[1], text_('def')) + self.assertEqual(result[0], ensure_text('abc')) + self.assertEqual(result[1], ensure_text('def')) def test_decode_tuple(self): result = self._callFUT(('abc', 'def')) self.assertEqual(type(result), tuple) - self.assertEqual(result[0], text_('abc')) - self.assertEqual(result[1], text_('def')) + self.assertEqual(result[0], ensure_text('abc')) + self.assertEqual(result[1], ensure_text('def')) def test_decode_dict(self): import ldap result = self._callFUT({'abc': 'def'}) self.assertTrue(isinstance(result, ldap.cidict.cidict)) - self.assertEqual(result[text_('abc')], text_('def')) + self.assertEqual(result[ensure_text('abc')], ensure_text('def')) def test_decode_nested(self): import ldap result = self._callFUT({'abc': ['def', 'jkl']}) self.assertTrue(isinstance(result, ldap.cidict.cidict)) - self.assertEqual(result[text_('abc')], [text_('def'), text_('jkl')]) + self.assertEqual(result[ensure_text('abc')], + [ensure_text('def'), ensure_text('jkl')]) def test_undecodeable(self): uid = b'\xdd\xafw:PuUO\x8a#\x17\xaa\xc2\xc7\x8e\xf6' @@ -109,7 +110,7 @@ def test_it_defaults(self): self.assertEqual(config.prop_name, 'ldap_connector') self.assertEqual(config.prop_reify, True) request = testing.DummyRequest() - self.assertEqual(config.prop(request).__class__, Connector) + self.assertEqual(config.prop_callable(request).__class__, Connector) class Test_ldap_set_groups_query(unittest.TestCase): @@ -203,7 +204,7 @@ def test_authenticate_escapes_login(self): registry = Dummy() registry.ldap_login_query = DummySearch([('a', 'b')]) inst = self._makeOne(registry, manager) - inst.authenticate('BAD\login', 'password') + inst.authenticate('BAD\\login', 'password') expected_escaped_login = 'BAD\\5clogin' self.assertEqual(registry.ldap_login_query.kw['login'], expected_escaped_login) @@ -213,7 +214,7 @@ def test_authenticate_escapes_password(self): registry = Dummy() registry.ldap_login_query = DummySearch([('a', 'b')]) inst = self._makeOne(registry, manager) - inst.authenticate('login', 'bad\*()password') + inst.authenticate('login', 'bad\\*()password') expected_escaped_password = r'bad\5c\2a\28\29password' self.assertEqual(registry.ldap_login_query.kw['password'], expected_escaped_password) @@ -304,10 +305,12 @@ def __init__(self): def add_directive(self, name, fn): self.directives.append(name) - def set_request_property(self, prop, name, reify=False): - self.prop_reify = reify + def add_request_method(self, callable=None, name=None, property=False, + reify=False): + self.prop_callable = callable self.prop_name = name - self.prop = prop + self.prop_property = property + self.prop_reify = reify def action(self, discriminator, callable, introspectables=()): if callable: diff --git a/setup.py b/setup.py index 328b024..8f44c85 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ requires = [ 'pyramid>=1.3', - 'six', # required by `ldappool` but not in their requirements file + 'six', # required by `ldappool` but not in their requirements file ] if 'READTHEDOCS' not in os.environ: # hail mary for readthedocs diff --git a/tox.ini b/tox.ini index 6272c00..acba20c 100644 --- a/tox.ini +++ b/tox.ini @@ -40,7 +40,7 @@ setenv = [testenv:py3-cover] basepython = python3.6 commands = - pip install -q pyramid[testing] + pip install -q pyramid_ldap[testing] coverage run --source=pyramid_ldap {envbindir}/nosetests coverage xml -o coverage-py3.xml setenv =