Allow pluggable workflows
Currently the way different subscription and unsubscription policies work is through mailinglist
attributes subscription_policy
and unsubscription_policy
. These attributes have a value from the SubscriptionPolicy
enum. Upon user sub/unsubscription a Sub/UnsubscriptionWorkflow
is created for the subscription request. This workflow is a quite complex state machine that sends the user a confirmation request if required, sends a moderation request if required and so, the two subscription and unsubscription workflows currently have much of the code duplicated.
The current architecture cannot be extended very easily and I think it requires some refactoring. For example, with the new plugin architecture, a plugin should be able to provide a custom subscription workflow in order to require some additional plugin-specific steps in the subscription. As currently a plugin can hook up almost anywhere in mailman, message processing, commands, REST, etc. but not subscription processing in any way.
Having pluggable workflows would allow a plugin to add steps to the subscription workflow, for example to check that a subscriber is a member of some organization, or, as the mailman-pgp plugin does, to request and confirm the users PGP key.
A solution to this problem should:
- be backward compatible (have DB migrations where necessary, and handle REST so that it doesn't break)
- deduplicate code between the subscription and unsubscription workflows, ideally by splitting them somehow
- make workflows pluggable components, that are dynamically loaded
- allow plugins to add custom workflows, composed of both Mailman provided steps and custom steps
MR !299 does this in a sub-par way, as the workflow expects to find the callable steps as attributes of the workflow instance, this MR splits the workflows into mixin classes.