Mercurial > p > roundup > code
comparison roundup/mailgw.py @ 1945:7e4058dfb29b
ignore incoming email with "Precedence: bulk" (patch [SF#843489])
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Thu, 04 Dec 2003 23:34:25 +0000 |
| parents | 20cfd25cffda |
| children | ca2dca3db172 |
comparison
equal
deleted
inserted
replaced
| 1944:23fd363ece42 | 1945:7e4058dfb29b |
|---|---|
| 71 set() method to add the message to the item's spool; in the second case we | 71 set() method to add the message to the item's spool; in the second case we |
| 72 are calling the create() method to create a new node). If an auditor raises | 72 are calling the create() method to create a new node). If an auditor raises |
| 73 an exception, the original message is bounced back to the sender with the | 73 an exception, the original message is bounced back to the sender with the |
| 74 explanatory message given in the exception. | 74 explanatory message given in the exception. |
| 75 | 75 |
| 76 $Id: mailgw.py,v 1.138 2003-11-13 03:41:38 richard Exp $ | 76 $Id: mailgw.py,v 1.139 2003-12-04 23:34:25 richard Exp $ |
| 77 """ | 77 """ |
| 78 | 78 |
| 79 import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri | 79 import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri |
| 80 import time, random, sys | 80 import time, random, sys |
| 81 import traceback, MimeWriter, rfc822 | 81 import traceback, MimeWriter, rfc822 |
| 90 | 90 |
| 91 class MailUsageError(ValueError): | 91 class MailUsageError(ValueError): |
| 92 pass | 92 pass |
| 93 | 93 |
| 94 class MailUsageHelp(Exception): | 94 class MailUsageHelp(Exception): |
| 95 pass | 95 """ We need to send the help message to the user. """ |
| 96 | |
| 97 class MailLoop(Exception): | |
| 98 """ We've seen this message before... """ | |
| 99 pass | 96 pass |
| 100 | 97 |
| 101 class Unauthorized(Exception): | 98 class Unauthorized(Exception): |
| 102 """ Access denied """ | 99 """ Access denied """ |
| 100 pass | |
| 101 | |
| 102 class IgnoreMessage(Exception): | |
| 103 """ A general class of message that we should ignore. """ | |
| 104 pass | |
| 105 class IgnoreBulk(IgnoreMessage): | |
| 106 """ This is email from a mailing list or from a vacation program. """ | |
| 107 pass | |
| 108 class IgnoreLoop(IgnoreMessage): | |
| 109 """ We've seen this message before... """ | |
| 110 pass | |
| 103 | 111 |
| 104 def initialiseSecurity(security): | 112 def initialiseSecurity(security): |
| 105 ''' Create some Permissions and Roles on the security object | 113 ''' Create some Permissions and Roles on the security object |
| 106 | 114 |
| 107 This function is directly invoked by security.Security.__init__() | 115 This function is directly invoked by security.Security.__init__() |
| 298 # in some rare cases, a particularly stuffed-up e-mail will make | 306 # in some rare cases, a particularly stuffed-up e-mail will make |
| 299 # its way into here... try to handle it gracefully | 307 # its way into here... try to handle it gracefully |
| 300 sendto = message.getaddrlist('resent-from') | 308 sendto = message.getaddrlist('resent-from') |
| 301 if not sendto: | 309 if not sendto: |
| 302 sendto = message.getaddrlist('from') | 310 sendto = message.getaddrlist('from') |
| 303 if sendto: | 311 if not sendto: |
| 304 if not self.trapExceptions: | |
| 305 return self.handle_message(message) | |
| 306 try: | |
| 307 return self.handle_message(message) | |
| 308 except MailUsageHelp: | |
| 309 # bounce the message back to the sender with the usage message | |
| 310 fulldoc = '\n'.join(string.split(__doc__, '\n')[2:]) | |
| 311 sendto = [sendto[0][1]] | |
| 312 m = [''] | |
| 313 m.append('\n\nMail Gateway Help\n=================') | |
| 314 m.append(fulldoc) | |
| 315 self.mailer.bounce_message(message, sendto, m, | |
| 316 subject="Mail Gateway Help") | |
| 317 except MailUsageError, value: | |
| 318 # bounce the message back to the sender with the usage message | |
| 319 fulldoc = '\n'.join(string.split(__doc__, '\n')[2:]) | |
| 320 sendto = [sendto[0][1]] | |
| 321 m = [''] | |
| 322 m.append(str(value)) | |
| 323 m.append('\n\nMail Gateway Help\n=================') | |
| 324 m.append(fulldoc) | |
| 325 self.mailer.bounce_message(message, sendto, m) | |
| 326 except Unauthorized, value: | |
| 327 # just inform the user that he is not authorized | |
| 328 sendto = [sendto[0][1]] | |
| 329 m = [''] | |
| 330 m.append(str(value)) | |
| 331 self.mailer.bounce_message(message, sendto, m) | |
| 332 except MailLoop: | |
| 333 # XXX we should use a log file here... | |
| 334 return | |
| 335 except: | |
| 336 # bounce the message back to the sender with the error message | |
| 337 # XXX we should use a log file here... | |
| 338 sendto = [sendto[0][1], self.instance.config.ADMIN_EMAIL] | |
| 339 m = [''] | |
| 340 m.append('An unexpected error occurred during the processing') | |
| 341 m.append('of your message. The tracker administrator is being') | |
| 342 m.append('notified.\n') | |
| 343 m.append('---- traceback of failure ----') | |
| 344 s = cStringIO.StringIO() | |
| 345 import traceback | |
| 346 traceback.print_exc(None, s) | |
| 347 m.append(s.getvalue()) | |
| 348 self.mailer.bounce_message(message, sendto, m) | |
| 349 else: | |
| 350 # very bad-looking message - we don't even know who sent it | 312 # very bad-looking message - we don't even know who sent it |
| 351 # XXX we should use a log file here... | 313 # XXX we should use a log file here... |
| 352 sendto = [self.instance.config.ADMIN_EMAIL] | 314 sendto = [self.instance.config.ADMIN_EMAIL] |
| 353 m = ['Subject: badly formed message from mail gateway'] | 315 m = ['Subject: badly formed message from mail gateway'] |
| 354 m.append('') | 316 m.append('') |
| 356 m.append('line, indicating that it is corrupt. Please check your') | 318 m.append('line, indicating that it is corrupt. Please check your') |
| 357 m.append('mail gateway source. Failed message is attached.') | 319 m.append('mail gateway source. Failed message is attached.') |
| 358 m.append('') | 320 m.append('') |
| 359 self.mailer.bounce_message(message, sendto, m, | 321 self.mailer.bounce_message(message, sendto, m, |
| 360 subject='Badly formed message from mail gateway') | 322 subject='Badly formed message from mail gateway') |
| 323 return | |
| 324 | |
| 325 # try normal message-handling | |
| 326 if not self.trapExceptions: | |
| 327 return self.handle_message(message) | |
| 328 try: | |
| 329 return self.handle_message(message) | |
| 330 except MailUsageHelp: | |
| 331 # bounce the message back to the sender with the usage message | |
| 332 fulldoc = '\n'.join(string.split(__doc__, '\n')[2:]) | |
| 333 sendto = [sendto[0][1]] | |
| 334 m = [''] | |
| 335 m.append('\n\nMail Gateway Help\n=================') | |
| 336 m.append(fulldoc) | |
| 337 self.mailer.bounce_message(message, sendto, m, | |
| 338 subject="Mail Gateway Help") | |
| 339 except MailUsageError, value: | |
| 340 # bounce the message back to the sender with the usage message | |
| 341 fulldoc = '\n'.join(string.split(__doc__, '\n')[2:]) | |
| 342 sendto = [sendto[0][1]] | |
| 343 m = [''] | |
| 344 m.append(str(value)) | |
| 345 m.append('\n\nMail Gateway Help\n=================') | |
| 346 m.append(fulldoc) | |
| 347 self.mailer.bounce_message(message, sendto, m) | |
| 348 except Unauthorized, value: | |
| 349 # just inform the user that he is not authorized | |
| 350 sendto = [sendto[0][1]] | |
| 351 m = [''] | |
| 352 m.append(str(value)) | |
| 353 self.mailer.bounce_message(message, sendto, m) | |
| 354 except IgnoreMessage: | |
| 355 # XXX we should use a log file here... | |
| 356 # do not take any action | |
| 357 # this exception is thrown when email should be ignored | |
| 358 return | |
| 359 except: | |
| 360 # bounce the message back to the sender with the error message | |
| 361 # XXX we should use a log file here... | |
| 362 sendto = [sendto[0][1], self.instance.config.ADMIN_EMAIL] | |
| 363 m = [''] | |
| 364 m.append('An unexpected error occurred during the processing') | |
| 365 m.append('of your message. The tracker administrator is being') | |
| 366 m.append('notified.\n') | |
| 367 m.append('---- traceback of failure ----') | |
| 368 s = cStringIO.StringIO() | |
| 369 import traceback | |
| 370 traceback.print_exc(None, s) | |
| 371 m.append(s.getvalue()) | |
| 372 self.mailer.bounce_message(message, sendto, m) | |
| 361 | 373 |
| 362 def get_part_data_decoded(self,part): | 374 def get_part_data_decoded(self,part): |
| 363 encoding = part.getencoding() | 375 encoding = part.getencoding() |
| 364 data = None | 376 data = None |
| 365 if encoding == 'base64': | 377 if encoding == 'base64': |
| 395 | 407 |
| 396 Parse the message as per the module docstring. | 408 Parse the message as per the module docstring. |
| 397 ''' | 409 ''' |
| 398 # detect loops | 410 # detect loops |
| 399 if message.getheader('x-roundup-loop', ''): | 411 if message.getheader('x-roundup-loop', ''): |
| 400 raise MailLoop | 412 raise IgnoreLoop |
| 413 | |
| 414 # detect Precedence: Bulk | |
| 415 if (message.getheader('precedence', '') == 'bulk'): | |
| 416 raise IgnoreBulk | |
| 401 | 417 |
| 402 # XXX Don't enable. This doesn't work yet. | 418 # XXX Don't enable. This doesn't work yet. |
| 403 # "[^A-z.]tracker\+(?P<classname>[^\d\s]+)(?P<nodeid>\d+)\@some.dom.ain[^A-z.]" | 419 # "[^A-z.]tracker\+(?P<classname>[^\d\s]+)(?P<nodeid>\d+)\@some.dom.ain[^A-z.]" |
| 404 # handle delivery to addresses like:tracker+issue25@some.dom.ain | 420 # handle delivery to addresses like:tracker+issue25@some.dom.ain |
| 405 # use the embedded issue number as our issue | 421 # use the embedded issue number as our issue |
