1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
import json
from twisted.python import log
from leap.common.check import leap_assert, leap_assert_type
from leap.soledad import Soledad
from leap.common.keymanager import openpgp
class LeapIncomingMail(object):
"""
Fetches mail from the incoming queue.
"""
def __init__(self, keymanager, soledad, imap_account):
"""
Initialize LeapIMAP.
:param keymanager: a keymanager instance
:type keymanager: keymanager.KeyManager
:param soledad: a soledad instance
:type soledad: Soledad
:param imap_account: the account to fetch periodically
:type imap_account: SoledadBackedAccount
"""
leap_assert(keymanager, "need a keymanager to initialize")
leap_assert_type(soledad, Soledad)
self._keymanager = keymanager
self._soledad = soledad
self.imapAccount = imap_account
self._pkey = self._keymanager.get_all_keys_in_local_db(
private=True).pop()
def fetch(self):
"""
Get new mail by syncing database, store it in the INBOX for the
user account, and remove from the incoming db.
"""
self._soledad.sync()
gen, doclist = self._soledad.get_all_docs()
#log.msg("there are %s docs" % (len(doclist),))
if doclist:
inbox = self.imapAccount.getMailbox('inbox')
key = self._pkey
for doc in doclist:
keys = doc.content.keys()
if '_enc_scheme' in keys and '_enc_json' in keys:
# XXX should check for _enc_scheme == "pubkey" || "none"
# that is what incoming mail uses.
encdata = doc.content['_enc_json']
decrdata = openpgp.decrypt_asym(
encdata, key,
# XXX get from public method instead
passphrase=self._soledad._passphrase)
if decrdata:
self.process_decrypted(doc, decrdata, inbox)
# XXX launch sync callback / defer
def process_decrypted(self, doc, data, inbox):
"""
Process a successfully decrypted message
"""
log.msg("processing incoming message!")
msg = json.loads(data)
if not isinstance(msg, dict):
return False
if not msg.get('incoming', False):
return False
# ok, this is an incoming message
rawmsg = msg.get('content', None)
if not rawmsg:
return False
#log.msg("we got raw message")
# add to inbox and delete from soledad
inbox.addMessage(rawmsg, ("\\Recent",))
doc_id = doc.doc_id
self._soledad.delete_doc(doc)
log.msg("deleted doc %s from incoming" % doc_id)
|