summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/chains/tests/test_headers.py12
-rw-r--r--src/mailman/core/docs/chains.rst8
-rw-r--r--src/mailman/interfaces/usermanager.py32
-rw-r--r--src/mailman/model/tests/test_usermanager.py28
-rw-r--r--src/mailman/model/usermanager.py10
5 files changed, 80 insertions, 10 deletions
diff --git a/src/mailman/chains/tests/test_headers.py b/src/mailman/chains/tests/test_headers.py
index cd4c932cc..940c4ea87 100644
--- a/src/mailman/chains/tests/test_headers.py
+++ b/src/mailman/chains/tests/test_headers.py
@@ -205,8 +205,8 @@ This is junk
events = []
with event_subscribers(events.append):
process(self._mlist, msg, msgdata, start_chain='header-match')
- self.assertEqual(len(events), 1)
- event = events[0]
+ self.assertEqual(len(events), 3) # Two address events and hold event.
+ event = events[2]
self.assertIsInstance(event, HoldEvent)
self.assertEqual(event.chain, config.chains['hold'])
@@ -229,8 +229,8 @@ body
events = []
with event_subscribers(events.append):
process(self._mlist, msg, msgdata, start_chain='header-match')
- self.assertEqual(len(events), 1)
- event = events[0]
+ self.assertEqual(len(events), 3) # Two address events and hold event.
+ event = events[2]
self.assertIsInstance(event, HoldEvent)
self.assertEqual(event.chain, config.chains['hold'])
@@ -258,8 +258,8 @@ A message body.
events = []
with event_subscribers(events.append):
process(self._mlist, msg, msgdata, start_chain='header-match')
- self.assertEqual(len(events), 1)
- event = events[0]
+ self.assertEqual(len(events), 3) # Two address events and hold event.
+ event = events[2]
# Site-wide wants to hold the message, the list wants to accept it.
self.assertIsInstance(event, HoldEvent)
self.assertEqual(event.chain, config.chains['hold'])
diff --git a/src/mailman/core/docs/chains.rst b/src/mailman/core/docs/chains.rst
index e3190e364..48b8c8858 100644
--- a/src/mailman/core/docs/chains.rst
+++ b/src/mailman/core/docs/chains.rst
@@ -32,9 +32,13 @@ The `discard` chain simply throws the message away.
... An important message.
... """)
+ >>> from mailman.interfaces.chain import ChainEvent
+
>>> def print_msgid(event):
- ... print('{0}: {1}'.format(
- ... event.chain.name.upper(), event.msg.get('message-id', 'n/a')))
+ ... if isinstance(event, ChainEvent):
+ ... print('{0}: {1}'.format(
+ ... event.chain.name.upper(),
+ ... event.msg.get('message-id', 'n/a')))
>>> from mailman.core.chains import process
>>> from mailman.testing.helpers import event_subscribers
diff --git a/src/mailman/interfaces/usermanager.py b/src/mailman/interfaces/usermanager.py
index 05034bc83..4dc3a2479 100644
--- a/src/mailman/interfaces/usermanager.py
+++ b/src/mailman/interfaces/usermanager.py
@@ -22,6 +22,38 @@ from zope.interface import Attribute, Interface
@public
+class AddressCreatingEvent:
+ """An address is about to be created."""
+
+ def __init__(self, email):
+ self.email = email
+
+
+@public
+class AddressCreatedEvent:
+ """An address was created."""
+
+ def __init__(self, address):
+ self.address = address
+
+
+@public
+class AddressDeletingEvent:
+ """An address is about to be deleted."""
+
+ def __init__(self, address):
+ self.address = address
+
+
+@public
+class AddressDeletedEvent:
+ """An address was deleted."""
+
+ def __init__(self, email):
+ self.email = email
+
+
+@public
class IUserManager(Interface):
"""The global user management service."""
diff --git a/src/mailman/model/tests/test_usermanager.py b/src/mailman/model/tests/test_usermanager.py
index 754acb610..7b5b490e1 100644
--- a/src/mailman/model/tests/test_usermanager.py
+++ b/src/mailman/model/tests/test_usermanager.py
@@ -24,7 +24,10 @@ from mailman.config import config
from mailman.interfaces.address import ExistingAddressError
from mailman.interfaces.autorespond import IAutoResponseSet, Response
from mailman.interfaces.member import DeliveryMode
-from mailman.interfaces.usermanager import IUserManager
+from mailman.interfaces.usermanager import (
+ AddressCreatedEvent, AddressCreatingEvent, AddressDeletedEvent,
+ AddressDeletingEvent, IUserManager)
+from mailman.testing.helpers import event_subscribers
from mailman.testing.layers import ConfigLayer
from mailman.utilities.datetime import now
from zope.component import getUtility
@@ -35,6 +38,29 @@ class TestUserManager(unittest.TestCase):
def setUp(self):
self._usermanager = getUtility(IUserManager)
+ self._events = []
+
+ def _record_event(self, event):
+ self._events.append(event)
+
+ def test_create_address_event(self):
+ with event_subscribers(self._record_event):
+ address = self._usermanager.create_address('anne@example.com')
+ self.assertEqual(len(self._events), 2)
+ self.assertIsInstance(self._events[0], AddressCreatingEvent)
+ self.assertEqual(self._events[0].email, 'anne@example.com')
+ self.assertIsInstance(self._events[1], AddressCreatedEvent)
+ self.assertEqual(self._events[1].address, address)
+
+ def test_delete_address_event(self):
+ address = self._usermanager.create_address('anne@example.com')
+ with event_subscribers(self._record_event):
+ self._usermanager.delete_address(address)
+ self.assertEqual(len(self._events), 2)
+ self.assertIsInstance(self._events[0], AddressDeletingEvent)
+ self.assertEqual(self._events[0].address, address)
+ self.assertIsInstance(self._events[1], AddressDeletedEvent)
+ self.assertEqual(self._events[1].email, 'anne@example.com')
def test_create_user_with_existing_address(self):
# LP: #1418280. If a user is created when an email address is passed
diff --git a/src/mailman/model/usermanager.py b/src/mailman/model/usermanager.py
index 24b3a355e..6f5d5b774 100644
--- a/src/mailman/model/usermanager.py
+++ b/src/mailman/model/usermanager.py
@@ -19,7 +19,9 @@
from mailman.database.transaction import dbconnection
from mailman.interfaces.address import ExistingAddressError
-from mailman.interfaces.usermanager import IUserManager
+from mailman.interfaces.usermanager import (
+ AddressCreatedEvent, AddressCreatingEvent, AddressDeletedEvent,
+ AddressDeletingEvent, IUserManager)
from mailman.model.address import Address
from mailman.model.autorespond import AutoResponseRecord
from mailman.model.digests import OneLastDigest
@@ -27,6 +29,7 @@ from mailman.model.member import Member
from mailman.model.preferences import Preferences
from mailman.model.user import User
from public import public
+from zope.event import notify
from zope.interface import implementer
@@ -104,6 +107,7 @@ class UserManager:
@dbconnection
def create_address(self, store, email, display_name=None):
"""See `IUserManager`."""
+ notify(AddressCreatingEvent(email))
addresses = store.query(Address).filter(Address.email == email.lower())
if addresses.count() == 1:
found = addresses[0]
@@ -116,6 +120,7 @@ class UserManager:
address = Address(email, display_name)
address.preferences = Preferences()
store.add(address)
+ notify(AddressCreatedEvent(address))
return address
@dbconnection
@@ -123,6 +128,8 @@ class UserManager:
"""See `IUserManager`."""
# If there's a user controlling this address, it has to first be
# unlinked before the address can be deleted.
+ email = address.email
+ notify(AddressDeletingEvent(address))
if address.user:
address.user.unlink(address)
# Remove memberships.
@@ -134,6 +141,7 @@ class UserManager:
store.query(OneLastDigest).filter_by(address=address).delete()
# Now delete the address.
store.delete(address)
+ notify(AddressDeletedEvent(email))
@dbconnection
def get_address(self, store, email):