From 1fef9503fd43b2d7a871a93f4219e7057842407e Mon Sep 17 00:00:00 2001 From: nd <git@notandy.de> Date: Thu, 11 Mar 2021 15:24:02 +0100 Subject: [PATCH] always try to subscribe a user because the mailman api is inconsistent --- .../commands/syncldapmemberships.py | 25 +++++++++++-------- setup.py | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/postorius_ldap_membership_management/management/commands/syncldapmemberships.py b/postorius_ldap_membership_management/management/commands/syncldapmemberships.py index 9de0fcb..a07d952 100644 --- a/postorius_ldap_membership_management/management/commands/syncldapmemberships.py +++ b/postorius_ldap_membership_management/management/commands/syncldapmemberships.py @@ -6,6 +6,8 @@ from django.core.management.base import BaseCommand from django_auth_ldap.config import LDAPSearch import django.conf +from urllib.error import HTTPError + from postorius.models import List, MailmanUser from postorius.utils import get_mailman_client @@ -30,6 +32,7 @@ class Command(BaseCommand): results = user_search.execute(conn) ldap_users = [list(attr.values())[0][0] for dn, attr in results ] django_users = get_user_model().objects.all() + backref_mapping = {'member': 'members', 'moderator': 'moderators', 'owner': 'owners'} mm_users = {} membership_settings = getattr(django.conf.settings, 'LDAP_MEMBERSHIP_SYNC', {}) @@ -42,6 +45,8 @@ class Command(BaseCommand): mm_users[user.username].display_name = user.get_full_name() mm_users[user.username].save() + mailman_id2username = {mm_users[i].user_id: i for i in mm_users} + for list_name in membership_settings: ldap_setting = membership_settings[list_name].get('ldap', {}) for membership_type in ldap_setting: @@ -56,9 +61,6 @@ class Command(BaseCommand): # we refetch the mm_list each time because of wired caching problems mm_list = client.get_list(list_name) - backref_mapping = {'member': 'members', 'moderator': 'moderators', 'owner': 'owners'} - - mailman_id2username = {mm_users[i].user_id: i for i in mm_users} mm_members = getattr(mm_list, backref_mapping[membership_type], []) for mm_member in mm_members: try: @@ -77,14 +79,11 @@ class Command(BaseCommand): try: mm_user = mm_users[username] displayname = mm_users[username].display_name or username - for mm_subscription in mm_user.subscriptions: - if mm_subscription.role == membership_type: - # user is already subscribed - break - else: - # user is not subscribed but should be subscribed -> subscribe + try: + # user might not be subscribed but should be subscribed -> subscribe + # we do not test if he is subscibed already because the mailman api is inconsistent and reports wrong state information for this... + # instead we always try to subscribe and catch the error if we are subscribed already user_mail = mm_user.addresses[0].email - logger.warning("subscribe {} ( {} ) as {} on {}".format(username, user_mail, membership_type, list_name)) if membership_type == 'member': mm_list.subscribe(user_mail, display_name=displayname, @@ -97,6 +96,12 @@ class Command(BaseCommand): elif membership_type == 'owner': mm_list.add_moderator(user_mail, display_name=displayname) + logger.warning("subscribe {} ( {} ) as {} on {}".format(username, user_mail, membership_type, list_name)) + except HTTPError as e: + # We get a http error if the user is already subscribed. + # It is silently ignored + if e.code == 409 and e.reason == b'Member already subscribed': + continue except Exception as e: logger.exception(e) continue diff --git a/setup.py b/setup.py index 400351f..2fac7ae 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup(name='postorius_ldap_membership_management', - version='1.0', + version='1.1', description='Sync subscriptions from ldap', url='https://git.cccv.de:infra/uffd/postorius-ldap-membership-management', author='Andreas Valder', -- GitLab