From 6ffc739b15405584cc75be313417edc04c904033 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 27 Feb 2024 16:08:12 -0300 Subject: [PATCH] Moderation policy, DMARC, archive --- export_mailman2_settings.py | 55 ++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/export_mailman2_settings.py b/export_mailman2_settings.py index c790fa6..b632648 100644 --- a/export_mailman2_settings.py +++ b/export_mailman2_settings.py @@ -4,7 +4,9 @@ import sys from bs4 import BeautifulSoup -from mailman.utilities.importer import NAME_MAPPINGS +from mailman.interfaces.archiver import ArchivePolicy +from mailman.interfaces.action import Action +from mailman.utilities.importer import NAME_MAPPINGS, member_moderation_action_mapping, dmarc_action_mapping KEYFILTER = ('submit') @@ -72,4 +74,55 @@ if __name__ == "__main__": msg(f"warning - duplicate key {key}") else: globalconfig[key] = value + + # Handle the moderation policy. + # + # The mlist.default_member_action and mlist.default_nonmember_action enum + # values are different in Mailman 2.1, because they have been merged into a + # single enum in Mailman 3. + # + # Unmoderated lists used to have default_member_moderation set to a false + # value; this translates to the Defer default action. Moderated lists with + # the default_member_moderation set to a true value used to store the + # action in the member_moderation_action flag, the values were: 0==Hold, + # 1=Reject, 2==Discard + if bool(globalconfig.get('default_member_moderation', 0)): + globalconfig['default_member_action'] = member_moderation_action_mapping( + globalconfig.get('member_moderation_action')).name + else: + globalconfig['default_member_action'] = Action.defer.name + # Handle DMARC mitigations. + # This would be straightforward except for from_is_list. The issue + # is in MM 2.1 the from_is_list action applies if dmarc_moderation_action + # doesn't apply and they can be different. + # We will map as follows: + # from_is_list > dmarc_moderation_action + # dmarc_mitigate_action = from_is_list action + # dmarc_mitigate_unconditionally = True + # from_is_list <= dmarc_moderation_action + # dmarc_mitigate_action = dmarc_moderation_action + # dmarc_mitigate_unconditionally = False + # The text attributes are handled above. + if (globalconfig.get('from_is_list', 0) > + globalconfig.get('dmarc_moderation_action', 0)): + globalconfig['dmarc_mitigate_action'] = dmarc_action_mapping( + globalconfig.get('from_is_list', 0)).name + globalconfig['dmarc_mitigate_unconditionally'] = True + else: + globalconfig['dmarc_mitigate_action'] = dmarc_action_mapping( + globalconfig.get('dmarc_moderation_action', 0)).name + globalconfig['dmarc_mitigate_unconditionally'] = False + # Handle the archiving policy. In MM2.1 there were two boolean options + # but only three of the four possible states were valid. Now there's just + # an enum. + if globalconfig.get('archive'): + # For maximum safety, if for some strange reason there's no + # archive_private key, treat the list as having private archives. + if globalconfig.get('archive_private', True): + globalconfig['archive_policy'] = ArchivePolicy.private.name + else: + globalconfig['archive_policy'] = ArchivePolicy.public.name + else: + globalconfig['archive_policy'] = ArchivePolicy.never.name + print(json.dumps(globalconfig))