Mercurial > libervia-backend
annotate src/plugins/plugin_misc_imap.py @ 513:8ee9113d307b
core, quick_frontend, primitivus, wixi, bridge: fixed delayed message timestamp:
- new "extra" parameter in newMessage signal
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 20 Oct 2012 17:23:56 +0200 |
parents | 2a072735e459 |
children | 89f9a50ce7bf |
rev | line source |
---|---|
253 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
5 SàT plugin for managing imap server |
253 | 6 Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) |
7 | |
8 This program is free software: you can redistribute it and/or modify | |
480
2a072735e459
Licence modification: the full project is now under AGPL v3+ instead of GPL v3+
Goffi <goffi@goffi.org>
parents:
439
diff
changeset
|
9 it under the terms of the GNU Affero General Public License as published by |
253 | 10 the Free Software Foundation, either version 3 of the License, or |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
480
2a072735e459
Licence modification: the full project is now under AGPL v3+ instead of GPL v3+
Goffi <goffi@goffi.org>
parents:
439
diff
changeset
|
16 GNU Affero General Public License for more details. |
253 | 17 |
480
2a072735e459
Licence modification: the full project is now under AGPL v3+ instead of GPL v3+
Goffi <goffi@goffi.org>
parents:
439
diff
changeset
|
18 You should have received a copy of the GNU Affero General Public License |
253 | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 """ | |
21 | |
22 from logging import debug, info, error | |
23 import warnings | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
24 from twisted.internet import protocol,defer |
253 | 25 from twisted.words.protocols.jabber import error as jab_error |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
26 from twisted.cred import portal,checkers,credentials |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
27 from twisted.cred import error as cred_error |
253 | 28 from twisted.mail import imap4 |
260
c8406fe5e81e
Added SMTP server plugin, for sending messages from classic MUA \o/
Goffi <goffi@goffi.org>
parents:
257
diff
changeset
|
29 from twisted.python import failure |
253 | 30 from email.parser import Parser |
31 import email.message | |
32 import os,os.path | |
33 from cStringIO import StringIO | |
34 from twisted.internet import reactor | |
35 import pdb | |
36 | |
37 | |
38 from zope.interface import implements | |
39 | |
40 | |
41 PLUGIN_INFO = { | |
42 "name": "IMAP server Plugin", | |
43 "import_name": "IMAP", | |
44 "type": "Misc", | |
45 "protocols": [], | |
46 "dependencies": ["Maildir"], | |
47 "main": "IMAP_server", | |
48 "handler": "no", | |
49 "description": _("""Create an Imap server that you can use to read your "normal" type messages""") | |
50 } | |
51 | |
52 class IMAP_server(): | |
439
866dbb0d7d87
plugin maildir: maildir now use PersistentBinaryDictionary to store profile specific data
Goffi <goffi@goffi.org>
parents:
412
diff
changeset
|
53 #TODO: connect profile on mailbox request, once password is accepted |
253 | 54 |
55 params = """ | |
56 <params> | |
57 <general> | |
261
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
58 <category name="Mail Server"> |
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
59 <param name="IMAP Port" value="10143" type="string" /> |
253 | 60 </category> |
61 </general> | |
62 </params> | |
63 """ | |
64 | |
65 def __init__(self, host): | |
66 info(_("Plugin Imap Server initialization")) | |
67 self.host = host | |
68 | |
69 #parameters | |
70 host.memory.importParams(self.params) | |
71 | |
261
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
72 port = int(self.host.memory.getParamA("IMAP Port", "Mail Server")) |
253 | 73 info(_("Launching IMAP server on port %d"), port) |
74 | |
75 self.server_factory = ImapServerFactory(self.host) | |
76 reactor.listenTCP(port, self.server_factory) | |
77 | |
78 class Message(): | |
79 implements(imap4.IMessage) | |
80 | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
81 def __init__(self, uid, flags, mess_fp): |
253 | 82 debug('Message Init') |
83 self.uid=uid | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
84 self.flags=flags |
253 | 85 self.mess_fp=mess_fp |
86 self.message=Parser().parse(mess_fp) | |
87 | |
88 def getUID(self): | |
89 """Retrieve the unique identifier associated with this message. | |
90 """ | |
91 debug('getUID (message)') | |
92 return self.uid | |
93 | |
94 def getFlags(self): | |
95 """Retrieve the flags associated with this message. | |
96 @return: The flags, represented as strings. | |
97 """ | |
98 debug('getFlags') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
99 return self.flags |
253 | 100 |
101 def getInternalDate(self): | |
102 """Retrieve the date internally associated with this message. | |
103 @return: An RFC822-formatted date string. | |
104 """ | |
105 debug('getInternalDate') | |
106 return self.message['Date'] | |
107 | |
108 | |
109 def getHeaders(self, negate, *names): | |
110 """Retrieve a group of message headers. | |
111 @param names: The names of the headers to retrieve or omit. | |
112 @param negate: If True, indicates that the headers listed in names | |
113 should be omitted from the return value, rather than included. | |
114 @return: A mapping of header field names to header field values | |
115 """ | |
116 debug('getHeaders %s - %s' % (negate, names)) | |
117 final_dict={} | |
118 to_check=[name.lower() for name in names] | |
119 for header in self.message.keys(): | |
120 if (negate and not header.lower() in to_check) or \ | |
121 (not negate and header.lower() in to_check): | |
122 final_dict[header]=self.message[header] | |
123 return final_dict | |
124 | |
125 def getBodyFile(self): | |
126 """Retrieve a file object containing only the body of this message. | |
127 """ | |
128 debug('getBodyFile') | |
129 return StringIO(self.message.get_payload()) | |
130 | |
131 def getSize(self): | |
132 """Retrieve the total size, in octets, of this message. | |
133 """ | |
134 debug('getSize') | |
135 self.mess_fp.seek(0,os.SEEK_END) | |
136 return self.mess_fp.tell() | |
137 | |
138 | |
139 def isMultipart(self): | |
140 """Indicate whether this message has subparts. | |
141 """ | |
142 debug('isMultipart') | |
143 return False | |
144 | |
145 def getSubPart(self,part): | |
146 """Retrieve a MIME sub-message | |
147 @param part: The number of the part to retrieve, indexed from 0. | |
148 @return: The specified sub-part. | |
149 """ | |
150 debug('getSubPart') | |
151 return TypeError | |
152 | |
153 | |
154 class SatMailbox: | |
155 implements(imap4.IMailbox) | |
156 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
157 def __init__(self,host,name,profile): |
253 | 158 self.host = host |
159 self.listeners=set() | |
160 debug ('Mailbox init (%s)', name) | |
161 if name!="INBOX": | |
162 raise imap4.MailboxException("Only INBOX is managed for the moment") | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
163 self.mailbox=self.host.plugins["Maildir"].accessMessageBox(name,self.newMessage, profile) |
253 | 164 |
165 def newMessage(self): | |
166 """Called when a new message is in the mailbox""" | |
167 debug ("newMessage signal received") | |
168 nb_messages=self.getMessageCount() | |
169 for listener in self.listeners: | |
170 listener.newMessages(nb_messages,None) | |
171 | |
172 def getUIDValidity(self): | |
173 """Return the unique validity identifier for this mailbox. | |
174 """ | |
175 debug ('getUIDValidity') | |
176 return 0 | |
177 | |
178 def getUIDNext(self): | |
179 """Return the likely UID for the next message added to this mailbox. | |
180 """ | |
181 debug ('getUIDNext') | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
182 return self.mailbox.getNextUid() |
253 | 183 |
184 def getUID(self,message): | |
185 """Return the UID of a message in the mailbox | |
186 @param message: The message sequence number | |
187 @return: The UID of the message. | |
188 """ | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
189 debug ('getUID (%i)' % message) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
190 #return self.mailbox.getUid(message-1) #XXX: it seems that this method get uid and not message sequence number |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
191 return message |
253 | 192 |
193 def getMessageCount(self): | |
194 """Return the number of messages in this mailbox. | |
195 """ | |
196 debug('getMessageCount') | |
197 ret = self.mailbox.getMessageCount() | |
198 debug("count = %i" % ret) | |
199 return ret | |
200 | |
201 def getRecentCount(self): | |
202 """Return the number of messages with the 'Recent' flag. | |
203 """ | |
204 debug('getRecentCount') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
205 return len(self.mailbox.getMessageIdsWithFlag('\\Recent')) |
253 | 206 |
207 def getUnseenCount(self): | |
208 """Return the number of messages with the 'Unseen' flag. | |
209 """ | |
210 debug('getUnseenCount') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
211 return self.getMessageCount()-len(self.mailbox.getMessageIdsWithFlag('\\SEEN')) |
253 | 212 |
213 def isWriteable(self): | |
214 """Get the read/write status of the mailbox. | |
215 @return: A true value if write permission is allowed, a false value otherwise. | |
216 """ | |
217 debug('isWriteable') | |
218 return True | |
219 | |
220 def destroy(self): | |
221 """Called before this mailbox is deleted, permanently. | |
222 """ | |
223 debug('destroy') | |
224 | |
225 | |
226 def requestStatus(self, names): | |
227 """Return status information about this mailbox. | |
228 @param names: The status names to return information regarding. | |
229 The possible values for each name are: MESSAGES, RECENT, UIDNEXT, | |
230 UIDVALIDITY, UNSEEN. | |
231 @return: A dictionary containing status information about the | |
232 requested names is returned. If the process of looking this | |
233 information up would be costly, a deferred whose callback will | |
234 eventually be passed this dictionary is returned instead. | |
235 """ | |
236 debug('requestStatus') | |
237 return imap4.statusRequestHelper(self, names) | |
238 | |
239 def addListener(self, listener): | |
240 """Add a mailbox change listener | |
241 | |
242 @type listener: Any object which implements C{IMailboxListener} | |
243 @param listener: An object to add to the set of those which will | |
244 be notified when the contents of this mailbox change. | |
245 """ | |
246 debug('addListener %s' % listener) | |
247 self.listeners.add(listener) | |
248 | |
249 def removeListener(self, listener): | |
250 """Remove a mailbox change listener | |
251 | |
252 @type listener: Any object previously added to and not removed from | |
253 this mailbox as a listener. | |
254 @param listener: The object to remove from the set of listeners. | |
255 | |
256 @raise ValueError: Raised when the given object is not a listener for | |
257 this mailbox. | |
258 """ | |
259 debug('removeListener') | |
260 if listener in self.listeners: | |
261 self.listeners.remove(listener) | |
262 else: | |
263 raise imap4.MailboxException('Trying to remove an unknown listener') | |
264 | |
265 def addMessage(self, message, flags = (), date = None): | |
266 """Add the given message to this mailbox. | |
267 @param message: The RFC822 formatted message | |
268 @param flags: The flags to associate with this message | |
269 @param date: If specified, the date to associate with this | |
270 @return: A deferred whose callback is invoked with the message | |
271 id if the message is added successfully and whose errback is | |
272 invoked otherwise. | |
273 """ | |
274 debug('addMessage') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
275 raise imap4.MailboxException("Client message addition not implemented yet") |
253 | 276 |
277 def expunge(self): | |
278 """Remove all messages flagged \\Deleted. | |
279 @return: The list of message sequence numbers which were deleted, | |
280 or a Deferred whose callback will be invoked with such a list. | |
281 """ | |
282 debug('expunge') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
283 self.mailbox.removeDeleted() |
253 | 284 |
285 def fetch(self, messages, uid): | |
286 """Retrieve one or more messages. | |
287 @param messages: The identifiers of messages to retrieve information | |
288 about | |
289 @param uid: If true, the IDs specified in the query are UIDs; | |
290 """ | |
291 debug('fetch (%s, %s)'%(messages,uid)) | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
292 if uid: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
293 messages.last = self.mailbox.getMaxUid() |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
294 messages.getnext = self.mailbox.getNextExistingUid |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
295 for mess_uid in messages: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
296 if mess_uid == None: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
297 debug ('stopping iteration') |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
298 raise StopIteration |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
299 try: |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
300 yield (mess_uid,Message(mess_uid,self.mailbox.getFlagsUid(mess_uid), self.mailbox.getMessageUid(mess_uid))) |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
301 except IndexError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
302 continue |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
303 else: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
304 messages.last = self.getMessageCount() |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
305 for mess_idx in messages: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
306 if mess_idx>self.getMessageCount(): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
307 raise StopIteration |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
308 yield (mess_idx,Message(mess_idx,self.mailbox.getFlags(mess_idx),self.mailbox.getMessage(mess_idx-1))) |
253 | 309 |
310 def store(self, messages, flags, mode, uid): | |
311 """Set the flags of one or more messages. | |
312 @param messages: The identifiers of the messages to set the flags of. | |
313 @param flags: The flags to set, unset, or add. | |
314 @param mode: If mode is -1, these flags should be removed from the | |
315 specified messages. If mode is 1, these flags should be added to | |
316 the specified messages. If mode is 0, all existing flags should be | |
317 cleared and these flags should be added. | |
318 @param uid: If true, the IDs specified in the query are UIDs; | |
319 otherwise they are message sequence IDs. | |
320 @return: A dict mapping message sequence numbers to sequences of str | |
321 representing the flags set on the message after this operation has | |
322 been performed, or a Deferred whose callback will be invoked with | |
323 such a dict. | |
324 """ | |
325 debug('store') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
326 |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
327 flags=[flag.upper() for flag in flags] |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
328 |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
329 def updateFlags(getF,setF): |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
330 ret = {} |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
331 for mess_id in messages: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
332 if (uid and mess_id == None) or (not uid and mess_id>self.getMessageCount()): |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
333 break |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
334 _flags=set(getF(mess_id) if mode else []) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
335 if mode==-1: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
336 _flags.difference_update(set(flags)) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
337 else: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
338 _flags.update(set(flags)) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
339 new_flags=list(_flags) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
340 setF(mess_id, new_flags) |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
341 ret[mess_id] = tuple(new_flags) |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
342 return ret |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
343 |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
344 if uid: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
345 messages.last = self.mailbox.getMaxUid() |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
346 messages.getnext = self.mailbox.getNextExistingUid |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
347 ret = updateFlags(self.mailbox.getFlagsUid,self.mailbox.setFlagsUid) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
348 for listener in self.listeners: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
349 listener.flagsChanged(ret) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
350 return ret |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
351 |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
352 else: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
353 messages.last = self.getMessageCount() |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
354 ret = updateFlags(self.mailbox.getFlags,self.mailbox.setFlags) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
355 newFlags={} |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
356 for idx in ret: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
357 #we have to convert idx to uid for the listeners |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
358 newFlags[self.mailbox.getUid(idx)] = ret[idx] |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
359 for listener in self.listeners: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
360 listener.flagsChanged(newFlags) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
361 return ret |
253 | 362 |
363 def getFlags(self): | |
364 """Return the flags defined in this mailbox | |
365 Flags with the \\ prefix are reserved for use as system flags. | |
366 @return: A list of the flags that can be set on messages in this mailbox. | |
367 """ | |
368 debug('getFlags') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
369 return ['\\SEEN','\\ANSWERED','\\FLAGGED','\\DELETED','\\DRAFT'] #TODO: add '\\RECENT' |
253 | 370 |
371 def getHierarchicalDelimiter(self): | |
372 """Get the character which delimits namespaces for in this mailbox. | |
373 """ | |
374 debug('getHierarchicalDelimiter') | |
375 return '.' | |
376 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
377 class ImapSatAccount(imap4.MemoryAccount): |
253 | 378 #implements(imap4.IAccount) |
379 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
380 def __init__(self, host, profile): |
253 | 381 debug("ImapAccount init") |
382 self.host=host | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
383 self.profile=profile |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
384 imap4.MemoryAccount.__init__(self,profile) |
253 | 385 self.addMailbox("Inbox") #We only manage Inbox for the moment |
386 debug ('INBOX added') | |
387 | |
388 def _emptyMailbox(self, name, id): | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
389 return SatMailbox(self.host,name,self.profile) |
253 | 390 |
391 | |
392 class ImapRealm: | |
393 implements(portal.IRealm) | |
394 | |
395 def __init__(self,host): | |
396 self.host = host | |
397 | |
398 def requestAvatar(self, avatarID, mind, *interfaces): | |
399 debug('requestAvatar') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
400 profile=avatarID.decode('utf-8') |
253 | 401 if imap4.IAccount not in interfaces: |
402 raise NotImplementedError | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
403 return imap4.IAccount, ImapSatAccount(self.host,profile), lambda:None |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
404 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
405 class SatProfileCredentialChecker: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
406 """ |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
407 This credential checker check against SàT's profile and associated jabber's password |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
408 Check if the profile exists, and if the password is OK |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
409 Return the profile as avatarId |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
410 """ |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
411 implements(checkers.ICredentialsChecker) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
412 credentialInterfaces = (credentials.IUsernamePassword, |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
413 credentials.IUsernameHashedPassword) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
414 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
415 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
416 def __init__(self, host): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
417 self.host = host |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
418 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
419 def _cbPasswordMatch(self, matched, profile): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
420 if matched: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
421 return profile.encode('utf-8') |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
422 else: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
423 return failure.Failure(cred_error.UnauthorizedLogin()) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
424 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
425 def requestAvatarId(self, credentials): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
426 profiles = self.host.memory.getProfilesList() |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
427 if not credentials.username in profiles: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
428 return defer.fail(cred_error.UnauthorizedLogin()) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
429 password = self.host.memory.getParamA("Password", "Connection", profile_key=credentials.username) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
430 return defer.maybeDeferred( |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
431 credentials.checkPassword, |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
432 password).addCallback( |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
433 self._cbPasswordMatch, credentials.username) |
253 | 434 |
435 class ImapServerFactory(protocol.ServerFactory): | |
436 protocol = imap4.IMAP4Server | |
437 | |
438 def __init__(self, host): | |
439 self.host=host | |
440 | |
441 def startedConnecting(self, connector): | |
442 debug (_("IMAP server connection started")) | |
443 | |
444 def clientConnectionLost(self, connector, reason): | |
445 debug (_("IMAP server connection lost (reason: %s)"), reason) | |
446 | |
447 def buildProtocol(self, addr): | |
412 | 448 debug ("Building protocol") |
253 | 449 prot = protocol.ServerFactory.buildProtocol(self, addr) |
450 prot.portal = portal.Portal(ImapRealm(self.host)) | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
451 prot.portal.registerChecker(SatProfileCredentialChecker(self.host)) |
253 | 452 return prot |