Mercurial > libervia-backend
annotate src/plugins/plugin_misc_imap.py @ 297:c5554e2939dd
plugin XEP 0277: author for in request + author, updated management for out request
- a workaround is now used to parse "nick" tag (Jappix behaviour)
- author and updated can now be used in data when sendind microblog. Is no author is given, user jid is used, if no updated is given, current timestamp is used
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 18 Feb 2011 22:32:02 +0100 |
parents | 0ecd9c33fa3a |
children | 62b17854254e |
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 | |
9 it under the terms of the GNU General Public License as published by | |
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 | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
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(): | |
53 | |
54 params = """ | |
55 <params> | |
56 <general> | |
261
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
57 <category name="Mail Server"> |
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
58 <param name="IMAP Port" value="10143" type="string" /> |
253 | 59 </category> |
60 </general> | |
61 </params> | |
62 """ | |
63 | |
64 def __init__(self, host): | |
65 info(_("Plugin Imap Server initialization")) | |
66 self.host = host | |
67 | |
68 #parameters | |
69 host.memory.importParams(self.params) | |
70 | |
261
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
71 port = int(self.host.memory.getParamA("IMAP Port", "Mail Server")) |
253 | 72 info(_("Launching IMAP server on port %d"), port) |
73 | |
74 self.server_factory = ImapServerFactory(self.host) | |
75 reactor.listenTCP(port, self.server_factory) | |
76 | |
77 class Message(): | |
78 implements(imap4.IMessage) | |
79 | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
80 def __init__(self, uid, flags, mess_fp): |
253 | 81 debug('Message Init') |
82 self.uid=uid | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
83 self.flags=flags |
253 | 84 self.mess_fp=mess_fp |
85 self.message=Parser().parse(mess_fp) | |
86 | |
87 def getUID(self): | |
88 """Retrieve the unique identifier associated with this message. | |
89 """ | |
90 debug('getUID (message)') | |
91 return self.uid | |
92 | |
93 def getFlags(self): | |
94 """Retrieve the flags associated with this message. | |
95 @return: The flags, represented as strings. | |
96 """ | |
97 debug('getFlags') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
98 return self.flags |
253 | 99 |
100 def getInternalDate(self): | |
101 """Retrieve the date internally associated with this message. | |
102 @return: An RFC822-formatted date string. | |
103 """ | |
104 debug('getInternalDate') | |
105 return self.message['Date'] | |
106 | |
107 | |
108 def getHeaders(self, negate, *names): | |
109 """Retrieve a group of message headers. | |
110 @param names: The names of the headers to retrieve or omit. | |
111 @param negate: If True, indicates that the headers listed in names | |
112 should be omitted from the return value, rather than included. | |
113 @return: A mapping of header field names to header field values | |
114 """ | |
115 debug('getHeaders %s - %s' % (negate, names)) | |
116 final_dict={} | |
117 to_check=[name.lower() for name in names] | |
118 for header in self.message.keys(): | |
119 if (negate and not header.lower() in to_check) or \ | |
120 (not negate and header.lower() in to_check): | |
121 final_dict[header]=self.message[header] | |
122 return final_dict | |
123 | |
124 def getBodyFile(self): | |
125 """Retrieve a file object containing only the body of this message. | |
126 """ | |
127 debug('getBodyFile') | |
128 return StringIO(self.message.get_payload()) | |
129 | |
130 def getSize(self): | |
131 """Retrieve the total size, in octets, of this message. | |
132 """ | |
133 debug('getSize') | |
134 self.mess_fp.seek(0,os.SEEK_END) | |
135 return self.mess_fp.tell() | |
136 | |
137 | |
138 def isMultipart(self): | |
139 """Indicate whether this message has subparts. | |
140 """ | |
141 debug('isMultipart') | |
142 return False | |
143 | |
144 def getSubPart(self,part): | |
145 """Retrieve a MIME sub-message | |
146 @param part: The number of the part to retrieve, indexed from 0. | |
147 @return: The specified sub-part. | |
148 """ | |
149 debug('getSubPart') | |
150 return TypeError | |
151 | |
152 | |
153 class SatMailbox: | |
154 implements(imap4.IMailbox) | |
155 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
156 def __init__(self,host,name,profile): |
253 | 157 self.host = host |
158 self.listeners=set() | |
159 debug ('Mailbox init (%s)', name) | |
160 if name!="INBOX": | |
161 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
|
162 self.mailbox=self.host.plugins["Maildir"].accessMessageBox(name,self.newMessage, profile) |
253 | 163 |
164 def newMessage(self): | |
165 """Called when a new message is in the mailbox""" | |
166 debug ("newMessage signal received") | |
167 nb_messages=self.getMessageCount() | |
168 for listener in self.listeners: | |
169 listener.newMessages(nb_messages,None) | |
170 | |
171 def getUIDValidity(self): | |
172 """Return the unique validity identifier for this mailbox. | |
173 """ | |
174 debug ('getUIDValidity') | |
175 return 0 | |
176 | |
177 def getUIDNext(self): | |
178 """Return the likely UID for the next message added to this mailbox. | |
179 """ | |
180 debug ('getUIDNext') | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
181 return self.mailbox.getNextUid() |
253 | 182 |
183 def getUID(self,message): | |
184 """Return the UID of a message in the mailbox | |
185 @param message: The message sequence number | |
186 @return: The UID of the message. | |
187 """ | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
188 debug ('getUID (%i)' % message) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
189 #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
|
190 return message |
253 | 191 |
192 def getMessageCount(self): | |
193 """Return the number of messages in this mailbox. | |
194 """ | |
195 debug('getMessageCount') | |
196 ret = self.mailbox.getMessageCount() | |
197 debug("count = %i" % ret) | |
198 return ret | |
199 | |
200 def getRecentCount(self): | |
201 """Return the number of messages with the 'Recent' flag. | |
202 """ | |
203 debug('getRecentCount') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
204 return len(self.mailbox.getMessageIdsWithFlag('\\Recent')) |
253 | 205 |
206 def getUnseenCount(self): | |
207 """Return the number of messages with the 'Unseen' flag. | |
208 """ | |
209 debug('getUnseenCount') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
210 return self.getMessageCount()-len(self.mailbox.getMessageIdsWithFlag('\\SEEN')) |
253 | 211 |
212 def isWriteable(self): | |
213 """Get the read/write status of the mailbox. | |
214 @return: A true value if write permission is allowed, a false value otherwise. | |
215 """ | |
216 debug('isWriteable') | |
217 return True | |
218 | |
219 def destroy(self): | |
220 """Called before this mailbox is deleted, permanently. | |
221 """ | |
222 debug('destroy') | |
223 | |
224 | |
225 def requestStatus(self, names): | |
226 """Return status information about this mailbox. | |
227 @param names: The status names to return information regarding. | |
228 The possible values for each name are: MESSAGES, RECENT, UIDNEXT, | |
229 UIDVALIDITY, UNSEEN. | |
230 @return: A dictionary containing status information about the | |
231 requested names is returned. If the process of looking this | |
232 information up would be costly, a deferred whose callback will | |
233 eventually be passed this dictionary is returned instead. | |
234 """ | |
235 debug('requestStatus') | |
236 return imap4.statusRequestHelper(self, names) | |
237 | |
238 def addListener(self, listener): | |
239 """Add a mailbox change listener | |
240 | |
241 @type listener: Any object which implements C{IMailboxListener} | |
242 @param listener: An object to add to the set of those which will | |
243 be notified when the contents of this mailbox change. | |
244 """ | |
245 debug('addListener %s' % listener) | |
246 self.listeners.add(listener) | |
247 | |
248 def removeListener(self, listener): | |
249 """Remove a mailbox change listener | |
250 | |
251 @type listener: Any object previously added to and not removed from | |
252 this mailbox as a listener. | |
253 @param listener: The object to remove from the set of listeners. | |
254 | |
255 @raise ValueError: Raised when the given object is not a listener for | |
256 this mailbox. | |
257 """ | |
258 debug('removeListener') | |
259 if listener in self.listeners: | |
260 self.listeners.remove(listener) | |
261 else: | |
262 raise imap4.MailboxException('Trying to remove an unknown listener') | |
263 | |
264 def addMessage(self, message, flags = (), date = None): | |
265 """Add the given message to this mailbox. | |
266 @param message: The RFC822 formatted message | |
267 @param flags: The flags to associate with this message | |
268 @param date: If specified, the date to associate with this | |
269 @return: A deferred whose callback is invoked with the message | |
270 id if the message is added successfully and whose errback is | |
271 invoked otherwise. | |
272 """ | |
273 debug('addMessage') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
274 raise imap4.MailboxException("Client message addition not implemented yet") |
253 | 275 |
276 def expunge(self): | |
277 """Remove all messages flagged \\Deleted. | |
278 @return: The list of message sequence numbers which were deleted, | |
279 or a Deferred whose callback will be invoked with such a list. | |
280 """ | |
281 debug('expunge') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
282 self.mailbox.removeDeleted() |
253 | 283 |
284 def fetch(self, messages, uid): | |
285 """Retrieve one or more messages. | |
286 @param messages: The identifiers of messages to retrieve information | |
287 about | |
288 @param uid: If true, the IDs specified in the query are UIDs; | |
289 """ | |
290 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
|
291 if uid: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
292 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
|
293 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
|
294 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
|
295 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
|
296 debug ('stopping iteration') |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
297 raise StopIteration |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
298 try: |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
299 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
|
300 except IndexError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
301 continue |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
302 else: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
303 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
|
304 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
|
305 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
|
306 raise StopIteration |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
307 yield (mess_idx,Message(mess_idx,self.mailbox.getFlags(mess_idx),self.mailbox.getMessage(mess_idx-1))) |
253 | 308 |
309 def store(self, messages, flags, mode, uid): | |
310 """Set the flags of one or more messages. | |
311 @param messages: The identifiers of the messages to set the flags of. | |
312 @param flags: The flags to set, unset, or add. | |
313 @param mode: If mode is -1, these flags should be removed from the | |
314 specified messages. If mode is 1, these flags should be added to | |
315 the specified messages. If mode is 0, all existing flags should be | |
316 cleared and these flags should be added. | |
317 @param uid: If true, the IDs specified in the query are UIDs; | |
318 otherwise they are message sequence IDs. | |
319 @return: A dict mapping message sequence numbers to sequences of str | |
320 representing the flags set on the message after this operation has | |
321 been performed, or a Deferred whose callback will be invoked with | |
322 such a dict. | |
323 """ | |
324 debug('store') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
325 |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
326 flags=[flag.upper() for flag in flags] |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
327 |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
328 def updateFlags(getF,setF): |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
329 ret = {} |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
330 for mess_id in messages: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
331 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
|
332 break |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
333 _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
|
334 if mode==-1: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
335 _flags.difference_update(set(flags)) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
336 else: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
337 _flags.update(set(flags)) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
338 new_flags=list(_flags) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
339 setF(mess_id, new_flags) |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
340 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
|
341 return ret |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
342 |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
343 if uid: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
344 messages.last = self.mailbox.getMaxUid() |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
345 messages.getnext = self.mailbox.getNextExistingUid |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
346 ret = updateFlags(self.mailbox.getFlagsUid,self.mailbox.setFlagsUid) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
347 for listener in self.listeners: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
348 listener.flagsChanged(ret) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
349 return ret |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
350 |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
351 else: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
352 messages.last = self.getMessageCount() |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
353 ret = updateFlags(self.mailbox.getFlags,self.mailbox.setFlags) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
354 newFlags={} |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
355 for idx in ret: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
356 #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
|
357 newFlags[self.mailbox.getUid(idx)] = ret[idx] |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
358 for listener in self.listeners: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
359 listener.flagsChanged(newFlags) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
360 return ret |
253 | 361 |
362 def getFlags(self): | |
363 """Return the flags defined in this mailbox | |
364 Flags with the \\ prefix are reserved for use as system flags. | |
365 @return: A list of the flags that can be set on messages in this mailbox. | |
366 """ | |
367 debug('getFlags') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
368 return ['\\SEEN','\\ANSWERED','\\FLAGGED','\\DELETED','\\DRAFT'] #TODO: add '\\RECENT' |
253 | 369 |
370 def getHierarchicalDelimiter(self): | |
371 """Get the character which delimits namespaces for in this mailbox. | |
372 """ | |
373 debug('getHierarchicalDelimiter') | |
374 return '.' | |
375 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
376 class ImapSatAccount(imap4.MemoryAccount): |
253 | 377 #implements(imap4.IAccount) |
378 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
379 def __init__(self, host, profile): |
253 | 380 debug("ImapAccount init") |
381 self.host=host | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
382 self.profile=profile |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
383 imap4.MemoryAccount.__init__(self,profile) |
253 | 384 self.addMailbox("Inbox") #We only manage Inbox for the moment |
385 debug ('INBOX added') | |
386 | |
387 def _emptyMailbox(self, name, id): | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
388 return SatMailbox(self.host,name,self.profile) |
253 | 389 |
390 | |
391 class ImapRealm: | |
392 implements(portal.IRealm) | |
393 | |
394 def __init__(self,host): | |
395 self.host = host | |
396 | |
397 def requestAvatar(self, avatarID, mind, *interfaces): | |
398 debug('requestAvatar') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
399 profile=avatarID.decode('utf-8') |
253 | 400 if imap4.IAccount not in interfaces: |
401 raise NotImplementedError | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
402 return imap4.IAccount, ImapSatAccount(self.host,profile), lambda:None |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
403 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
404 class SatProfileCredentialChecker: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
405 """ |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
406 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
|
407 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
|
408 Return the profile as avatarId |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
409 """ |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
410 implements(checkers.ICredentialsChecker) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
411 credentialInterfaces = (credentials.IUsernamePassword, |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
412 credentials.IUsernameHashedPassword) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
413 |
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 def __init__(self, host): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
416 self.host = host |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
417 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
418 def _cbPasswordMatch(self, matched, profile): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
419 if matched: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
420 return profile.encode('utf-8') |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
421 else: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
422 return failure.Failure(cred_error.UnauthorizedLogin()) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
423 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
424 def requestAvatarId(self, credentials): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
425 profiles = self.host.memory.getProfilesList() |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
426 if not credentials.username in profiles: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
427 return defer.fail(cred_error.UnauthorizedLogin()) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
428 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
|
429 return defer.maybeDeferred( |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
430 credentials.checkPassword, |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
431 password).addCallback( |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
432 self._cbPasswordMatch, credentials.username) |
253 | 433 |
434 class ImapServerFactory(protocol.ServerFactory): | |
435 protocol = imap4.IMAP4Server | |
436 | |
437 def __init__(self, host): | |
438 self.host=host | |
439 | |
440 def startedConnecting(self, connector): | |
441 debug (_("IMAP server connection started")) | |
442 | |
443 def clientConnectionLost(self, connector, reason): | |
444 debug (_("IMAP server connection lost (reason: %s)"), reason) | |
445 | |
446 def buildProtocol(self, addr): | |
447 debug ("Building protocole") | |
448 prot = protocol.ServerFactory.buildProtocol(self, addr) | |
449 prot.portal = portal.Portal(ImapRealm(self.host)) | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
450 prot.portal.registerChecker(SatProfileCredentialChecker(self.host)) |
253 | 451 return prot |