Projet

Général

Profil

0001-WIP-ldap_backend-fix-encoding-errors-during-user-syn.patch

Paul Marillonnet, 27 octobre 2017 17:58

Télécharger (5,8 ko)

Voir les différences:

Subject: [PATCH] WIP ldap_backend : fix encoding errors during user
 synchronization (#19168)

 src/authentic2/backends/ldap_backend.py | 20 +++++++++++++++++++
 tests/test_ldap.py                      | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
src/authentic2/backends/ldap_backend.py
319 319
        # First get our configuration into a standard format
320 320
        for block in blocks:
321 321
            cls.update_default(block)
322
            # python-ldap needs UTF-8 encoded strings
323
            if isinstance(block.get('base_dn'), unicode):
324
                block['base_dn'] = block['base_dn'].encode('utf-8')
322 325
        log.debug('got config %r', blocks)
323 326
        return blocks
324 327

  
......
349 352
        utf8_username = smart_bytes(username)
350 353
        utf8_password = smart_bytes(password)
351 354

  
355
        # python-ldap needs UTF-8 encoded strings
356
        for dn_subelement in ('basedn', 'user_basedn', 'user_dn_template'):
357
            if isinstance(block.get(dn_subelement), unicode):
358
                block[dn_sublement] = block[dn_subelement].encode('utf-8')
359

  
352 360
        for conn in self.get_connections(block):
353 361
            authz_ids = []
354 362
            user_basedn = block.get('user_basedn') or block['basedn']
......
522 530
        '''Retrieve group DNs from the LDAP by attributes (memberOf) or by
523 531
           filter.
524 532
        '''
533
        # python-ldap needs UTF-8 encoded strings
534
        if isinstance(block.get('group_base_dn'), unicode):
535
            block['group_base_dn'] = block['group_base_dn'].encode('utf-8')
525 536
        group_base_dn = block.get('group_basedn', block['basedn'])
526 537
        member_of_attribute = block['member_of_attribute']
527 538
        group_filter = block['group_filter']
......
840 851
            if conn is None:
841 852
                logger.warning(u'unable to synchronize with LDAP servers %r', block['url'])
842 853
                continue
854
            # python-ldap needs UTF-8 encoded strings.
855
            if isinstance(block.get('user_basedn'), unicode):
856
                block['user_basedn'] = block['user_basedn'].encode('utf-8')
843 857
            user_basedn = block.get('user_basedn') or block['basedn']
844 858
            user_filter = block['sync_ldap_users_filter'] or block['user_filter']
845 859
            user_filter = user_filter.replace('%s', '*')
......
950 964
                    auth = handler_class(*sasl_params)
951 965
                    conn.sasl_interactive_bind_s(who, auth)
952 966
                elif block['binddn'] and block['bindpw']:
967
                    # python-ldap needs UTF-8 encoded strings
968
                    if isinstance(block.get('binddn'), unicode):
969
                        block['binddn'] = block['binddn'].encode('utf-8')
953 970
                    conn.bind_s(block['binddn'], block['bindpw'])
954 971
                yield conn
955 972
            except ldap.INVALID_CREDENTIALS:
......
1072 1089
                            results = conn.search_s(dn, ldap.SCOPE_BASE)
1073 1090
                        else:
1074 1091
                            ldap_filter = self.external_id_to_filter(external_id, external_id_tuple)
1092
                            # python-ldap needs UTF-8 encoded strings
1093
                            if isinstance(block.get('basedn'), unicode):
1094
                                block['basedn'] = block['basedn'].encode('utf-8')
1075 1095
                            results = conn.search_s(block['basedn'],
1076 1096
                                                    ldap.SCOPE_SUBTREE, ldap_filter)
1077 1097
                            if not results:
tests/test_ldap.py
23 23
DN = 'cn=%s,o=orga' % escape_dn_chars(CN)
24 24
PASS = 'passé'
25 25

  
26
USERNAME_ACCENTS = u'étienne.michü'
27
UID_ACCENTS = 'étienne.michü'
28
CN_ACCENTS = 'Étienne Michü'
29
DN_ACCENTS = 'cn=%s,o=orga' % (escape_dn_chars(CN_ACCENTS))
30

  
26 31

  
27 32
@pytest.fixture
28 33
def slapd(request):
......
41 46
member: {dn}
42 47

  
43 48
'''.format(dn=DN, uid=UID, password=PASS))
49
    result = slapd.add_ldif('''dn: {dn}
50
objectClass: inetOrgPerson
51
userPassword: {password}
52
uid: {uid}
53
cn: Étienne Michü
54
sn: Michü
55
gn: Étienne
56
mail: emichu@example.net
57

  
58
'''.format(dn=DN_ACCENTS, uid=UID_ACCENTS, password=PASS))
44 59
    for i in range(100):
45 60
        slapd.add_ldif('''dn: uid=michu{i},o=orga
46 61
objectClass: inetOrgPerson
......
101 116

  
102 117

  
103 118
@pytest.mark.django_db
119
def test_accents_in_dn(slapd, settings, client):
120
    settings.LDAP_AUTH_SETTINGS = [{
121
        'url': [slapd.ldap_url],
122
        'basedn': 'o=orga',
123
        'use_tls': False,
124
    }]
125
    result = client.post('/login/', {'login-password-submit': '1',
126
                                     'username': USERNAME_ACCENTS,
127
                                     'password': PASS}, follow=True)
128
    assert result.status_code == 200
129
    assert u'Étienne Michü' in unicode(str(result), 'utf-8')
130
    User = get_user_model()
131
    assert User.objects.count() == 1
132
    user = User.objects.get()
133
    assert user.username == u'%s@ldap' % USERNAME_ACCENTS
134
    assert user.first_name == u'Étienne'
135
    assert user.last_name == u'Michü'
136

  
137

  
138
@pytest.mark.django_db
104 139
def test_simple_with_binddn(slapd, settings, client):
105 140
    settings.LDAP_AUTH_SETTINGS = [{
106 141
        'url': [slapd.ldap_url],
107
-