summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/docs/NEWS.rst2
-rw-r--r--src/mailman/interfaces/pending.py18
-rw-r--r--src/mailman/model/listmanager.py2
-rw-r--r--src/mailman/model/pending.py6
-rw-r--r--src/mailman/model/requests.py10
-rw-r--r--src/mailman/model/tests/test_listmanager.py24
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