Projet

Général

Profil

0001-ldap-perform-extensive-user-lookup-regardless-of-the.patch

Paul Marillonnet, 21 juillet 2022 16:13

Télécharger (6,13 ko)

Voir les différences:

Subject: [PATCH 1/2] ldap: perform extensive user lookup regardless of their
 origin (#67600)

 src/authentic2/backends/ldap_backend.py | 22 +++++++++++++---------
 tests/test_ldap.py                      | 19 +++++++++++--------
 2 files changed, 24 insertions(+), 17 deletions(-)
src/authentic2/backends/ldap_backend.py
1359 1359
        return ' '.join(part for part in parts)
1360 1360

  
1361 1361
    def _lookup_user_queryset(self, block):
1362
        return LDAPUser.objects.prefetch_related('groups').exclude(userexternalid__source=block['realm'])
1362
        ueids = UserExternalId.objects.filter(source=block['realm'])
1363
        return User.objects.prefetch_related('groups').exclude(
1364
            id__in=ueids.values_list('user__id', flat=True)
1365
        )
1363 1366

  
1364 1367
    def _lookup_by_username(self, ou, block, username):
1365 1368
        try:
1366 1369
            log.debug('ldap: lookup using username %r', username)
1367 1370
            return self._lookup_user_queryset(block=block).get(ou=ou, username=username)
1368
        except LDAPUser.DoesNotExist:
1371
        except User.DoesNotExist:
1369 1372
            return None
1370
        except LDAPUser.MultipleObjectsReturned:
1373
        except User.MultipleObjectsReturned:
1371 1374
            log.warning(
1372 1375
                'ldap: lookup using username %r, too many users with this username in ou "%s"', username, ou
1373 1376
            )
......
1384 1387
        try:
1385 1388
            log.debug('ldap: lookup using email %r', email)
1386 1389
            return self._lookup_user_queryset(block=block).get(ou=ou, email=email)
1387
        except LDAPUser.DoesNotExist:
1390
        except User.DoesNotExist:
1388 1391
            return None
1389
        except LDAPUser.MultipleObjectsReturned:
1392
        except User.MultipleObjectsReturned:
1390 1393
            log.warning('ldap: lookup using email %r, too many users with this email in ou "%s"', email, ou)
1391 1394
            return None
1392 1395

  
......
1583 1586
            user = LDAPUser(username=username)
1584 1587
            user._created = True
1585 1588
            user.set_unusable_password()
1586
        user.ldap_init(block, dn)
1587
        user.keep_password(password)
1588
        self.populate_user(user, dn, username, conn, block, attributes)
1589
        if isinstance(user, LDAPUser):
1590
            user.ldap_init(block, dn)
1591
            user.keep_password(password)
1592
            self.populate_user(user, dn, username, conn, block, attributes)
1589 1593
        if not user.pk or getattr(user, '_changed', False):
1590 1594
            user.save()
1591 1595

  
......
1652 1656
            if not user:
1653 1657
                log.warning('unable to retrieve user for dn %s', dn)
1654 1658
                continue
1655
            if user._changed or user._created:
1659
            if isinstance(user, LDAPUser) and (user._changed or user._created):
1656 1660
                log.info(
1657 1661
                    '%s user %s (uuid %s) from %s',
1658 1662
                    'Created' if user._created else 'Updated',
tests/test_ldap.py
771 771
            'group_to_role_mapping': [
772 772
                ['cn=unknown,o=dn', ['Role2']],
773 773
            ],
774
            'lookups': ['external_id', 'username'],
774
            'lookups': ['external_id', 'username', 'email'],
775 775
        }
776 776
    ]
777 777
    save = mock.Mock(wraps=ldap_backend.LDAPUser.save)
......
2324 2324
        return ldap_backend.LDAPBackend()
2325 2325

  
2326 2326
    def test_by_email(self, backend, slapd, settings, client, db):
2327
        user = User.objects.create(email=EMAIL, ou=get_default_ou())
2327
        user = User.objects.create(email=EMAIL, ou=get_default_ou(), username=USERNAME)
2328 2328
        assert backend.authenticate(None, username=USERNAME, password=PASS) == user
2329
        assert models.UserExternalId.objects.get(user=user, source='ldap', external_id=UID)
2329
        # user existed before ldap authn, we do not consider ldap as its source
2330
        assert not models.UserExternalId.objects.filter(user=user, source='ldap', external_id=UID).count()
2330 2331
        user.email = ''
2331 2332
        user.save()
2332
        # if email is changed
2333 2333
        auth_user = backend.authenticate(None, username=USERNAME, password=PASS)
2334
        # we do not modify pre-existing users
2334 2335
        assert auth_user == user
2335
        assert auth_user.email == EMAIL
2336
        assert auth_user.email == ''
2336 2337

  
2337 2338
    def test_by_email_only(self, backend, slapd, settings, client, db):
2338 2339
        settings.LDAP_AUTH_SETTINGS[0]['lookups'] = ['email']
......
2346 2347
        assert new_user.email == EMAIL
2347 2348

  
2348 2349
    def test_by_username(self, backend, slapd, settings, client, db):
2349
        user = User.objects.create(username=UID, ou=get_default_ou())
2350
        user = User.objects.create(username=UID, email=EMAIL, ou=get_default_ou())
2350 2351
        assert backend.authenticate(None, username=EMAIL, password=PASS) == user
2351
        assert models.UserExternalId.objects.get(user=user, source='ldap', external_id=UID)
2352
        # user existed before ldap authn, we do not consider ldap as its source
2353
        assert not models.UserExternalId.objects.filter(user=user, source='ldap', external_id=UID).count()
2352 2354
        user.username = ''
2353 2355
        user.save()
2354 2356
        auth_user = backend.authenticate(None, username=EMAIL, password=PASS)
......
2356 2358
        assert auth_user.username == ''
2357 2359
        settings.LDAP_AUTH_SETTINGS[0]['update_username'] = True
2358 2360
        auth_user = backend.authenticate(None, username=EMAIL, password=PASS)
2361
        # we do not modify pre-existing users
2359 2362
        assert auth_user == user
2360
        assert auth_user.username == f'{UID}@ldap'
2363
        assert auth_user.username == ''
2361 2364

  
2362 2365
    def test_by_guid_migration(self, backend, slapd, settings, client, db):
2363 2366
        settings.LDAP_AUTH_SETTINGS[0]['lookups'] = ['external_id']
2364
-