Project

General

Profile

0001-ldap-use_controls-defaults-to-False-if-python-ldap-3.patch

Loïc Dachary, 18 March 2021 02:59 PM

Download (4.03 KB)

View differences:

Subject: [PATCH] ldap: use_controls defaults to False if python-ldap < 3.3.1
 (#52190)

Controls prior to python-ldap 3.3.1 are partially implemented because
exceptions do not report information about the controls that may have
triggered the error. To avoid an unexpected behavior, the default for
use_controls is modified to be False if python-ldap 3.3.1.

Tests are added for python-ldap 3.1.0 because it is the version
available in Debian GNU/Linux buster & bullseye.

Discussion: https://listes.entrouvert.com/arc/authentic/2021-03/msg00005.html
Fixes: https://dev.entrouvert.org/issues/52190

License: MIT
 src/authentic2/backends/ldap_backend.py | 15 ++++++++++++++-
 tests/test_ldap.py                      | 10 ++++++++++
 tox.ini                                 |  2 ++
 3 files changed, 26 insertions(+), 1 deletion(-)
src/authentic2/backends/ldap_backend.py
32 32
    ldap = None
33 33
    PYTHON_LDAP3 = None
34 34
import logging
35
from packaging.version import parse as version_parse
35 36
import random
36 37
import base64
37 38
import os
......
97 98

  
98 99

  
99 100
if PYTHON_LDAP3 is True:
101

  
102
    def ldap_implements_controls():
103
        #
104
        # prior to 3.3.1 controls are partially implemented: exceptions do not include
105
        # controls information
106
        #
107
        return version_parse(ldap.__version__) >= version_parse('3.3.1')
108

  
100 109
    class LDAPObject(NativeLDAPObject):
101 110
        def __init__(self, uri, trace_level=0, trace_file=None,
102 111
                     trace_stack_limit=5, bytes_mode=False,
......
149 158
            return resp_type, resp_data, resp_msgid, decoded_resp_ctrls, resp_name, resp_value
150 159

  
151 160
elif PYTHON_LDAP3 is False:
161

  
162
    def ldap_implements_controls():
163
        return False
164

  
152 165
    class LDAPObject(NativeLDAPObject):
153 166
        def simple_bind_s(self, who='', cred='', serverctrls=None, clientctrls=None):
154 167
            who = force_bytes(who)
......
547 560
        # mapping from LDAP attributes to User attributes
548 561
        'user_attributes': [],
549 562
        # https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#ldap-controls
550
        'use_controls': True,
563
        'use_controls': ldap_implements_controls(),
551 564
    }
552 565
    _REQUIRED = ('url', 'basedn')
553 566
    _TO_ITERABLE = ('url', 'groupsu', 'groupstaff', 'groupactive')
tests/test_ldap.py
80 80

  
81 81
@pytest.fixture
82 82
def slapd_ppolicy():
83
    if ldap_backend.ldap_implements_controls() is False:
84
        pytest.skip("ldap does not implement controls")
83 85
    with create_slapd() as slapd:
84 86
        conn = slapd.get_connection_admin()
85 87
        assert conn.protocol_version == ldap.VERSION3
......
1474 1476
            }
1475 1477
        ]
1476 1478
    }
1479

  
1480

  
1481
def test_use_controls():
1482
    from packaging.version import parse as version_parse
1483
    if version_parse(ldap.__version__) >= version_parse('3.3.1'):
1484
        assert ldap_backend.LDAPBackend._DEFAULTS['use_controls'] is True
1485
    else:
1486
        assert ldap_backend.LDAPBackend._DEFAULTS['use_controls'] is False
tox.ini
18 18
  authentic-py3-dj111-drf34
19 19
  authentic-py3-dj111-drf39
20 20
  authentic-py3-dj22-drf39
21
  authentic-py3-dj22-drf39-pythonldap310
21 22

  
22 23
[testenv]
23 24
setenv =
......
77 78
  py3: django-filter<2.3
78 79
  drf34: djangorestframework>=3.4,<3.4.1
79 80
  drf39: djangorestframework>=3.9.2,<3.10
81
  pythonldap310: python-ldap==3.1.0
80 82
usedevelop = True
81 83
commands =
82 84
  py2: ./getlasso.sh
83
-