IMAPmailbox.get_headers() for bounces

This commit is contained in:
Dominik Chilla 2019-01-07 22:01:20 +01:00
parent ff04b9f3e4
commit 8fae189267
5 changed files with 106 additions and 28 deletions

View File

@ -263,14 +263,16 @@ class Gulag:
except(GulagException,GulagDBException) as e:
logging.warning(whoami(self) + e.message)
raise GulagException(whoami(self) + e.message) from e
if 'rfc822_message' not in args:
if 'rfc822_message' not in args and 'headers' not in args:
return {
'quarmails': qms_db,
'rfc822_messages': {}
'rfc822_messages': {},
'headers': {}
}
# recognize all IMAP mailboxes to read from
# and store rfc822-messages under it
mailboxes = {}
headers = {}
for qm in qms_db:
if qm['mailbox_id'] not in mailboxes:
mailboxes[qm['mailbox_id']] = {}
@ -290,18 +292,29 @@ class Gulag:
for qm_db in qms_db:
if qm_db['imap_uid'] not in mailboxes[mailbox_id]:
try:
mailboxes[mailbox_id][qm_db['imap_uid']] = imap_mb.get_message(
qm_db['imap_uid']
).decode("utf-8")
if 'rfc822_message' in args:
mailboxes[mailbox_id][qm_db['imap_uid']] = imap_mb.get_message(
qm_db['imap_uid']
).decode("utf-8")
elif 'headers' in args:
mailboxes[mailbox_id][qm_db['imap_uid']] = imap_mb.get_headers(
qm_db['imap_uid']
).decode("utf-8")
except IMAPmailboxException as e:
logging.warning(whoami(self) + e.message)
raise GulagException(whoami(self) + e.message) from e
imap_mb.close()
# end for mailboxes
return {
"quarmails": qms_db,
"rfc822_messages": mailboxes
}
if 'rfc822_message' in args:
return {
"quarmails": qms_db,
"rfc822_messages": mailboxes
}
elif 'headers' in args:
return {
"quarmails": qms_db,
"headers": mailboxes
}
def get_quarmail(self,args):
qm_db = None
@ -312,7 +325,7 @@ class Gulag:
except GulagDBException as e:
logging.warning(whoami(self) + e.message)
raise GulagException(whoami(self) + e.message) from e
if 'rfc822_message' not in args:
if 'rfc822_message' not in args and 'headers' not in args:
return qm_db
# pull full RFC822 message from IMAP mailbox
mailbox = None
@ -326,29 +339,20 @@ class Gulag:
imap_mb = None
try:
imap_mb = IMAPmailbox(mailbox)
qm_db['rfc822_message'] = imap_mb.get_message(
qm_db['imap_uid']
).decode("utf-8")
if 'rfc822_message' in args:
qm_db['rfc822_message'] = imap_mb.get_message(
qm_db['imap_uid']
).decode("utf-8")
elif 'headers' in args:
qm_db['headers'] = imap_mb.get_headers(
qmat_db['imap_uid']
)
imap_mb.close()
return qm_db
except IMAPmailboxException as e:
logging.warning(whoami(self) + e.message)
raise GulagException(whoami(self) + e.message) from e
def release_quarmail(self,args):
try:
quarmail = self.get_quarmail({
"quarmail_id": args['quarmail_id'],
"rfc822_message": True
})
#
# TODO: re-send quarmail to original env_rcpt
# TODO: self.delete_quarmail() if arg['purge']
except GulagNotFoundException as e:
raise GulagNotFoundException(whoami(self) + e.message) from e
except GulagException as e:
raise GulagException(whoami(self) + e.message) from e
def delete_quarmail(self, args):
qm_db = None
try:
@ -394,6 +398,44 @@ class Gulag:
imap_mb.close()
return
def release_quarmail(self,args):
try:
quarmail = self.get_quarmail({
"quarmail_id": args['quarmail_id'],
"rfc822_message": True
})
# TODO: re-send quarmail to original env_rcpt
# TODO: self.delete_quarmail() if arg['purge']
except GulagNotFoundException as e:
raise GulagNotFoundException(whoami(self) + e.message) from e
except GulagException as e:
raise GulagException(whoami(self) + e.message) from e
def bounce_quarmail(self,args):
try:
quarmail = self.get_quarmail({
"quarmail_id": args['quarmail_id'],
"rfc822_message": True
})
# TODO: bounce quarmail headers-only to quarmail['env_from']
# TODO: self.delete_quarmail() if arg['purge']
except GulagNotFoundException as e:
raise GulagNotFoundException(whoami(self) + e.message) from e
except GulagException as e:
raise GulagException(whoami(self) + e.message) from e
def forward_quarmail(self,args):
try:
quarmail = self.get_quarmail({
"quarmail_id": args['quarmail_id'],
"rfc822_message": True
})
# TODO: send quarmail to args['env_rcpt']
except GulagNotFoundException as e:
raise GulagNotFoundException(whoami(self) + e.message) from e
except GulagException as e:
raise GulagException(whoami(self) + e.message) from e
def get_quarmail_attachments(self,args):
try:
return self.db.get_quarmail_attachments(args['quarmail_id'])

View File

@ -1,6 +1,7 @@
import imaplib
import email
import email.header
from email.parser import HeaderParser
import time
import re
from GulagUtils import whoami
@ -103,6 +104,14 @@ class IMAPmailbox:
)
return True
def get_headers(self,imap_uid):
rv, data = self.mailbox.uid('FETCH', str(imap_uid), '(BODY[HEADER])')
if rv != 'OK':
raise IMAPmailboxException(whoami(self) +
"ERROR getting headers: %s", str(imap_uid)
)
return data[0][1]
def get_attachment(self,imap_uid,filename):
msg = email.message_from_bytes(self.get_message(imap_uid))
for part in msg.walk():

View File

@ -71,6 +71,8 @@ class ResQuarMail(GulagResource):
abort(404, message=e.message)
except GulagException as e:
abort(500, message=e.message)
def delete(self,quarmail_id):
pass
def delete(self,quarmail_id):
args = {"quarmail_id": quarmail_id}
try:
@ -93,6 +95,18 @@ class ResQuarMailRelease(GulagResource):
except GulagException as e:
abort(500, message=e.message)
class ResQuarMailBounce(GulagResource):
def get(self,quarmail_id):
args = {"quarmail_id": quarmail_id}
if(request.args.get('purge')):
args['purge'] = True
try:
return self.gulag.bounce_quarmail(args)
except GulagNotFoundException as e:
abort(404, message=e.message)
except GulagException as e:
abort(500, message=e.message)
class ResQuarMailAttachments(GulagResource):
def get(self,quarmail_id):
args = {"quarmail_id": quarmail_id}

View File

@ -17,3 +17,5 @@ RUN env; set -ex ; \
&& /bin/mkdir /config /socket /app
COPY app/*.py /app/
CMD ["/usr/bin/uwsgi","--emperor","/config/vassals"]

View File

@ -50,6 +50,10 @@ paths:
type: string
required: false
description: get full RFC822 email message for each QuarMail object
- in: query
name: headers
description: get all email headers for each QuarMail object
required: false
- in: query
name: filters
type: string
@ -81,9 +85,13 @@ paths:
type: integer
- in: query
name: rfc822_message
description: if set to a (random) value, full RFC822 email message will be returned as well
description: if set to a (random) value, full RFC822 email message will be returned
type: string
required: false
- in: query
name: headers
description: if set to a (random) value, all email headers will be returned
required: false
responses:
200:
description: quarantined email object
@ -311,6 +319,9 @@ definitions:
rfc822_message:
type: string
description: full RFC822 email message
headers:
type: string
description: email headers
Attachment:
type: object
required: