summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAurélien Bompard2016-02-29 12:08:43 +0100
committerBarry Warsaw2016-02-29 21:52:13 -0500
commit9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81 (patch)
tree19ccd0ee3a5d7500a4ad97f792a040ece7ffc663 /src
parentef9cdf45000b1172c3973b329ebe7ed32d604fb1 (diff)
downloadmailman-9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81.tar.gz
mailman-9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81.tar.zst
mailman-9684f1fc0e8bbe2c41566bf16dab92a0ff0f8b81.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/chains/headers.py7
-rw-r--r--src/mailman/chains/tests/test_headers.py9
-rw-r--r--src/mailman/database/alembic/versions/cb7fc8476779_header_match_chain_renamed_to_action.py57
-rw-r--r--src/mailman/database/tests/test_migrations.py51
-rw-r--r--src/mailman/interfaces/mailinglist.py16
-rw-r--r--src/mailman/model/mailinglist.py12
-rw-r--r--src/mailman/model/tests/test_mailinglist.py15
-rw-r--r--src/mailman/rules/docs/header-matching.rst3
-rw-r--r--src/mailman/utilities/importer.py14
-rw-r--r--src/mailman/utilities/tests/test_import.py6
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')]
)