diff options
| author | Barry Warsaw | 2017-01-09 05:37:13 +0000 |
|---|---|---|
| committer | Barry Warsaw | 2017-01-09 05:37:13 +0000 |
| commit | 089fb5f5612f5b25fb5c3bea94d671c45ecea9df (patch) | |
| tree | e077c807084e5f15ea92f4748ffa6bf7e2df92f7 | |
| parent | 609739ee390447a8feb99bb52d13c6e3f0bf3caa (diff) | |
| parent | a01ef2bac4d52da67e4be1fccc2634086aaa03e3 (diff) | |
| download | mailman-089fb5f5612f5b25fb5c3bea94d671c45ecea9df.tar.gz mailman-089fb5f5612f5b25fb5c3bea94d671c45ecea9df.tar.zst mailman-089fb5f5612f5b25fb5c3bea94d671c45ecea9df.zip | |
| -rw-r--r-- | src/mailman/docs/NEWS.rst | 2 | ||||
| -rw-r--r-- | src/mailman/interfaces/pending.py | 18 | ||||
| -rw-r--r-- | src/mailman/model/listmanager.py | 2 | ||||
| -rw-r--r-- | src/mailman/model/pending.py | 6 | ||||
| -rw-r--r-- | src/mailman/model/requests.py | 10 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_listmanager.py | 24 |
6 files changed, 54 insertions, 8 deletions
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index d8b8bb75f..0259d967d 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -101,6 +101,8 @@ Bugs ``reason`` attribute. Given by Aurélien Bompard. * Don't return a 500 error from the REST API when trying to handle a held message with defective content. Given by Abhilash Raj. (Closes: #256) + * Delete subscription requests when a mailing list is deleted. Given by + Abhilash Raj. (Closes: #214) Configuration ------------- diff --git a/src/mailman/interfaces/pending.py b/src/mailman/interfaces/pending.py index 841d195f5..aef18bcb4 100644 --- a/src/mailman/interfaces/pending.py +++ b/src/mailman/interfaces/pending.py @@ -96,14 +96,20 @@ class IPendings(Interface): def evict(): """Remove all pended items whose lifetime has expired.""" - def find(mlist=None, pend_type=None): + def find(mlist=None, pend_type=None, confirm=True): """Search for the pendables matching the given criteria. - :param mlist: The MailingList object that the pendables must be - related to. - :param pend_type: The type of the pendables that are looked for, this - corresponds to the `PEND_TYPE` attribute. - :return: An iterator over 2-tuples of the form (token, dict). + :param mlist: The mailing list object that the pendables must be + related to, or None. The default returns all pendables regardless + of which mailing list they are related to. + :type mlist: IMailingList or None. + :param pend_type: The type of the pendables that are looked for, or + None. This corresponds to the `PEND_TYPE` attribute. The default + returns all pending types. + :param confirm: A flag indicating whether the found pendings should be + "confirmed" or not. See ``confirm()`` for details. + :return: An iterator over 2-tuples of the form (token, pendable). + When ``confirm`` is False, ``pendable`` is None. """ def __iter__(): diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py index 25848aabf..885e5c284 100644 --- a/src/mailman/model/listmanager.py +++ b/src/mailman/model/listmanager.py @@ -22,6 +22,7 @@ from mailman.interfaces.address import InvalidEmailAddressError from mailman.interfaces.listmanager import ( IListManager, ListAlreadyExistsError, ListCreatedEvent, ListCreatingEvent, ListDeletedEvent, ListDeletingEvent) +from mailman.interfaces.requests import IListRequests from mailman.model.autorespond import AutoResponseRecord from mailman.model.bans import Ban from mailman.model.mailinglist import ( @@ -76,6 +77,7 @@ class ListManager: notify(ListDeletingEvent(mlist)) # First delete information associated with the mailing list. IAcceptableAliasSet(mlist).clear() + IListRequests(mlist).clear() store.query(AutoResponseRecord).filter_by(mailing_list=mlist).delete() store.query(ContentFilter).filter_by(mailing_list=mlist).delete() store.query(ListArchiver).filter_by(mailing_list=mlist).delete() diff --git a/src/mailman/model/pending.py b/src/mailman/model/pending.py index dfcc6ea4f..5e5a2af83 100644 --- a/src/mailman/model/pending.py +++ b/src/mailman/model/pending.py @@ -151,7 +151,7 @@ class Pendings: store.delete(pending) @dbconnection - def find(self, store, mlist=None, pend_type=None): + def find(self, store, mlist=None, pend_type=None, confirm=True): query = store.query(Pended) if mlist is not None: pkv_alias_mlist = aliased(PendedKeyValue) @@ -166,7 +166,9 @@ class Pendings: pkv_alias_type.value == pend_type )) for pending in query: - yield pending.token, self.confirm(pending.token, expunge=False) + pendable = (self.confirm(pending.token, expunge=False) + if confirm else None) + yield pending.token, pendable @dbconnection def __iter__(self, store): diff --git a/src/mailman/model/requests.py b/src/mailman/model/requests.py index c177388af..90d1c686c 100644 --- a/src/mailman/model/requests.py +++ b/src/mailman/model/requests.py @@ -23,6 +23,7 @@ from mailman.database.transaction import dbconnection from mailman.database.types import Enum, SAUnicode from mailman.interfaces.pending import IPendable, IPendings from mailman.interfaces.requests import IListRequests, RequestType +from mailman.model.pending import Pended, PendedKeyValue from mailman.utilities.queries import QuerySequence from pickle import dumps, loads from public import public @@ -139,6 +140,15 @@ class ListRequests: getUtility(IPendings).confirm(request.data_hash) store.delete(request) + @dbconnection + def clear(self, store): + for token, pendable in getUtility(IPendings).find( + mlist=self.mailing_list, + confirm=False): + pended = store.query(Pended).filter_by(token=token).first() + store.query(PendedKeyValue).filter_by(pended_id=pended.id).delete() + store.delete(pended) + class _Request(Model): """Table for mailing list hold requests.""" diff --git a/src/mailman/model/tests/test_listmanager.py b/src/mailman/model/tests/test_listmanager.py index 914c0c185..da65f88ce 100644 --- a/src/mailman/model/tests/test_listmanager.py +++ b/src/mailman/model/tests/test_listmanager.py @@ -30,6 +30,7 @@ from mailman.interfaces.listmanager import ( ListDeletedEvent, ListDeletingEvent) from mailman.interfaces.mailinglist import IListArchiverSet from mailman.interfaces.messages import IMessageStore +from mailman.interfaces.pending import IPendable, IPendings from mailman.interfaces.requests import IListRequests from mailman.interfaces.subscriptions import ISubscriptionService from mailman.interfaces.usermanager import IUserManager @@ -38,6 +39,12 @@ from mailman.testing.helpers import ( event_subscribers, specialized_message_from_string) from mailman.testing.layers import ConfigLayer from zope.component import getUtility +from zope.interface import implementer + + +@implementer(IPendable) +class SimplePendable(dict): + PEND_TYPE = 'simple' class TestListManager(unittest.TestCase): @@ -190,6 +197,23 @@ Message-ID: <argon> mailing_list=self._ant) self.assertEqual(filters.count(), 0) + def test_pendings_are_deleted_when_mailing_list_is_deleted(self): + pendingdb = getUtility(IPendings) + pendable_1 = SimplePendable( + type='subscription', + list_id='ant.example.com') + pendingdb.add(pendable_1) + pendable_2 = SimplePendable( + type='subscription', + list_id='bee.example.com') + pendingdb.add(pendable_2) + self.assertEqual(pendingdb.count, 2) + list_manager = getUtility(IListManager) + list_manager.delete(self._ant) + self.assertEqual(pendingdb.count, 1) + list_manager.delete(self._bee) + self.assertEqual(pendingdb.count, 0) + class TestListCreation(unittest.TestCase): layer = ConfigLayer |
