diff options
Diffstat (limited to 'src')
24 files changed, 112 insertions, 204 deletions
diff --git a/src/mailman/app/docs/moderator.rst b/src/mailman/app/docs/moderator.rst index e183d050c..ce25a4711 100644 --- a/src/mailman/app/docs/moderator.rst +++ b/src/mailman/app/docs/moderator.rst @@ -217,12 +217,12 @@ the unsubscribing address is required. Fred is a member of the mailing list... >>> from mailman.interfaces.usermanager import IUserManager - >>> from zope.component import getAdapter, getUtility + >>> from zope.component import getUtility >>> mlist.send_welcome_message = False >>> fred = getUtility(IUserManager).create_address( ... 'fred@example.com', 'Fred Person') >>> from mailman.interfaces.subscriptions import ISubscriptionManager - >>> registrar = getAdapter(mlist, ISubscriptionManager, name='subscribe') + >>> registrar = ISubscriptionManager(mlist) >>> token, token_owner, member = registrar.register( ... fred, pre_verified=True, pre_confirmed=True, pre_approved=True) >>> member diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py index 2790a6751..15df6b3f3 100644 --- a/src/mailman/app/subscriptions.py +++ b/src/mailman/app/subscriptions.py @@ -297,7 +297,9 @@ class SubscriptionWorkflow(Workflow): # We can immediately subscribe the user to the mailing list. self.member = self.mlist.subscribe(self.subscriber) # This workflow is done so throw away any associated state. - getUtility(IWorkflowStateManager).restore(self.name, self.token) + if self.token is not None: + getUtility(IWorkflowStateManager).discard(self.token) + self._set_token(TokenOwner.no_one) def _step_send_confirmation(self): self._set_token(TokenOwner.subscriber) @@ -533,7 +535,9 @@ class UnSubscriptionWorkflow(Workflow): pass self.member = None # This workflow is done so throw away any associated state. - getUtility(IWorkflowStateManager).restore(self.name, self.token) + if self.token is not None: + getUtility(IWorkflowStateManager).discard(self.token) + self._set_token(TokenOwner.no_one) def _step_unsubscribe_from_restored(self): # Prevent replay attacks. @@ -546,48 +550,11 @@ class UnSubscriptionWorkflow(Workflow): self.push('do_unsubscription') -class BaseSubscriptionManager: - """Base class to handle registration and un-registration workflows.""" - - def __init__(self, mlist): - self._mlist = mlist - - def _get_workflow(self): - raise NotImplementedError - - def register(self, subscriber=None, *, - pre_verified=False, pre_confirmed=False, pre_approved=False): - raise NotImplementedError - - def unregister(self, subscriber=None, *, - pre_confirmed=False, pre_approved=False): - raise NotImplementedError - - def confirm(self, token): - workflow = self._get_workflow() - workflow.token = token - workflow.restore() - # In order to just run the whole workflow, all we need to do - # is iterate over the workflow object. On calling the __next__ - # over the workflow iterator it automatically executes the steps - # that needs to be done. - list(workflow) - return workflow.token, workflow.token_owner, workflow.member - - def discard(self, token): - with flush(): - getUtility(IPendings).confirm(token) - getUtility(IWorkflowStateManager).discard( - self._get_workflow().name, token) - - @public @implementer(ISubscriptionManager) -class SubscriptionManager(BaseSubscriptionManager): - """Handle registrations and confirmations for subscriptions.""" - - def _get_workflow(self): - return SubscriptionWorkflow(self._mlist) +class SubscriptionManager: + def __init__(self, mlist): + self._mlist = mlist def register(self, subscriber=None, *, pre_verified=False, pre_confirmed=False, pre_approved=False): @@ -600,15 +567,6 @@ class SubscriptionManager(BaseSubscriptionManager): list(workflow) return workflow.token, workflow.token_owner, workflow.member - -@public -@implementer(ISubscriptionManager) -class UnsubscriptionManager(BaseSubscriptionManager): - """Handle un-subscriptions and confirmations for un-subscriptions.""" - - def _get_workflow(self): - return UnSubscriptionWorkflow(self._mlist) - def unregister(self, subscriber=None, *, pre_confirmed=False, pre_approved=False): workflow = UnSubscriptionWorkflow( @@ -618,6 +576,32 @@ class UnsubscriptionManager(BaseSubscriptionManager): list(workflow) return workflow.token, workflow.token_owner, workflow.member + def confirm(self, token): + if token is None: + raise LookupError + pendable = getUtility(IPendings).confirm(token, expunge=False) + if pendable is None: + raise LookupError + workflow_type = pendable.get('type') + assert workflow_type in (PendableSubscription.PEND_TYPE, + PendableUnsubscription.PEND_TYPE) + workflow = (SubscriptionWorkflow + if workflow_type == PendableSubscription.PEND_TYPE + else UnSubscriptionWorkflow)(self._mlist) + workflow.token = token + workflow.restore() + # In order to just run the whole workflow, all we need to do + # is iterate over the workflow object. On calling the __next__ + # over the workflow iterator it automatically executes the steps + # that needs to be done. + list(workflow) + return workflow.token, workflow.token_owner, workflow.member + + def discard(self, token): + with flush(): + getUtility(IPendings).confirm(token) + getUtility(IWorkflowStateManager).discard(token) + def _handle_confirmation_needed_events(event, template_name): subject = 'confirm {}'.format(event.token) diff --git a/src/mailman/app/tests/test_moderation.py b/src/mailman/app/tests/test_moderation.py index 63b665948..90485bfad 100644 --- a/src/mailman/app/tests/test_moderation.py +++ b/src/mailman/app/tests/test_moderation.py @@ -35,7 +35,7 @@ from mailman.testing.helpers import ( specialized_message_from_string as mfs) from mailman.testing.layers import SMTPLayer from mailman.utilities.datetime import now -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestModeration(unittest.TestCase): @@ -153,8 +153,7 @@ class TestUnsubscription(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') - self._registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + self._registrar = ISubscriptionManager(self._mlist) def test_unsubscribe_defer(self): # When unsubscriptions must be approved by the moderator, but the diff --git a/src/mailman/app/tests/test_subscriptions.py b/src/mailman/app/tests/test_subscriptions.py index 9f02593a9..a6a00d80e 100644 --- a/src/mailman/app/tests/test_subscriptions.py +++ b/src/mailman/app/tests/test_subscriptions.py @@ -359,8 +359,6 @@ class TestSubscriptionWorkflow(unittest.TestCase): pre_verified=True, pre_confirmed=True, pre_approved=True) - # Cache the token. - token = workflow.token # Consume the entire state machine. list(workflow) # Anne is now a member of the mailing list. @@ -370,13 +368,6 @@ class TestSubscriptionWorkflow(unittest.TestCase): # The workflow is done, so it has no token. self.assertIsNone(workflow.token) self.assertEqual(workflow.token_owner, TokenOwner.no_one) - # The pendable associated with the token has been evicted. - self.assertIsNone(getUtility(IPendings).confirm(token, expunge=False)) - # There is no saved workflow associated with the token. This shows up - # as an exception when we try to restore the workflow. - new_workflow = SubscriptionWorkflow(self._mlist) - new_workflow.token = token - self.assertRaises(LookupError, new_workflow.restore) def test_moderator_approves(self): # The workflow runs until moderator approval is required, at which diff --git a/src/mailman/app/tests/test_unsubscriptions.py b/src/mailman/app/tests/test_unsubscriptions.py index b7693f774..d8dbc18cb 100644 --- a/src/mailman/app/tests/test_unsubscriptions.py +++ b/src/mailman/app/tests/test_unsubscriptions.py @@ -184,7 +184,7 @@ class TestUnSubscriptionWorkflow(unittest.TestCase): self.assertIsNone(workflow.token) self.assertEqual(workflow.token_owner, TokenOwner.no_one) - def test_do_unsubscription_pre_approved_pre_onfirmed(self): + def test_do_unsubscription_pre_approved_pre_confirmed(self): # A moderation-requiring un-subscription policy plus a pre-appvoed # address means the user gets un-subscribed to the mailing list without # any further confirmations or approvals. @@ -201,14 +201,12 @@ class TestUnSubscriptionWorkflow(unittest.TestCase): self.assertEqual(workflow.token_owner, TokenOwner.no_one) def test_do_unsubscription_cleanups(self): - # Once the user is un-subscribed, the token and its associated pending + # Once the user is unsubscribed, the token and its associated pending # database record will be removed from the database. self._mlist.unsubscription_policy = SubscriptionPolicy.open workflow = UnSubscriptionWorkflow(self._mlist, self.anne, pre_approved=True, pre_confirmed=True) - # Cache the token. - token = workflow.token # Run the workflow. list(workflow) # Anne is now un-subscribed from the list. @@ -217,13 +215,6 @@ class TestUnSubscriptionWorkflow(unittest.TestCase): # Workflow is done, so it has no token. self.assertIsNone(workflow.token) self.assertEqual(workflow.token_owner, TokenOwner.no_one) - # The pendable associated with the token as been evicted. - self.assertIsNone(getUtility(IPendings).confirm(token, expunge=False)) - # There is no workflow associated with the token. This shows up as an - # exception when trying to restore the workflow. - new_workflow = UnSubscriptionWorkflow(self._mlist) - new_workflow.token = token - self.assertRaises(LookupError, new_workflow.restore) def test_moderator_approves(self): # The workflow runs until moderator approval is required, at which diff --git a/src/mailman/app/tests/test_workflowmanager.py b/src/mailman/app/tests/test_workflowmanager.py index f72486111..4193beefe 100644 --- a/src/mailman/app/tests/test_workflowmanager.py +++ b/src/mailman/app/tests/test_workflowmanager.py @@ -28,7 +28,7 @@ from mailman.interfaces.usermanager import IUserManager from mailman.testing.helpers import get_queue_messages from mailman.testing.layers import ConfigLayer from mailman.utilities.datetime import now -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestRegistrar(unittest.TestCase): @@ -38,8 +38,7 @@ class TestRegistrar(unittest.TestCase): def setUp(self): self._mlist = create_list('ant@example.com') - self._registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + self._registrar = ISubscriptionManager(self._mlist) self._pendings = getUtility(IPendings) self._anne = getUtility(IUserManager).create_address( 'anne@example.com') diff --git a/src/mailman/app/workflow.py b/src/mailman/app/workflow.py index eec8a14a8..762b0fd91 100644 --- a/src/mailman/app/workflow.py +++ b/src/mailman/app/workflow.py @@ -132,15 +132,11 @@ class Workflow: raise AssertionError( "Can't save a workflow state with more than one step " "in the queue") - state_manager.save( - self.__class__.__name__, - self.token, - step, - json.dumps(data)) + state_manager.save(self.token, step, json.dumps(data)) def restore(self): state_manager = getUtility(IWorkflowStateManager) - state = state_manager.restore(self.__class__.__name__, self.token) + state = state_manager.restore(self.token) if state is None: # The token doesn't exist in the database. raise LookupError(self.token) diff --git a/src/mailman/commands/eml_confirm.py b/src/mailman/commands/eml_confirm.py index b8e1610c4..6787b0987 100644 --- a/src/mailman/commands/eml_confirm.py +++ b/src/mailman/commands/eml_confirm.py @@ -21,7 +21,6 @@ from mailman import public from mailman.core.i18n import _ from mailman.interfaces.command import ContinueProcessing, IEmailCommand from mailman.interfaces.subscriptions import ISubscriptionManager, TokenOwner -from zope.component import getAdapter from zope.interface import implementer @@ -50,8 +49,8 @@ class Confirm: tokens.add(token) results.confirms = tokens try: - new_token, token_owner, member = getAdapter( - mlist, ISubscriptionManager, name='subscribe').confirm(token) + new_token, token_owner, member = ISubscriptionManager( + mlist).confirm(token) if new_token is None: assert token_owner is TokenOwner.no_one, token_owner assert member is not None, member diff --git a/src/mailman/commands/eml_membership.py b/src/mailman/commands/eml_membership.py index 2c535a9d5..e658e7b58 100644 --- a/src/mailman/commands/eml_membership.py +++ b/src/mailman/commands/eml_membership.py @@ -25,7 +25,7 @@ from mailman.interfaces.member import DeliveryMode, MemberRole from mailman.interfaces.subscriptions import ( ISubscriptionManager, ISubscriptionService) from mailman.interfaces.usermanager import IUserManager -from zope.component import getAdapter, getUtility +from zope.component import getUtility from zope.interface import implementer @@ -101,8 +101,7 @@ used. print(_('$person is already a member'), file=results) return ContinueProcessing.yes subscriber = match_subscriber(email, display_name) - getAdapter( - mlist, ISubscriptionManager, name='subscribe').register(subscriber) + ISubscriptionManager(mlist).register(subscriber) print(_('Confirmation email sent to $person'), file=results) return ContinueProcessing.yes @@ -197,7 +196,7 @@ You may be asked to confirm your request.""") return ContinueProcessing.yes # Ignore any subsequent 'leave' commands. already_left.add(email) - manager = getAdapter(mlist, ISubscriptionManager, name='unsubscribe') + manager = ISubscriptionManager(mlist) token, token_owner, member = manager.unregister(user_address) person = formataddr((user.display_name, email)) # noqa if member is None: diff --git a/src/mailman/commands/tests/test_confirm.py b/src/mailman/commands/tests/test_confirm.py index 7351bd6b7..e0f816f24 100644 --- a/src/mailman/commands/tests/test_confirm.py +++ b/src/mailman/commands/tests/test_confirm.py @@ -30,7 +30,7 @@ from mailman.interfaces.usermanager import IUserManager from mailman.runners.command import CommandRunner, Results from mailman.testing.helpers import get_queue_messages, make_testable_runner from mailman.testing.layers import ConfigLayer -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestConfirm(unittest.TestCase): @@ -42,8 +42,8 @@ class TestConfirm(unittest.TestCase): self._mlist = create_list('test@example.com') anne = getUtility(IUserManager).create_address( 'anne@example.com', 'Anne Person') - self._token, token_owner, member = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe').register(anne) + self._token, token_owner, member = ISubscriptionManager( + self._mlist).register(anne) self._command = Confirm() # Clear the virgin queue. get_queue_messages('virgin') @@ -88,8 +88,8 @@ class TestEmailResponses(unittest.TestCase): 'bart@example.com', 'Bart Person') # Clear any previously queued confirmation messages. get_queue_messages('virgin') - self._token, token_owner, member = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe').register(bart) + self._token, token_owner, member = ISubscriptionManager( + self._mlist).register(bart) # There should now be one email message in the virgin queue, i.e. the # confirmation message sent to Bart. items = get_queue_messages('virgin', expected_count=1) diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml index 338f02e1c..2fd0c8788 100644 --- a/src/mailman/config/configure.zcml +++ b/src/mailman/config/configure.zcml @@ -50,14 +50,6 @@ for="mailman.interfaces.mailinglist.IMailingList" provides="mailman.interfaces.subscriptions.ISubscriptionManager" factory="mailman.app.subscriptions.SubscriptionManager" - name='subscribe' - /> - - <adapter - for="mailman.interfaces.mailinglist.IMailingList" - provides="mailman.interfaces.subscriptions.ISubscriptionManager" - factory="mailman.app.subscriptions.UnsubscriptionManager" - name='unsubscribe' /> <utility diff --git a/src/mailman/database/alembic/versions/448a93984c35_unsubscription_workflow.py b/src/mailman/database/alembic/versions/448a93984c35_unsubscription_workflow.py index 85003bd1e..dc57c8aee 100644 --- a/src/mailman/database/alembic/versions/448a93984c35_unsubscription_workflow.py +++ b/src/mailman/database/alembic/versions/448a93984c35_unsubscription_workflow.py @@ -9,7 +9,7 @@ import sqlalchemy as sa from alembic import op from mailman.database.helpers import exists_in_db -from mailman.database.types import Enum +from mailman.database.types import Enum, SAUnicode from mailman.interfaces.mailinglist import SubscriptionPolicy @@ -35,8 +35,11 @@ def upgrade(): op.execute(mlist.update().values( {'unsubscription_policy': op.inline_literal(SubscriptionPolicy.open)})) + with op.batch_alter_table('workflowstate') as batch_op: + batch_op.drop_column('name') def downgrade(): with op.batch_alter_table('mailinglist') as batch_op: batch_op.drop_column('unsubscription_policy') + op.add_column('workflowstate', sa.Column('name', SAUnicode)) diff --git a/src/mailman/interfaces/workflow.py b/src/mailman/interfaces/workflow.py index bf2138959..9846f4683 100644 --- a/src/mailman/interfaces/workflow.py +++ b/src/mailman/interfaces/workflow.py @@ -25,8 +25,6 @@ from zope.interface import Attribute, Interface class IWorkflowState(Interface): """The state of a workflow.""" - name = Attribute('The name of the workflow.') - token = Attribute('A unique key identifying the workflow instance.') step = Attribute("This workflow's next step.") @@ -38,11 +36,9 @@ class IWorkflowState(Interface): class IWorkflowStateManager(Interface): """The workflow states manager.""" - def save(name, token, step, data=None): + def save(token, step, data=None): """Save the state of a workflow. - :param name: The name of the workflow. - :type name: str :param token: A unique token identifying this workflow instance. :type token: str :param step: The next step for this workflow. @@ -51,11 +47,9 @@ class IWorkflowStateManager(Interface): :type data: str """ - def restore(name, token): + def restore(token): """Get the saved state for a workflow or None if nothing was saved. - :param name: The name of the workflow. - :type name: str :param token: A unique token identifying this workflow instance. :type token: str :return: The saved state associated with this name/token pair, or None @@ -63,11 +57,9 @@ class IWorkflowStateManager(Interface): :rtype: ``IWorkflowState`` """ - def discard(name, token): + def discard(token): """Throw away the saved state for a workflow. - :param name: The name of the workflow. - :type name: str :param token: A unique token identifying this workflow instance. :type token: str """ diff --git a/src/mailman/model/docs/subscriptions.rst b/src/mailman/model/docs/subscriptions.rst index 4c079d542..1e1810a7a 100644 --- a/src/mailman/model/docs/subscriptions.rst +++ b/src/mailman/model/docs/subscriptions.rst @@ -13,9 +13,8 @@ To begin, adapt a mailing list to an ``ISubscriptionManager``. This is a named interface because the same interface manages both subscriptions and unsubscriptions. - >>> from zope.component import getAdapter >>> mlist = create_list('ant@example.com') - >>> manager = getAdapter(mlist, ISubscriptionManager, 'subscribe') + >>> manager = ISubscriptionManager(mlist) Either addresses or users with a preferred address can be registered. @@ -114,7 +113,7 @@ that their email address is already verified, that step is not required. To begin with unsubscribing, you need to adapt the mailing list to the same interface, but with a different name. - >>> manager = getAdapter(mlist, ISubscriptionManager, 'unsubscribe') + >>> manager = ISubscriptionManager(mlist) If the mailing list's unsubscription policy is open, unregistering the subscription takes effect immediately. diff --git a/src/mailman/model/pending.py b/src/mailman/model/pending.py index 9d8315605..7e7f0b2eb 100644 --- a/src/mailman/model/pending.py +++ b/src/mailman/model/pending.py @@ -130,8 +130,8 @@ class Pendings: # Iterate on PendedKeyValue entries that are associated with the # pending object's ID. Watch out for type conversions. for keyvalue in pending.key_values: - # The `type` key is special and served. It is not JSONified. See - # the IPendable interface for details. + # The `type` key is special and reserved. It is not JSONified. + # See the IPendable interface for details. if keyvalue.key == 'type': value = keyvalue.value else: diff --git a/src/mailman/model/tests/test_workflow.py b/src/mailman/model/tests/test_workflow.py index ee14f17a7..6aade980b 100644 --- a/src/mailman/model/tests/test_workflow.py +++ b/src/mailman/model/tests/test_workflow.py @@ -32,116 +32,88 @@ class TestWorkflow(unittest.TestCase): def test_save_restore_workflow(self): # Save and restore a workflow. - name = 'ant' token = 'bee' step = 'cat' data = 'dog' - self._manager.save(name, token, step, data) - state = self._manager.restore(name, token) - self.assertEqual(state.name, name) + self._manager.save(token, step, data) + state = self._manager.restore(token) self.assertEqual(state.token, token) self.assertEqual(state.step, step) self.assertEqual(state.data, data) def test_save_restore_workflow_without_step(self): # Save and restore a workflow that contains no step. - name = 'ant' token = 'bee' data = 'dog' - self._manager.save(name, token, data=data) - state = self._manager.restore(name, token) - self.assertEqual(state.name, name) + self._manager.save(token, data=data) + state = self._manager.restore(token) self.assertEqual(state.token, token) self.assertIsNone(state.step) self.assertEqual(state.data, data) def test_save_restore_workflow_without_data(self): # Save and restore a workflow that contains no data. - name = 'ant' token = 'bee' step = 'cat' - self._manager.save(name, token, step) - state = self._manager.restore(name, token) - self.assertEqual(state.name, name) + self._manager.save(token, step) + state = self._manager.restore(token) self.assertEqual(state.token, token) self.assertEqual(state.step, step) self.assertIsNone(state.data) def test_save_restore_workflow_without_step_or_data(self): # Save and restore a workflow that contains no step or data. - name = 'ant' token = 'bee' - self._manager.save(name, token) - state = self._manager.restore(name, token) - self.assertEqual(state.name, name) + self._manager.save(token) + state = self._manager.restore(token) self.assertEqual(state.token, token) self.assertIsNone(state.step) self.assertIsNone(state.data) - def test_restore_workflow_with_no_matching_name(self): - # Try to restore a workflow that has no matching name in the database. - name = 'ant' - token = 'bee' - self._manager.save(name, token) - state = self._manager.restore('ewe', token) - self.assertIsNone(state) - def test_restore_workflow_with_no_matching_token(self): # Try to restore a workflow that has no matching token in the database. - name = 'ant' - token = 'bee' - self._manager.save(name, token) - state = self._manager.restore(name, 'fly') - self.assertIsNone(state) - - def test_restore_workflow_with_no_matching_token_or_name(self): - # Try to restore a workflow that has no matching token or name in the - # database. - name = 'ant' token = 'bee' - self._manager.save(name, token) - state = self._manager.restore('ewe', 'fly') + self._manager.save(token) + state = self._manager.restore('fly') self.assertIsNone(state) def test_restore_removes_record(self): - name = 'ant' token = 'bee' self.assertEqual(self._manager.count, 0) - self._manager.save(name, token) + self._manager.save(token) self.assertEqual(self._manager.count, 1) - self._manager.restore(name, token) + self._manager.restore(token) self.assertEqual(self._manager.count, 0) def test_save_after_restore(self): - name = 'ant' token = 'bee' self.assertEqual(self._manager.count, 0) - self._manager.save(name, token) + self._manager.save(token) self.assertEqual(self._manager.count, 1) - self._manager.restore(name, token) + self._manager.restore(token) self.assertEqual(self._manager.count, 0) - self._manager.save(name, token) + self._manager.save(token) self.assertEqual(self._manager.count, 1) def test_discard(self): # Discard some workflow state. This is use by # ISubscriptionManager.discard(). - self._manager.save('ant', 'token', 'one') - self._manager.save('bee', 'token', 'two') - self._manager.save('ant', 'nekot', 'three') - self._manager.save('bee', 'nekot', 'four') + self._manager.save('token1', 'one') + self._manager.save('token2', 'two') + self._manager.save('token3', 'three') + self._manager.save('token4', 'four') self.assertEqual(self._manager.count, 4) - self._manager.discard('bee', 'token') + self._manager.discard('token2') self.assertEqual(self._manager.count, 3) - state = self._manager.restore('ant', 'token') + state = self._manager.restore('token1') self.assertEqual(state.step, 'one') - state = self._manager.restore('bee', 'token') + state = self._manager.restore('token2') self.assertIsNone(state) - state = self._manager.restore('ant', 'nekot') + state = self._manager.restore('token3') self.assertEqual(state.step, 'three') - state = self._manager.restore('bee', 'nekot') + state = self._manager.restore('token4') self.assertEqual(state.step, 'four') def test_discard_missing_workflow(self): - self._manager.discard('bogus-name', 'bogus-token') + self._manager.discard('bogus-token') self.assertEqual(self._manager.count, 0) diff --git a/src/mailman/model/workflow.py b/src/mailman/model/workflow.py index 1072fa548..53763a0e8 100644 --- a/src/mailman/model/workflow.py +++ b/src/mailman/model/workflow.py @@ -33,7 +33,6 @@ class WorkflowState(Model): __tablename__ = 'workflowstate' - name = Column(SAUnicode, primary_key=True) token = Column(SAUnicode, primary_key=True) step = Column(SAUnicode) data = Column(SAUnicode) @@ -45,23 +44,23 @@ class WorkflowStateManager: """See `IWorkflowStateManager`.""" @dbconnection - def save(self, store, name, token, step=None, data=None): + def save(self, store, token, step=None, data=None): """See `IWorkflowStateManager`.""" - state = WorkflowState(name=name, token=token, step=step, data=data) + state = WorkflowState(token=token, step=step, data=data) store.add(state) @dbconnection - def restore(self, store, name, token): + def restore(self, store, token): """See `IWorkflowStateManager`.""" - state = store.query(WorkflowState).get((name, token)) + state = store.query(WorkflowState).get(token) if state is not None: store.delete(state) return state @dbconnection - def discard(self, store, name, token): + def discard(self, store, token): """See `IWorkflowStateManager`.""" - state = store.query(WorkflowState).get((name, token)) + state = store.query(WorkflowState).get(token) if state is not None: store.delete(state) diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py index fd9f141cc..b35440af4 100644 --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -37,7 +37,7 @@ from mailman.rest.preferences import Preferences, ReadOnlyPreferences from mailman.rest.validator import ( Validator, enum_validator, subscriber_validator) from uuid import UUID -from zope.component import getAdapter, getUtility +from zope.component import getUtility class _MemberBase(CollectionMixin): @@ -253,8 +253,7 @@ class AllMembers(_MemberBase): # Now we can run the registration process until either the # subscriber is subscribed, or the workflow is paused for # verification, confirmation, or approval. - registrar = getAdapter( - mlist, ISubscriptionManager, name='subscribe') + registrar = ISubscriptionManager(mlist) try: token, token_owner, member = registrar.register( subscriber, diff --git a/src/mailman/rest/sub_moderation.py b/src/mailman/rest/sub_moderation.py index 273d4c3a0..55b6a7609 100644 --- a/src/mailman/rest/sub_moderation.py +++ b/src/mailman/rest/sub_moderation.py @@ -28,7 +28,7 @@ from mailman.rest.helpers import ( CollectionMixin, bad_request, child, conflict, etag, no_content, not_found, okay) from mailman.rest.validator import Validator, enum_validator -from zope.component import getAdapter, getUtility +from zope.component import getUtility class _ModerationBase: @@ -54,8 +54,7 @@ class IndividualRequest(_ModerationBase): def __init__(self, mlist, token): super().__init__() self._mlist = mlist - self._registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + self._registrar = ISubscriptionManager(self._mlist) self._token = token def on_get(self, request, response): diff --git a/src/mailman/rest/tests/test_membership.py b/src/mailman/rest/tests/test_membership.py index 9e5a486f3..f705fdcf6 100644 --- a/src/mailman/rest/tests/test_membership.py +++ b/src/mailman/rest/tests/test_membership.py @@ -34,7 +34,7 @@ from mailman.testing.helpers import ( from mailman.testing.layers import ConfigLayer, RESTLayer from mailman.utilities.datetime import now from urllib.error import HTTPError -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestMembership(unittest.TestCase): @@ -214,8 +214,7 @@ class TestMembership(unittest.TestCase): def test_duplicate_pending_subscription(self): # Issue #199 - a member's subscription is already pending and they try # to subscribe again. - registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + registrar = ISubscriptionManager(self._mlist) with transaction(): self._mlist.subscription_policy = SubscriptionPolicy.moderate anne = self._usermanager.create_address('anne@example.com') @@ -238,8 +237,7 @@ class TestMembership(unittest.TestCase): # Issue #199 - a member's subscription is already pending and they try # to subscribe again. Unlike above, this pend is waiting for the user # to confirm their subscription. - registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + registrar = ISubscriptionManager(self._mlist) with transaction(): self._mlist.subscription_policy = ( SubscriptionPolicy.confirm_then_moderate) diff --git a/src/mailman/rest/tests/test_moderation.py b/src/mailman/rest/tests/test_moderation.py index cbf9c9381..e0c3f1ccf 100644 --- a/src/mailman/rest/tests/test_moderation.py +++ b/src/mailman/rest/tests/test_moderation.py @@ -32,7 +32,7 @@ from mailman.testing.helpers import ( specialized_message_from_string as mfs) from mailman.testing.layers import RESTLayer from urllib.error import HTTPError -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestPostModeration(unittest.TestCase): @@ -150,8 +150,7 @@ class TestSubscriptionModeration(unittest.TestCase): def setUp(self): with transaction(): self._mlist = create_list('ant@example.com') - self._registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + self._registrar = ISubscriptionManager(self._mlist) manager = getUtility(IUserManager) self._anne = manager.create_address( 'anne@example.com', 'Anne Person') diff --git a/src/mailman/runners/docs/command.rst b/src/mailman/runners/docs/command.rst index fec0d628b..2243d4ff4 100644 --- a/src/mailman/runners/docs/command.rst +++ b/src/mailman/runners/docs/command.rst @@ -141,9 +141,8 @@ address, and the other is the results of his email command. 2 >>> from mailman.interfaces.subscriptions import ISubscriptionManager - >>> from zope.component import getAdapter - >>> manager = getAdapter(mlist, ISubscriptionManager, 'subscribe') + >>> manager = ISubscriptionManager(mlist) >>> for item in messages: ... subject = item.msg['subject'] ... print('Subject:', subject) diff --git a/src/mailman/runners/tests/test_confirm.py b/src/mailman/runners/tests/test_confirm.py index bb18914d0..af6f03eb5 100644 --- a/src/mailman/runners/tests/test_confirm.py +++ b/src/mailman/runners/tests/test_confirm.py @@ -31,7 +31,7 @@ from mailman.testing.helpers import ( get_queue_messages, make_testable_runner, specialized_message_from_string as mfs) from mailman.testing.layers import ConfigLayer -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestConfirm(unittest.TestCase): @@ -47,8 +47,7 @@ class TestConfirm(unittest.TestCase): self._mlist = create_list('test@example.com') self._mlist.send_welcome_message = False anne = getUtility(IUserManager).create_address('anne@example.org') - registrar = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe') + registrar = ISubscriptionManager(self._mlist) self._token, token_owner, member = registrar.register(anne) def test_confirm_with_re_prefix(self): diff --git a/src/mailman/runners/tests/test_join.py b/src/mailman/runners/tests/test_join.py index 1fb1dfe5c..1e249d68f 100644 --- a/src/mailman/runners/tests/test_join.py +++ b/src/mailman/runners/tests/test_join.py @@ -31,7 +31,7 @@ from mailman.testing.helpers import ( get_queue_messages, make_testable_runner, specialized_message_from_string as mfs) from mailman.testing.layers import ConfigLayer -from zope.component import getAdapter, getUtility +from zope.component import getUtility class TestJoin(unittest.TestCase): @@ -145,8 +145,8 @@ class TestJoinWithDigests(unittest.TestCase): subject_words = str(items[1].msg['subject']).split() self.assertEqual(subject_words[0], 'confirm') token = subject_words[1] - token, token_owner, rmember = getAdapter( - self._mlist, ISubscriptionManager, name='subscribe').confirm(token) + token, token_owner, rmember = ISubscriptionManager( + self._mlist).confirm(token) self.assertIsNone(token) self.assertEqual(token_owner, TokenOwner.no_one) # Now, make sure that Anne is a member of the list and is receiving |
