diff options
| author | Aurélien Bompard | 2016-02-29 12:08:43 +0100 |
|---|---|---|
| committer | Barry Warsaw | 2016-02-29 21:52:13 -0500 |
| commit | 9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81 (patch) | |
| tree | 19ccd0ee3a5d7500a4ad97f792a040ece7ffc663 | |
| parent | ef9cdf45000b1172c3973b329ebe7ed32d604fb1 (diff) | |
| download | mailman-9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81.tar.gz mailman-9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81.tar.zst mailman-9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81.zip | |
| -rw-r--r-- | src/mailman/chains/headers.py | 7 | ||||
| -rw-r--r-- | src/mailman/chains/tests/test_headers.py | 9 | ||||
| -rw-r--r-- | src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py | 57 | ||||
| -rw-r--r-- | src/mailman/database/tests/test_migrations.py | 51 | ||||
| -rw-r--r-- | src/mailman/interfaces/mailinglist.py | 16 | ||||
| -rw-r--r-- | src/mailman/model/mailinglist.py | 12 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_mailinglist.py | 15 | ||||
| -rw-r--r-- | src/mailman/rules/docs/header-matching.rst | 3 | ||||
| -rw-r--r-- | src/mailman/utilities/importer.py | 14 | ||||
| -rw-r--r-- | src/mailman/utilities/tests/test_import.py | 6 |
10 files changed, 38 insertions, 152 deletions
diff --git a/src/mailman/chains/headers.py b/src/mailman/chains/headers.py index d3db30b23..23ad79fdf 100644 --- a/src/mailman/chains/headers.py +++ b/src/mailman/chains/headers.py @@ -150,9 +150,6 @@ class HeaderMatchChain(Chain): yield Link('any', LinkAction.jump, config.antispam.jump_chain) # Then return all the list-specific header matches. for entry in mlist.header_matches: - if entry.action is None: - # Default to the default antispam chain. - chain = config.antispam.jump_chain - else: - chain = entry.action.name + # Jump to the default antispam chain if the entry chain is None. + chain = entry.chain or config.antispam.jump_chain yield make_link(entry.header, entry.pattern, chain) diff --git a/src/mailman/chains/tests/test_headers.py b/src/mailman/chains/tests/test_headers.py index 28c3e1cdc..693f132d0 100644 --- a/src/mailman/chains/tests/test_headers.py +++ b/src/mailman/chains/tests/test_headers.py @@ -29,7 +29,6 @@ from mailman.chains.headers import HeaderMatchRule, make_link from mailman.config import config from mailman.core.chains import process from mailman.email.message import Message -from mailman.interfaces.action import Action from mailman.interfaces.chain import LinkAction, HoldEvent, DiscardEvent from mailman.interfaces.configuration import ConfigurationUpdatedEvent from mailman.interfaces.mailinglist import IHeaderMatchList @@ -163,9 +162,9 @@ class TestHeaderChain(unittest.TestCase): # properly. chain = config.chains['header-match'] header_matches = IHeaderMatchList(self._mlist) - header_matches.append('Foo', 'a+', Action.reject) - header_matches.append('Bar', 'b+', Action.discard) - header_matches.append('Baz', 'z+', Action.accept) + header_matches.append('Foo', 'a+', 'reject') + header_matches.append('Bar', 'b+', 'discard') + header_matches.append('Baz', 'z+', 'accept') links = [link for link in chain.get_links(self._mlist, Message(), {}) if link.rule.name != 'any'] self.assertEqual(len(links), 3) @@ -196,7 +195,7 @@ A message body. """) msgdata = {} header_matches = IHeaderMatchList(self._mlist) - header_matches.append('Foo', 'foo', Action.accept) + header_matches.append('Foo', 'foo', 'accept') # This event subscriber records the event that occurs when the message # is processed by the owner chain. events = [] diff --git a/src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py b/src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py deleted file mode 100644 index 45a09b936..000000000 --- a/src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py +++ /dev/null @@ -1,57 +0,0 @@ -"""HeaderMatch chain renamed to action - -Revision ID: cb7fc8476779 -Revises: d4fbb4fd34ca -Create Date: 2016-02-02 17:23:36.199207 - -""" - -# revision identifiers, used by Alembic. -revision = 'cb7fc8476779' -down_revision = 'd4fbb4fd34ca' - -import sqlalchemy as sa -from alembic import op -from mailman.database.helpers import is_sqlite, exists_in_db -from mailman.database.types import Enum -from mailman.interfaces.action import Action - - -# Don't import the table definition from the models, it may break this -# migration when the model is updated in the future (see the Alembic doc) -hm_table = sa.sql.table('headermatch', - sa.sql.column('action', Enum(Action)), - sa.sql.column('chain', sa.VARCHAR()) - ) - - -def upgrade(): - if not exists_in_db(op.get_bind(), 'headermatch', 'action'): - op.add_column( - 'headermatch', sa.Column('action', Enum(Action), nullable=True)) - - # Now migrate the data - for action_enum in Action: - op.execute(hm_table.update( - ).values(action=action_enum - ).where(hm_table.c.chain == action_enum.name)) - # Now that data is migrated, drop the old column (except on SQLite which - # does not support this) - if not is_sqlite(op.get_bind()): - op.drop_column('headermatch', 'chain') - - -def downgrade(): - if not exists_in_db(op.get_bind(), 'headermatch', 'chain'): - op.add_column( - 'headermatch', sa.Column('chain', sa.VARCHAR(), nullable=True)) - - # Now migrate the data - for action_enum in Action: - op.execute(hm_table.update( - ).values(chain=action_enum.name - ).where(hm_table.c.action == action_enum)) - # Now that data is migrated, drop the new column (except on SQLite which - # does not support this) - if not is_sqlite(op.get_bind()): - op.drop_column('headermatch', 'action') diff --git a/src/mailman/database/tests/test_migrations.py b/src/mailman/database/tests/test_migrations.py index 560c10648..c3558abea 100644 --- a/src/mailman/database/tests/test_migrations.py +++ b/src/mailman/database/tests/test_migrations.py @@ -33,9 +33,6 @@ from mailman.database.alembic import alembic_cfg from mailman.database.helpers import exists_in_db from mailman.database.model import Model from mailman.database.transaction import transaction -from mailman.database.types import Enum -from mailman.interfaces.action import Action -from mailman.interfaces.mailinglist import IHeaderMatchList from mailman.testing.layers import ConfigLayer @@ -226,51 +223,3 @@ class TestMigrations(unittest.TestCase): os.path.join(config.LIST_DATA_DIR, 'ant@example.com'))) self.assertTrue(os.path.exists(ant.data_path)) self.assertTrue(os.path.exists(bee.data_path)) - - def test_cb7fc8476779_header_match_action(self): - data = { - 'header-1': Action.accept, - 'header-2': Action.hold, - 'header-3': Action.discard, - 'header-4': Action.reject, - } - # Create a mailing list through the standard API. - with transaction(): - ant = create_list('ant@example.com') - # Create header matches - header_matches = IHeaderMatchList(ant) - for header, action in data.items(): - header_matches.append(header, 'pattern', action) - hm_table = sa.sql.table( - 'headermatch', - sa.sql.column('header', sa.Unicode), - sa.sql.column('action', Enum(Action)), - sa.sql.column('chain', sa.Unicode), - ) - # Downgrade and verify that the chain names are correct. - with transaction(): - alembic.command.downgrade(alembic_cfg, 'd4fbb4fd34ca') - with transaction(): - results = config.db.store.execute( - sa.select([hm_table.c.header, hm_table.c.chain])).fetchall() - self.assertEqual(len(results), 4) - for header, chain in results: - self.assertEqual(chain, data[header].name) - if config.db.store.bind.dialect.name == 'sqlite': - # Clear the previous values for testing, since SQLite did not - # remove the column. - with transaction(): - config.db.store.execute( - hm_table.update().values(action=None)) - for action in config.db.store.execute( - sa.select([hm_table.c.action])).fetchall(): - self.assertEqual(action[0], None) - # Upgrade and verify that the actions are back to normal. - with transaction(): - alembic.command.upgrade(alembic_cfg, 'cb7fc8476779') - with transaction(): - results = config.db.store.execute( - sa.select([hm_table.c.header, hm_table.c.action])).fetchall() - self.assertEqual(len(results), 4) - for header, action in results: - self.assertEqual(action, data[header]) diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py index fc92425a8..53cea9d61 100644 --- a/src/mailman/interfaces/mailinglist.py +++ b/src/mailman/interfaces/mailinglist.py @@ -880,7 +880,7 @@ class IHeaderMatchList(Interface): def clear(): """Clear the list of header matching rules.""" - def append(header, pattern, action=None): + def append(header, pattern, chain=None): """Append the given rule to this mailing list's header match list. :param header: The email header to filter on. It will be converted to @@ -888,14 +888,14 @@ class IHeaderMatchList(Interface): :type header: string :param pattern: The regular expression to use. :type pattern: string - :param action: The Action enum pointing to the chain to jump to, or - None to use the site-wide configuration. Defaults to None. - :type action: `Action` enum or None + :param chain: The chain to jump to, or None to use the site-wide + configuration. Defaults to None. + :type chain: string or None :raises ValueError: if the header/pattern pair already exists for this mailing list. """ - def insert(index, header, pattern, action=None): + def insert(index, header, pattern, chain=None): """Insert the given rule at the given index position in this mailing list's header match list. @@ -906,9 +906,9 @@ class IHeaderMatchList(Interface): :type header: string :param pattern: The regular expression to use. :type pattern: string - :param action: The Action enum pointing to the chain to jump to, or - None to use the site-wide configuration. Defaults to None. - :type action: `Action` enum or None + :param chain: The chain to jump to, or None to use the site-wide + configuration. Defaults to None. + :type chain: string or None :raises ValueError: if the header/pattern pair already exists for this mailing list. """ diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py index b5c83ff29..7761f2842 100644 --- a/src/mailman/model/mailinglist.py +++ b/src/mailman/model/mailinglist.py @@ -643,7 +643,7 @@ class HeaderMatch(Model): _position = Column('position', Integer, index=True, default=0) header = Column(Unicode) pattern = Column(Unicode) - action = Column(Enum(Action), nullable=True) + chain = Column(Unicode, nullable=True) def __init__(self, **kw): if 'position' in kw: @@ -711,7 +711,7 @@ class HeaderMatchList: del self._mailing_list.header_matches[:] @dbconnection - def append(self, store, header, pattern, action=None): + def append(self, store, header, pattern, chain=None): header = header.lower() existing = store.query(HeaderMatch).filter( HeaderMatch.mailing_list == self._mailing_list, @@ -726,20 +726,20 @@ class HeaderMatchList: last_position = -1 header_match = HeaderMatch( mailing_list=self._mailing_list, - header=header, pattern=pattern, action=action, + header=header, pattern=pattern, chain=chain, position=last_position + 1) store.add(header_match) store.expire(self._mailing_list, ['header_matches']) @dbconnection - def insert(self, store, index, header, pattern, action=None): - self.append(header, pattern, action) + def insert(self, store, index, header, pattern, chain=None): + self.append(header, pattern, chain) # Get the header match that was just added. header_match = store.query(HeaderMatch).filter( HeaderMatch.mailing_list == self._mailing_list, HeaderMatch.header == header.lower(), HeaderMatch.pattern == pattern, - HeaderMatch.action == action).one() + HeaderMatch.chain == chain).one() header_match.position = index store.expire(self._mailing_list, ['header_matches']) diff --git a/src/mailman/model/tests/test_mailinglist.py b/src/mailman/model/tests/test_mailinglist.py index 63e1cd300..1fc7b2e0d 100644 --- a/src/mailman/model/tests/test_mailinglist.py +++ b/src/mailman/model/tests/test_mailinglist.py @@ -30,7 +30,6 @@ import unittest from mailman.app.lifecycle import create_list from mailman.config import config from mailman.database.transaction import transaction -from mailman.interfaces.action import Action from mailman.interfaces.listmanager import IListManager from mailman.interfaces.mailinglist import ( IAcceptableAliasSet, IHeaderMatchList, IListArchiverSet) @@ -206,11 +205,11 @@ class TestHeaderMatch(unittest.TestCase): self.assertEqual(len(self._mlist.header_matches), 1) self.assertEqual(self._mlist.header_matches[0].header, 'header') - def test_action_defaults_to_none(self): + def test_chain_defaults_to_none(self): header_matches = IHeaderMatchList(self._mlist) header_matches.append('header', 'pattern') self.assertEqual(len(self._mlist.header_matches), 1) - self.assertEqual(self._mlist.header_matches[0].action, None) + self.assertEqual(self._mlist.header_matches[0].chain, None) def test_duplicate(self): header_matches = IHeaderMatchList(self._mlist) @@ -241,16 +240,16 @@ class TestHeaderMatch(unittest.TestCase): header_matches = IHeaderMatchList(self._mlist) header_matches.append('Header', 'pattern') header_matches.append('Subject', 'patt.*') - header_matches.append('From', '.*@example.com', Action.discard) - header_matches.append('From', '.*@example.org', Action.accept) - matches = [(match.header, match.pattern, match.action) + header_matches.append('From', '.*@example.com', 'discard') + header_matches.append('From', '.*@example.org', 'accept') + matches = [(match.header, match.pattern, match.chain) for match in IHeaderMatchList(self._mlist)] self.assertEqual( matches, [ ('header', 'pattern', None), ('subject', 'patt.*', None), - ('from', '.*@example.com', Action.discard), - ('from', '.*@example.org', Action.accept), + ('from', '.*@example.com', 'discard'), + ('from', '.*@example.org', 'accept'), ]) def test_clear(self): diff --git a/src/mailman/rules/docs/header-matching.rst b/src/mailman/rules/docs/header-matching.rst index a4d539291..4e6c0853d 100644 --- a/src/mailman/rules/docs/header-matching.rst +++ b/src/mailman/rules/docs/header-matching.rst @@ -177,9 +177,8 @@ As does a message with a spam score of four pluses. Now, the list administrator wants to match on three plus signs, but wants those emails to be discarded instead of held. - >>> from mailman.interfaces.action import Action >>> header_matches.remove('x-spam-score', '[+]{3,}') - >>> header_matches.append('x-spam-score', '[+]{3,}', Action.discard) + >>> header_matches.append('x-spam-score', '[+]{3,}', 'discard') A message with a spam score of three pluses will still match, and the message will be discarded. diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py index 8a37d909e..52de967cf 100644 --- a/src/mailman/utilities/importer.py +++ b/src/mailman/utilities/importer.py @@ -129,7 +129,7 @@ def nonmember_action_mapping(value): }[value] -def action_to_enum(value): +def action_to_chain(value): # Converts an action number in Mailman 2.1 to the name of the corresponding # chain in 3.x. The actions 'approve', 'subscribe' and 'unsubscribe' are # ignored. The defer action is converted to None, because it is not @@ -137,12 +137,12 @@ def action_to_enum(value): return { 0: None, #1: 'approve', - 2: Action.reject, - 3: Action.discard, + 2: 'reject', + 3: 'discard', #4: 'subscribe', #5: 'unsubscribe', - 6: Action.accept, - 7: Action.hold, + 6: 'accept', + 7: 'hold', }[value] @@ -337,7 +337,7 @@ def import_config_pck(mlist, config_dict): header_filter_rules = config_dict.get('header_filter_rules', []) for line_patterns, action, _unused in header_filter_rules: try: - action = action_to_enum(action) + chain = action_to_chain(action) except KeyError: log.warning('Unsupported header_filter_rules action: %r', action) @@ -374,7 +374,7 @@ def import_config_pck(mlist, config_dict): 'invalid regular expression: %r', line_pattern) continue try: - header_matches.append(header, pattern, action) + header_matches.append(header, pattern, chain) except ValueError: log.warning('Skipping duplicate header_filter rule: %r', line_pattern) diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py index 1b7c1d60e..68a005760 100644 --- a/src/mailman/utilities/tests/test_import.py +++ b/src/mailman/utilities/tests/test_import.py @@ -367,7 +367,7 @@ class TestBasicImport(unittest.TestCase): error_log = LogFileMark('mailman.error') self._import() self.assertListEqual( - [(hm.header, hm.pattern, hm.action.name) + [(hm.header, hm.pattern, hm.chain) for hm in self._mlist.header_matches ], [ ('x-spam-status', 'Yes.*', 'discard'), ('x-spam-status', 'Yes', 'reject'), @@ -445,7 +445,7 @@ class TestBasicImport(unittest.TestCase): ] self._import() self.assertListEqual( - [(hm.header, hm.pattern, hm.action) + [(hm.header, hm.pattern, hm.chain) for hm in self._mlist.header_matches], [('x-spam-status', 'Yes', None)] ) @@ -476,7 +476,7 @@ class TestBasicImport(unittest.TestCase): error_log = LogFileMark('mailman.error') self._import() self.assertListEqual( - [(hm.header, hm.pattern, hm.action.name) + [(hm.header, hm.pattern, hm.chain) for hm in self._mlist.header_matches], [('someheadername', 'test-pattern', 'discard')] ) |
