summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman_pgp/commands/eml_key.py2
-rw-r--r--src/mailman_pgp/commands/tests/test_key.py2
-rw-r--r--src/mailman_pgp/workflows/key_change.py15
-rw-r--r--src/mailman_pgp/workflows/key_confirm.py (renamed from src/mailman_pgp/workflows/pubkey.py)73
-rw-r--r--src/mailman_pgp/workflows/key_set.py79
-rw-r--r--src/mailman_pgp/workflows/mod_approval.py74
-rw-r--r--src/mailman_pgp/workflows/subscription.py21
-rw-r--r--src/mailman_pgp/workflows/tests/test_base.py4
-rw-r--r--src/mailman_pgp/workflows/tests/test_mod_approval.py13
9 files changed, 202 insertions, 81 deletions
diff --git a/src/mailman_pgp/commands/eml_key.py b/src/mailman_pgp/commands/eml_key.py
index 2bc00c7..417fd95 100644
--- a/src/mailman_pgp/commands/eml_key.py
+++ b/src/mailman_pgp/commands/eml_key.py
@@ -41,7 +41,7 @@ from mailman_pgp.utils.pgp import key_usable
from mailman_pgp.workflows.key_change import (CHANGE_CONFIRM_REQUEST,
KeyChangeModWorkflow,
KeyChangeWorkflow)
-from mailman_pgp.workflows.pubkey import CONFIRM_REQUEST
+from mailman_pgp.workflows.key_confirm import CONFIRM_REQUEST
def _cmd_set(pgp_list, mlist, msg, msgdata, arguments, results):
diff --git a/src/mailman_pgp/commands/tests/test_key.py b/src/mailman_pgp/commands/tests/test_key.py
index 900af7b..f6e4edf 100644
--- a/src/mailman_pgp/commands/tests/test_key.py
+++ b/src/mailman_pgp/commands/tests/test_key.py
@@ -41,7 +41,7 @@ from mailman_pgp.pgp.wrapper import PGPWrapper
from mailman_pgp.testing.layers import PGPConfigLayer
from mailman_pgp.testing.pgp import load_key
from mailman_pgp.workflows.key_change import CHANGE_CONFIRM_REQUEST
-from mailman_pgp.workflows.pubkey import CONFIRM_REQUEST
+from mailman_pgp.workflows.key_confirm import CONFIRM_REQUEST
from mailman_pgp.workflows.subscription import OpenSubscriptionPolicy
diff --git a/src/mailman_pgp/workflows/key_change.py b/src/mailman_pgp/workflows/key_change.py
index 8536304..fce7b71 100644
--- a/src/mailman_pgp/workflows/key_change.py
+++ b/src/mailman_pgp/workflows/key_change.py
@@ -32,7 +32,8 @@ from mailman_pgp.model.address import PGPAddress
from mailman_pgp.model.list import PGPMailingList
from mailman_pgp.pgp.wrapper import PGPWrapper
from mailman_pgp.utils.email import copy_headers
-from mailman_pgp.workflows.mod_approval import ModeratorApprovalMixin
+from mailman_pgp.workflows.mod_approval import (
+ ModeratorKeyChangeApprovalMixin)
CHANGE_CONFIRM_REQUEST = """\
----------
@@ -150,10 +151,20 @@ class KeyChangeWorkflow(KeyChangeBase):
@public
@implementer(IWorkflow)
-class KeyChangeModWorkflow(KeyChangeBase, ModeratorApprovalMixin):
+class KeyChangeModWorkflow(KeyChangeBase, ModeratorKeyChangeApprovalMixin):
name = 'pgp-key-change-mod-workflow'
description = ''
initial_state = 'prepare'
+ save_attributes = (
+ 'approved',
+ 'address_key',
+ 'pubkey_key'
+ )
+
+ def __init__(self, mlist, pgp_address=None, pubkey=None,
+ pre_approved=False):
+ KeyChangeBase.__init__(self, mlist, pgp_address, pubkey)
+ ModeratorKeyChangeApprovalMixin.__init__(self, pre_approved)
def _step_prepare(self):
self.push('do_change')
diff --git a/src/mailman_pgp/workflows/pubkey.py b/src/mailman_pgp/workflows/key_confirm.py
index 65ea74d..b8ac51e 100644
--- a/src/mailman_pgp/workflows/pubkey.py
+++ b/src/mailman_pgp/workflows/key_confirm.py
@@ -1,6 +1,23 @@
+# Copyright (C) 2017 Jan Jancar
+#
+# This file is a part of the Mailman PGP plugin.
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+
+""""""
from mailman.email.message import UserNotification
from mailman.interfaces.subscriptions import TokenOwner
-from pgpy import PGPKey
from public import public
from mailman_pgp.database import transaction
@@ -9,13 +26,6 @@ from mailman_pgp.model.list import PGPMailingList
from mailman_pgp.pgp.wrapper import PGPWrapper
from mailman_pgp.utils.email import copy_headers
-KEY_REQUEST = """\
-----------
-TODO: this is a pgp enabled list.
-We need your pubkey.
-Reply to this message with it as a PGP/MIME(preferred) or inline.
-----------"""
-
CONFIRM_REQUEST = """\
----------
TODO: this is a pgp enabled list.
@@ -29,53 +39,6 @@ Token: {}
@public
-class SetPubkeyMixin:
- def __init__(self, pubkey=None):
- self.pubkey = pubkey
-
- @property
- def pubkey_key(self):
- if self.pubkey is None:
- return None
- return str(self.pubkey)
-
- @pubkey_key.setter
- def pubkey_key(self, value):
- if value is not None:
- self.pubkey, _ = PGPKey.from_blob(value)
- else:
- self.pubkey = None
-
- def _step_pubkey_checks(self):
- pgp_address = PGPAddress.for_address(self.address)
- assert pgp_address is not None
-
- if self.pubkey is None:
- if pgp_address.key is None:
- self.push('send_key_request')
- else:
- with transaction():
- pgp_address.key = self.pubkey
-
- def _step_send_key_request(self):
- self._set_token(TokenOwner.subscriber)
- self.push('receive_key')
- self.save()
- request_address = self.mlist.request_address
- email_address = self.address.email
- msg = UserNotification(email_address, request_address,
- 'key set {}'.format(self.token),
- KEY_REQUEST)
- msg.send(self.mlist, add_precedence=False)
- # Now we wait for the confirmation.
- raise StopIteration
-
- def _step_receive_key(self):
- self._restore_subscriber()
- self._set_token(TokenOwner.no_one)
-
-
-@public
class ConfirmPubkeyMixin:
def __init__(self, pre_confirmed=False):
self.pubkey_confirmed = pre_confirmed
diff --git a/src/mailman_pgp/workflows/key_set.py b/src/mailman_pgp/workflows/key_set.py
new file mode 100644
index 0000000..e76e299
--- /dev/null
+++ b/src/mailman_pgp/workflows/key_set.py
@@ -0,0 +1,79 @@
+# Copyright (C) 2017 Jan Jancar
+#
+# This file is a part of the Mailman PGP plugin.
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>.
+
+""""""
+from mailman.email.message import UserNotification
+from mailman.interfaces.subscriptions import TokenOwner
+from pgpy import PGPKey
+from public import public
+
+from mailman_pgp.database import transaction
+from mailman_pgp.model.address import PGPAddress
+
+KEY_REQUEST = """\
+----------
+TODO: this is a pgp enabled list.
+We need your pubkey.
+Reply to this message with it as a PGP/MIME(preferred) or inline.
+----------"""
+
+
+@public
+class SetPubkeyMixin:
+ def __init__(self, pubkey=None):
+ self.pubkey = pubkey
+
+ @property
+ def pubkey_key(self):
+ if self.pubkey is None:
+ return None
+ return str(self.pubkey)
+
+ @pubkey_key.setter
+ def pubkey_key(self, value):
+ if value is not None:
+ self.pubkey, _ = PGPKey.from_blob(value)
+ else:
+ self.pubkey = None
+
+ def _step_pubkey_checks(self):
+ pgp_address = PGPAddress.for_address(self.address)
+ assert pgp_address is not None
+
+ if self.pubkey is None:
+ if pgp_address.key is None:
+ self.push('send_key_request')
+ else:
+ with transaction():
+ pgp_address.key = self.pubkey
+
+ def _step_send_key_request(self):
+ self._set_token(TokenOwner.subscriber)
+ self.push('receive_key')
+ self.save()
+ request_address = self.mlist.request_address
+ email_address = self.address.email
+ msg = UserNotification(email_address, request_address,
+ 'key set {}'.format(self.token),
+ KEY_REQUEST)
+ msg.send(self.mlist, add_precedence=False)
+ # Now we wait for the confirmation.
+ raise StopIteration
+
+ def _step_receive_key(self):
+ self._restore_subscriber()
+ self._set_token(TokenOwner.no_one)
diff --git a/src/mailman_pgp/workflows/mod_approval.py b/src/mailman_pgp/workflows/mod_approval.py
index 90edf4c..f610c4c 100644
--- a/src/mailman_pgp/workflows/mod_approval.py
+++ b/src/mailman_pgp/workflows/mod_approval.py
@@ -17,40 +17,77 @@
""""""
import copy
+from enum import Enum
from mailman.email.message import UserNotification
+from mailman.interfaces.pending import IPendings
from mailman.interfaces.subscriptions import TokenOwner
from public import public
+from zope.component import getUtility
from mailman_pgp.pgp.mime import MIMEWrapper
from mailman_pgp.utils.email import overwrite_message
-MOD_APPROVAL_REQUEST = """\
+SUBSCRIPTION_MOD_REQUEST = """\
----------
TODO: this is a pgp enabled list.
-A subscriber with address {} requested a change of his key.
+A user with address {address} requested subscription
His new key is attached to this message.
-Fingerprint: {}
+Fingerprint: {new_fpr}
----------
"""
+KEY_CHANGE_MOD_REQUEST = """\
+----------
+TODO: this is a pgp enabled list.
+A subscriber with address {address} requested a change of his key.
+His new key is attached to this message.
+
+Old key fingerprint: {old_fpr}
+New key fingerprint: {new_fpr}
+----------
+"""
+
+
+@public
+class WhichApproval(Enum):
+ subscription = 1
+ key_change = 2
+
@public
class ModeratorApprovalMixin:
+ def __init__(self, approval_type, pre_approved=False):
+ self.approved = pre_approved
+ self._approval_type = approval_type
+
def _step_mod_approval(self):
- self.push('get_approval')
+ if not self.approved:
+ self.push('get_approval')
def _step_get_approval(self):
self._pend(TokenOwner.moderator)
- self.push('receive_confirmation')
+ self.push('receive_mod_confirmation')
self.save()
+ params = {'mlist': self.mlist.fqdn_listname,
+ 'address': self.pgp_address.email}
+
+ if self._approval_type is WhichApproval.subscription:
+ name = 'subscription'
+ body = SUBSCRIPTION_MOD_REQUEST
+ params['old_fpr'] = params['new_fpr'] = self.pubkey.fingerprint
+ else:
+ name = 'key change'
+ body = KEY_CHANGE_MOD_REQUEST
+ params['old_fpr'] = self.pgp_address.key_fingerprint
+ params['new_fpr'] = self.pubkey.fingerprint
+
if self.mlist.admin_immed_notify:
- subject = 'New key change request from {}'.format(
- self.pgp_address.email)
- text = MOD_APPROVAL_REQUEST.format(self.pgp_address.email,
- self.pubkey.fingerprint)
+ subject = 'New {} request from {}'.format(name,
+ self.pgp_address.email)
+ text = body.format(**params)
msg = UserNotification(
self.mlist.owner_address, self.mlist.owner_address,
subject, text, self.mlist.preferred_language)
@@ -60,3 +97,22 @@ class ModeratorApprovalMixin:
overwrite_message(msg, out)
out.send(self.mlist)
raise StopIteration
+
+ def _step_receive_mod_confirmation(self):
+ pendings = getUtility(IPendings)
+ if self.token is not None:
+ pendings.confirm(self.token)
+ self.token = None
+ self.token_owner = TokenOwner.no_one
+
+
+@public
+class ModeratorSubApprovalMixin(ModeratorApprovalMixin):
+ def __init__(self, pre_approved=False):
+ super().__init__(WhichApproval.subscription, pre_approved)
+
+
+@public
+class ModeratorKeyChangeApprovalMixin(ModeratorApprovalMixin):
+ def __init__(self, pre_approved=False):
+ super().__init__(WhichApproval.key_change, pre_approved)
diff --git a/src/mailman_pgp/workflows/subscription.py b/src/mailman_pgp/workflows/subscription.py
index 809b7cb..d5803c2 100644
--- a/src/mailman_pgp/workflows/subscription.py
+++ b/src/mailman_pgp/workflows/subscription.py
@@ -19,13 +19,15 @@
from mailman.core.i18n import _
from mailman.interfaces.workflows import ISubscriptionWorkflow
-from mailman.workflows.common import (ConfirmationMixin, ModerationMixin,
- SubscriptionBase, VerificationMixin)
+from mailman.workflows.common import (ConfirmationMixin, SubscriptionBase,
+ VerificationMixin)
from public import public
from zope.interface import implementer
from mailman_pgp.workflows.base import PGPMixin
-from mailman_pgp.workflows.pubkey import ConfirmPubkeyMixin, SetPubkeyMixin
+from mailman_pgp.workflows.key_confirm import ConfirmPubkeyMixin
+from mailman_pgp.workflows.key_set import SetPubkeyMixin
+from mailman_pgp.workflows.mod_approval import ModeratorSubApprovalMixin
@public
@@ -112,7 +114,7 @@ class ConfirmSubscriptionPolicy(SubscriptionBase, VerificationMixin,
@public
@implementer(ISubscriptionWorkflow)
class ModerationSubscriptionPolicy(SubscriptionBase, VerificationMixin,
- ModerationMixin, SetPubkeyMixin,
+ ModeratorSubApprovalMixin, SetPubkeyMixin,
ConfirmPubkeyMixin, PGPMixin):
""""""
@@ -136,14 +138,14 @@ class ModerationSubscriptionPolicy(SubscriptionBase, VerificationMixin,
pubkey_pre_confirmed=False):
SubscriptionBase.__init__(self, mlist, subscriber)
VerificationMixin.__init__(self, pre_verified=pre_verified)
- ModerationMixin.__init__(self, pre_approved=pre_approved)
+ ModeratorSubApprovalMixin.__init__(self, pre_approved=pre_approved)
SetPubkeyMixin.__init__(self, pubkey=pubkey)
ConfirmPubkeyMixin.__init__(self, pre_confirmed=pubkey_pre_confirmed)
PGPMixin.__init__(self)
def _step_prepare(self):
self.push('do_subscription')
- self.push('moderation_checks')
+ self.push('mod_approval')
self.push('pubkey_confirmation')
self.push('pubkey_checks')
self.push('pgp_prepare')
@@ -154,7 +156,8 @@ class ModerationSubscriptionPolicy(SubscriptionBase, VerificationMixin,
@public
@implementer(ISubscriptionWorkflow)
class ConfirmModerationSubscriptionPolicy(SubscriptionBase, VerificationMixin,
- ConfirmationMixin, ModerationMixin,
+ ConfirmationMixin,
+ ModeratorSubApprovalMixin,
SetPubkeyMixin, ConfirmPubkeyMixin,
PGPMixin):
""""""
@@ -181,14 +184,14 @@ class ConfirmModerationSubscriptionPolicy(SubscriptionBase, VerificationMixin,
SubscriptionBase.__init__(self, mlist, subscriber)
VerificationMixin.__init__(self, pre_verified=pre_verified)
ConfirmationMixin.__init__(self, pre_confirmed=pre_confirmed)
- ModerationMixin.__init__(self, pre_approved=pre_approved)
+ ModeratorSubApprovalMixin.__init__(self, pre_approved=pre_approved)
SetPubkeyMixin.__init__(self, pubkey=pubkey)
ConfirmPubkeyMixin.__init__(self, pre_confirmed=pubkey_pre_confirmed)
PGPMixin.__init__(self)
def _step_prepare(self):
self.push('do_subscription')
- self.push('moderation_checks')
+ self.push('mod_approval')
self.push('pubkey_confirmation')
self.push('pubkey_checks')
self.push('pgp_prepare')
diff --git a/src/mailman_pgp/workflows/tests/test_base.py b/src/mailman_pgp/workflows/tests/test_base.py
index 5273939..440068c 100644
--- a/src/mailman_pgp/workflows/tests/test_base.py
+++ b/src/mailman_pgp/workflows/tests/test_base.py
@@ -37,8 +37,8 @@ from mailman_pgp.pgp.wrapper import PGPWrapper
from mailman_pgp.testing.layers import PGPConfigLayer
from mailman_pgp.testing.pgp import load_key
from mailman_pgp.workflows.base import (PGPMixin)
-from mailman_pgp.workflows.pubkey import (ConfirmPubkeyMixin, KEY_REQUEST,
- SetPubkeyMixin)
+from mailman_pgp.workflows.key_confirm import ConfirmPubkeyMixin
+from mailman_pgp.workflows.key_set import KEY_REQUEST, SetPubkeyMixin
class PubkeyMixinTestSetup():
diff --git a/src/mailman_pgp/workflows/tests/test_mod_approval.py b/src/mailman_pgp/workflows/tests/test_mod_approval.py
index 49e4204..7d57a9b 100644
--- a/src/mailman_pgp/workflows/tests/test_mod_approval.py
+++ b/src/mailman_pgp/workflows/tests/test_mod_approval.py
@@ -33,14 +33,23 @@ from mailman_pgp.pgp.wrapper import PGPWrapper
from mailman_pgp.testing.layers import PGPConfigLayer
from mailman_pgp.testing.pgp import load_key
from mailman_pgp.workflows.key_change import KeyChangeBase
-from mailman_pgp.workflows.mod_approval import ModeratorApprovalMixin
+from mailman_pgp.workflows.mod_approval import (
+ ModeratorKeyChangeApprovalMixin)
@implementer(IWorkflow)
-class PGPTestWorkflow(KeyChangeBase, ModeratorApprovalMixin):
+class PGPTestWorkflow(KeyChangeBase, ModeratorKeyChangeApprovalMixin):
name = 'test-workflow'
description = ''
initial_state = 'mod_approval'
+ save_attributes = (
+ 'approved',
+ )
+
+ def __init__(self, mlist, pgp_address=None, pubkey=None,
+ pre_approved=False):
+ KeyChangeBase.__init__(self, mlist, pgp_address, pubkey)
+ ModeratorKeyChangeApprovalMixin.__init__(self, pre_approved)
class TestModeratorApprovalMixin(TestCase):