Projet

Général

Profil

0001-ldap-add-useful-output-to-sync-ldap-users-command-54.patch

Valentin Deniaud, 31 août 2021 11:39

Télécharger (7,96 ko)

Voir les différences:

Subject: [PATCH] ldap: add useful output to sync-ldap-users command (#54078)

 src/authentic2/backends/ldap_backend.py       | 26 ++++++++++-
 .../management/commands/sync-ldap-users.py    | 17 +++++--
 tests/test_ldap.py                            | 45 ++++++++++++++++---
 3 files changed, 75 insertions(+), 13 deletions(-)
src/authentic2/backends/ldap_backend.py
1543 1543

  
1544 1544
    @classmethod
1545 1545
    def get_users(cls):
1546
        for block in cls.get_config():
1546
        blocks = cls.get_config()
1547
        if not blocks:
1548
            log.info('No LDAP server configured.')
1549
            return
1550
        for block in blocks:
1551
            log.info('Synchronising users from realm "%s"', block['realm'])
1547 1552
            conn = cls.get_connection(block)
1548 1553
            if conn is None:
1549 1554
                log.warning('unable to synchronize with LDAP servers %s', force_text(block['url']))
......
1552 1557
            user_basedn = force_text(block.get('user_basedn') or block['basedn'])
1553 1558
            user_filter = cls.get_sync_ldap_user_filter(block)
1554 1559
            attribute_names = cls.get_ldap_attributes_names(block)
1560
            log.info('Searching for %s', user_filter)
1555 1561
            results = cls.paged_search(
1556 1562
                conn, user_basedn, ldap.SCOPE_SUBTREE, user_filter, attrlist=attribute_names
1557 1563
            )
1558 1564
            backend = cls()
1565
            count = 0
1559 1566
            for dn, attrs in results:
1560
                yield backend._return_user(dn, None, conn, block, attrs)
1567
                count += 1
1568
                user = backend._return_user(dn, None, conn, block, attrs)
1569
                if getattr(user, '_changed', False):
1570
                    log.debug(
1571
                        'Updated user %s (username %s, full name %s)',
1572
                        user.uuid,
1573
                        user.get_username(),
1574
                        user.get_full_name(),
1575
                    )
1576
                yield user
1577
            log.info('Server returned %s users.', count)
1561 1578

  
1562 1579
    @classmethod
1563 1580
    def deactivate_orphaned_users(cls):
......
1711 1728
            user_credentials = block['connect_with_user_credentials'] and credentials
1712 1729
            success, error = cls.bind(block, conn, credentials=user_credentials)
1713 1730
            if success:
1731
                log.info('Connected to server %s', url)
1714 1732
                yield conn
1715 1733
            else:
1716 1734
                if block['replicas']:
......
1726 1744
                who, password = credentials[0], credentials[1]
1727 1745
                password = force_text(password)
1728 1746
                conn.simple_bind_s(who, password)
1747
                log.info('Binding with %s account: success', who)
1729 1748
            elif block['bindsasl']:
1730 1749
                sasl_mech, who, sasl_params = map_text(block['bindsasl'])
1731 1750
                handler_class = getattr(ldap.sasl, sasl_mech)
1732 1751
                auth = handler_class(*sasl_params)
1733 1752
                conn.sasl_interactive_bind_s(who, auth)
1753
                log.info('Binding with %s account: success', who)
1734 1754
            elif block['binddn'] and block['bindpw']:
1735 1755
                who = force_text(block['binddn'])
1736 1756
                conn.simple_bind_s(who, force_text(block['bindpw']))
1757
                log.info('Binding with %s binddn: success', who)
1737 1758
            else:
1738 1759
                who = 'anonymous'
1739 1760
                conn.simple_bind_s()
1761
                log.info('Binding anonymously: success')
1740 1762
            return True, None
1741 1763
        except ldap.INVALID_CREDENTIALS:
1742 1764
            return False, 'invalid credentials'
src/authentic2/management/commands/sync-ldap-users.py
21 21
except ImportError:
22 22
    ldap = None
23 23

  
24
import logging
25

  
24 26
from django.core.management.base import BaseCommand
25 27

  
26 28
from authentic2.backends.ldap_backend import LDAPBackend
27 29

  
30
logger = logging.getLogger(__name__)
31

  
28 32

  
29 33
class Command(BaseCommand):
30 34
    def handle(self, *args, **kwargs):
31 35
        verbosity = int(kwargs['verbosity'])
32
        if verbosity > 1:
33
            print('Updated users :')
36
        root_logger = logging.getLogger()
37
        if verbosity == 0:
38
            root_logger.setLevel(logging.WARNING)
39
        elif verbosity == 1:
40
            root_logger.setLevel(logging.INFO)
41
        elif verbosity == 2:
42
            root_logger.setLevel(logging.DEBUG)
43

  
34 44
        for user in LDAPBackend.get_users():
35
            if getattr(user, '_changed', False) and verbosity > 1:
36
                print(' -', user.uuid, user.get_username(), user.get_full_name())
45
            continue
tests/test_ldap.py
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17 17
import json
18
import logging
18 19
import os
19 20
import time
20 21
import urllib.parse
......
1605 1606
    assert '_auth_user_id' in app.session
1606 1607

  
1607 1608

  
1608
def test_sync_ldap_users(slapd, settings, app, db, capsys):
1609
def test_sync_ldap_users(slapd, settings, app, db, caplog):
1610
    caplog.set_level(logging.DEBUG)  # force pytest to reset log level after test
1611

  
1612
    management.call_command('sync-ldap-users')
1613
    assert len(caplog.records) == 1
1614
    assert caplog.records[0].message == 'No LDAP server configured.'
1615

  
1609 1616
    settings.LDAP_AUTH_SETTINGS = [
1610 1617
        {
1611 1618
            'url': [slapd.ldap_url],
......
1633 1640
    )
1634 1641

  
1635 1642
    assert User.objects.count() == 0
1636
    capsys.readouterr()
1637
    management.call_command('sync-ldap-users', verbosity=2)
1638
    assert len(capsys.readouterr().out.splitlines()) == 7
1643
    caplog.clear()
1644
    management.call_command('sync-ldap-users')
1645
    assert caplog.messages == [
1646
        'Synchronising users from realm "ldap"',
1647
        'Binding anonymously: success',
1648
        'Connected to server %s' % slapd.ldap_url,
1649
        'Searching for (|(mail=*)(uid=*))',
1650
        'Server returned 6 users.',
1651
    ]
1652

  
1639 1653
    assert User.objects.count() == 6
1640 1654
    assert all(user.first_name == 'Étienne' for user in User.objects.all())
1641 1655
    assert all(user.attributes.first_name == 'Étienne' for user in User.objects.all())
......
1652 1666
            for user in User.objects.all()
1653 1667
        ]
1654 1668
    )
1655
    capsys.readouterr()
1669

  
1670
    User.objects.update(first_name='John')
1671
    caplog.clear()
1672
    management.call_command('sync-ldap-users', verbosity=2)
1673
    assert len(caplog.records) == 42
1674
    assert (
1675
        caplog.records[10].message
1676
        == 'Updated user %s (username etienne.michu@ldap, full name Étienne Michu)'
1677
        % User.objects.first().uuid
1678
    )
1679

  
1680
    caplog.clear()
1656 1681
    management.call_command('sync-ldap-users', verbosity=2)
1657
    assert len(capsys.readouterr().out.splitlines()) == 1
1682
    assert len(caplog.records) == 36  # users have not been updated
1683

  
1684
    caplog.clear()
1685
    management.call_command('sync-ldap-users', verbosity=0)
1686
    assert len(caplog.records) == 0
1658 1687

  
1659 1688

  
1660 1689
def test_alert_on_wrong_user_filter(slapd, settings, client, db, caplog):
......
1819 1848
    }
1820 1849

  
1821 1850

  
1822
def test_switch_user_ldap_user(slapd, settings, app, db):
1851
def test_switch_user_ldap_user(slapd, settings, app, db, caplog):
1852
    caplog.set_level(logging.DEBUG)  # force pytest to reset log level after test
1853

  
1823 1854
    settings.LDAP_AUTH_SETTINGS = [
1824 1855
        {
1825 1856
            'url': [slapd.ldap_url],
1826
-