diff options
Diffstat (limited to 'alot')
-rw-r--r-- | alot/account.py | 12 | ||||
-rw-r--r-- | alot/commands/envelope.py | 27 | ||||
-rw-r--r-- | alot/commands/globals.py | 36 | ||||
-rw-r--r-- | alot/commands/thread.py | 4 | ||||
-rw-r--r-- | alot/commands/utils.py | 32 | ||||
-rw-r--r-- | alot/defaults/alot.rc.spec | 3 |
6 files changed, 82 insertions, 32 deletions
diff --git a/alot/account.py b/alot/account.py index 0e40a816..db1ef288 100644 --- a/alot/account.py +++ b/alot/account.py @@ -50,11 +50,12 @@ class Account(object): managing this accounts contacts""" def __init__(self, address=None, aliases=None, alias_regexp=None, - realname=None, gpg_key=None, signature=None, - signature_filename=None, signature_as_attachment=False, - sent_box=None, sent_tags=['sent'], draft_box=None, - draft_tags=['draft'], abook=None, sign_by_default=False, - **rest): + realname=None, gpg_key=None, signature=None, + signature_filename=None, signature_as_attachment=False, + sent_box=None, sent_tags=['sent'], draft_box=None, + draft_tags=['draft'], abook=None, sign_by_default=False, + encrypt_by_default=False, + **rest): self.address = address self.aliases = aliases self.alias_regexp = alias_regexp @@ -64,6 +65,7 @@ class Account(object): self.signature_filename = signature_filename self.signature_as_attachment = signature_as_attachment self.sign_by_default = sign_by_default + self.encrypt_by_default = encrypt_by_default self.sent_box = sent_box self.sent_tags = sent_tags self.draft_box = draft_box diff --git a/alot/commands/envelope.py b/alot/commands/envelope.py index b90816d2..c72c5fa3 100644 --- a/alot/commands/envelope.py +++ b/alot/commands/envelope.py @@ -12,12 +12,13 @@ from twisted.internet.defer import inlineCallbacks import datetime from alot.account import SendingMailFailed, StoreMailError -from alot.errors import GPGProblem, GPGCode +from alot.errors import GPGProblem from alot import buffers from alot import commands from alot import crypto from alot.commands import Command, registerCommand from alot.commands import globals +from alot.commands.utils import get_keys from alot.helper import string_decode from alot.helper import email_as_string from alot.settings import settings @@ -557,26 +558,10 @@ class EncryptCommand(Command): self.encrypt_keys.append(recipient) logging.debug("encryption keys: " + str(self.encrypt_keys)) - for keyid in self.encrypt_keys: - try: - key = crypto.get_key(keyid, validate=True, encrypt=True) - except GPGProblem as e: - if e.code == GPGCode.AMBIGUOUS_NAME: - possible_keys = crypto.list_keys(hint=keyid) - tmp_choices = [k.uids[0].uid for k in possible_keys] - choices = {str(len(tmp_choices) - x): tmp_choices[x] - for x in range(0, len(tmp_choices))} - keyid = yield ui.choice("ambiguous keyid! Which " + - "key do you want to use?", - choices, cancel=None) - if keyid: - self.encrypt_keys.append(keyid) - continue - else: - ui.notify(e.message, priority='error') - continue - envelope.encrypt_keys[crypto.hash_key(key)] = key - if not envelope.encrypt_keys: + keys = yield get_keys(ui, self.encrypt_keys) + if keys: + envelope.encrypt_keys.update(keys) + else: envelope.encrypt = False # reload buffer ui.current_buffer.rebuild() diff --git a/alot/commands/globals.py b/alot/commands/globals.py index e090f757..26be98fb 100644 --- a/alot/commands/globals.py +++ b/alot/commands/globals.py @@ -2,9 +2,9 @@ # This file is released under the GNU GPL, version 3 or a later revision. # For further details see the COPYING file import os +import re import code from twisted.internet import threads -from twisted.internet import defer import subprocess import email import urwid @@ -16,9 +16,8 @@ from StringIO import StringIO from alot.commands import Command, registerCommand from alot.completion import CommandLineCompleter -from alot.commands import CommandParseError -from alot.commands import commandfactory from alot.commands import CommandCanceled +from alot.commands.utils import get_keys from alot import buffers from alot.widgets.utils import DialogBox from alot import helper @@ -29,7 +28,7 @@ from alot.completion import TagsCompleter from alot.db.envelope import Envelope from alot import commands from alot.settings import settings -from alot.helper import split_commandstring, split_commandline +from alot.helper import split_commandstring from alot.helper import mailto_to_envelope from alot.utils.booleanaction import BooleanAction @@ -647,7 +646,8 @@ class ComposeCommand(Command): """compose a new email""" def __init__(self, envelope=None, headers={}, template=None, sender=u'', subject=u'', to=[], cc=[], bcc=[], attach=None, - omit_signature=False, spawn=None, rest=[], **kwargs): + omit_signature=False, spawn=None, rest=[], + encrypt=False, **kwargs): """ :param envelope: use existing envelope :type envelope: :class:`~alot.db.envelope.Envelope` @@ -677,6 +677,8 @@ class ComposeCommand(Command): 'mailto' in which case it is interpreted as mailto string. Otherwise it will be interpreted as recipients (to) header :type rest: list(str) + :param encrypt: if the email should be encrypted + :type encrypt: bool """ Command.__init__(self, **kwargs) @@ -693,6 +695,7 @@ class ComposeCommand(Command): self.omit_signature = omit_signature self.force_spawn = spawn self.rest = ' '.join(rest) + self.encrypt = encrypt @inlineCallbacks def apply(self, ui): @@ -844,11 +847,34 @@ class ComposeCommand(Command): self.envelope.attach(a) logging.debug('attaching: ' + a) + # set encryption if needed + if self.encrypt or account.encrypt_by_default: + yield self._set_encrypt(ui, self.envelope) + cmd = commands.envelope.EditCommand(envelope=self.envelope, spawn=self.force_spawn, refocus=False) ui.apply_command(cmd) + @inlineCallbacks + def _set_encrypt(self, ui, envelope): + encrypt_keys = [] + for recipient in envelope.headers['To'][0].split(','): + if not recipient: + continue + match = re.search("<(.*@.*)>", recipient) + if match: + recipient = match.group(0) + encrypt_keys.append(recipient) + + logging.debug("encryption keys: " + str(encrypt_keys)) + keys = yield get_keys(ui, encrypt_keys, block_error=self.encrypt) + if keys: + envelope.encrypt_keys.update(keys) + envelope.encrypt = True + else: + envelope.encrypt = False + @registerCommand(MODE, 'move', help='move focus in current buffer', arguments=[(['movement'], { diff --git a/alot/commands/thread.py b/alot/commands/thread.py index 0c8c64f9..1d39fc4d 100644 --- a/alot/commands/thread.py +++ b/alot/commands/thread.py @@ -242,8 +242,10 @@ class ReplyCommand(Command): envelope.add('References', '<%s>' % self.message.get_message_id()) # continue to compose + encrypt = mail.get_content_subtype() == 'encrypted' ui.apply_command(ComposeCommand(envelope=envelope, - spawn=self.force_spawn)) + spawn=self.force_spawn, + encrypt=encrypt)) def clear_my_address(self, my_addresses, value): """return recipient header without the addresses in my_addresses""" diff --git a/alot/commands/utils.py b/alot/commands/utils.py new file mode 100644 index 00000000..a6290671 --- /dev/null +++ b/alot/commands/utils.py @@ -0,0 +1,32 @@ +# Copyright (C) 2015 Patrick Totzke <patricktotzke@gmail.com> +# This file is released under the GNU GPL, version 3 or a later revision. +# For further details see the COPYING file +from twisted.internet.defer import inlineCallbacks, returnValue + +from alot.errors import GPGProblem, GPGCode +from alot import crypto + + +@inlineCallbacks +def get_keys(ui, encrypt_keyids, block_error=False): + keys = {} + for keyid in encrypt_keyids: + try: + key = crypto.get_key(keyid, validate=True, encrypt=True) + except GPGProblem as e: + if e.code == GPGCode.AMBIGUOUS_NAME: + possible_keys = crypto.list_keys(hint=keyid) + tmp_choices = [k.uids[0].uid for k in possible_keys] + choices = {str(len(tmp_choices) - x): tmp_choices[x] + for x in range(0, len(tmp_choices))} + keyid = yield ui.choice("ambiguous keyid! Which " + + "key do you want to use?", + choices, cancel=None) + if keyid: + encrypt_keyids.append(keyid) + continue + else: + ui.notify(e.message, priority='error', block=block_error) + continue + keys[crypto.hash_key(key)] = key + returnValue(keys) diff --git a/alot/defaults/alot.rc.spec b/alot/defaults/alot.rc.spec index 77a4df0a..4efc7b4a 100644 --- a/alot/defaults/alot.rc.spec +++ b/alot/defaults/alot.rc.spec @@ -282,6 +282,9 @@ prefer_plaintext = boolean(default=False) # Outgoing messages will be GPG signed by default if this is set to True. sign_by_default = boolean(default=False) + # Outgoing messages will be GPG encrypted by default if this is set to True. + encrypt_by_default = boolean(default=False) + # The GPG key ID you want to use with this account. If unset, alot will # use your default key. gpg_key = gpg_key_hint(default=None) |