mirror of
https://github.com/chillout2k/gulag.git
synced 2025-12-13 16:00:18 +00:00
attachment improvements
This commit is contained in:
parent
c66758110e
commit
bc4796b885
@ -96,6 +96,8 @@ class QuarMail:
|
|||||||
imap_uid = None
|
imap_uid = None
|
||||||
msg_size = None
|
msg_size = None
|
||||||
href = None
|
href = None
|
||||||
|
attach_count = None
|
||||||
|
attachments = None
|
||||||
|
|
||||||
def __init__(self,qm_ref):
|
def __init__(self,qm_ref):
|
||||||
if 'id' not in qm_ref:
|
if 'id' not in qm_ref:
|
||||||
@ -136,6 +138,10 @@ class QuarMail:
|
|||||||
self.msg_size = qm_ref['msg_size']
|
self.msg_size = qm_ref['msg_size']
|
||||||
if 'href' in qm_ref:
|
if 'href' in qm_ref:
|
||||||
self.href = qm_ref['href']
|
self.href = qm_ref['href']
|
||||||
|
if 'attach_count' in qm_ref:
|
||||||
|
self.attach_count = qm_ref['attach_count']
|
||||||
|
if 'attachments' in qm_ref:
|
||||||
|
self.attachments = qm_ref['attachments']
|
||||||
|
|
||||||
|
|
||||||
class AttachmentException(Exception):
|
class AttachmentException(Exception):
|
||||||
|
|||||||
70
app/Gulag.py
70
app/Gulag.py
@ -39,9 +39,9 @@ class Gulag:
|
|||||||
except IMAPmailboxException as e:
|
except IMAPmailboxException as e:
|
||||||
print(e.message)
|
print(e.message)
|
||||||
continue
|
continue
|
||||||
quarmail_ids = []
|
|
||||||
attachments = []
|
|
||||||
for unseen in imap_mb.get_unseen_messages():
|
for unseen in imap_mb.get_unseen_messages():
|
||||||
|
quarmail_ids = []
|
||||||
|
attachments = []
|
||||||
uid = unseen['imap_uid']
|
uid = unseen['imap_uid']
|
||||||
msg = unseen['msg']
|
msg = unseen['msg']
|
||||||
msg_size = len(str(msg))
|
msg_size = len(str(msg))
|
||||||
@ -113,13 +113,14 @@ class Gulag:
|
|||||||
attachments.append(attach_id)
|
attachments.append(attach_id)
|
||||||
# Ende if part.get_filename()
|
# Ende if part.get_filename()
|
||||||
# Ende for msg.walk()
|
# Ende for msg.walk()
|
||||||
|
# QuarMails und Attachments verknüpfen
|
||||||
|
if(len(attachments) > 0):
|
||||||
|
for quarmail_id in quarmail_ids:
|
||||||
|
for attachment_id in attachments:
|
||||||
|
self.db.quarmail2attachment(str(quarmail_id), str(attachment_id))
|
||||||
# Ende for(unseen)
|
# Ende for(unseen)
|
||||||
imap_mb.close()
|
imap_mb.close()
|
||||||
# QuarMails und Attachments verknüpfen
|
|
||||||
if(len(attachments) > 0):
|
|
||||||
for quarmail_id in quarmail_ids:
|
|
||||||
for attachment_id in attachments:
|
|
||||||
self.db.quarmail2attachment(str(quarmail_id), str(attachment_id))
|
|
||||||
# Ende for get_mailboxes
|
# Ende for get_mailboxes
|
||||||
|
|
||||||
def cleanup_quarmails(self):
|
def cleanup_quarmails(self):
|
||||||
@ -144,13 +145,12 @@ class Gulag:
|
|||||||
def get_quarmail(self,args):
|
def get_quarmail(self,args):
|
||||||
qm_db = None
|
qm_db = None
|
||||||
try:
|
try:
|
||||||
qm_db = self.db.get_quarmail({
|
qm_db = self.db.get_quarmail({"id": args['id']})
|
||||||
"id": args['id']
|
|
||||||
})
|
|
||||||
except GulagDBException as e:
|
except GulagDBException as e:
|
||||||
raise GulagException("GulagDBException: " + e.message) from e
|
raise GulagException("GulagDBException: " + e.message) from e
|
||||||
if 'rfc822_message' not in args:
|
if 'rfc822_message' not in args:
|
||||||
return qm_db
|
return qm_db
|
||||||
|
# pull full RFC822 message from mailbox
|
||||||
mailbox = None
|
mailbox = None
|
||||||
try:
|
try:
|
||||||
mailbox = self.db.get_mailbox(qm_db['mailbox_id'])
|
mailbox = self.db.get_mailbox(qm_db['mailbox_id'])
|
||||||
@ -165,16 +165,26 @@ class Gulag:
|
|||||||
print(e.message)
|
print(e.message)
|
||||||
raise GulagException(e.message) from e
|
raise GulagException(e.message) from e
|
||||||
|
|
||||||
|
def get_attachment(self,args):
|
||||||
|
at_db = None
|
||||||
|
try:
|
||||||
|
at_db = self.db.get_attachment({"id": args['id']})
|
||||||
|
return at_db
|
||||||
|
except GulagDBException as e:
|
||||||
|
raise GulagException(e.message) from e
|
||||||
|
|
||||||
def rspamd_http2imap(self,mailbox_id):
|
def rspamd_http2imap(self,mailbox_id):
|
||||||
mailbox = None
|
mailbox = None
|
||||||
try:
|
try:
|
||||||
mailbox = self.db.get_mailbox(mailbox_id)
|
mailbox = self.db.get_mailbox(mailbox_id)
|
||||||
except GulagDBException as e:
|
except GulagDBException as e:
|
||||||
raise GulagException(e.message) from e
|
raise GulagException(e.message) from e
|
||||||
|
# check if the request comes really from rspamd´s metadata_exporter
|
||||||
|
# default metadata_header prefix 'X-Rspamd' will be expected
|
||||||
if(request.headers.get('X-Rspamd-From') == None):
|
if(request.headers.get('X-Rspamd-From') == None):
|
||||||
raise GulagException("Missing Rspamd-specific headers (e.g. X-Rspamd-From)!")
|
raise GulagException("Missing Rspamd-specific headers (e.g. X-Rspamd-From)!")
|
||||||
# recompose rejected mail that will be sent to quarantine mailbox
|
# Prepend gulag-specific headers to rejected mail
|
||||||
|
# before pushing into quarantine mailbox
|
||||||
msg = None
|
msg = None
|
||||||
try:
|
try:
|
||||||
rcpts_hdr = ""
|
rcpts_hdr = ""
|
||||||
@ -184,35 +194,33 @@ class Gulag:
|
|||||||
else:
|
else:
|
||||||
rcpts_hdr = rcpt
|
rcpts_hdr = rcpt
|
||||||
msg = "Return-Path: <" + request.headers.get('X-Rspamd-From') + ">\r\n"
|
msg = "Return-Path: <" + request.headers.get('X-Rspamd-From') + ">\r\n"
|
||||||
msg = msg + "Received: from rspamd_http2imap relay by gulag-mailbox " + mailbox_id + "\r\n"
|
msg += "Received: from rspamd_http2imap relay by gulag-mailbox " + mailbox_id + "\r\n"
|
||||||
msg = msg + "X-Envelope-To-Blocked: " + rcpts_hdr + "\r\n"
|
msg += "X-Envelope-To-Blocked: " + rcpts_hdr + "\r\n"
|
||||||
msg = msg + "X-Spam-Status: " + request.headers.get('X-Rspamd-Symbols') + "\r\n"
|
msg += "X-Spam-Status: " + request.headers.get('X-Rspamd-Symbols') + "\r\n"
|
||||||
msg = msg + "X-Spam-QID: " + request.headers.get('X-Rspamd-Qid') + "\r\n"
|
msg += "X-Spam-QID: " + request.headers.get('X-Rspamd-Qid') + "\r\n"
|
||||||
msg = msg + request.get_data(as_text=True)
|
# append original mail
|
||||||
#FIXME: except email.errors.* as e:
|
msg += request.get_data(as_text=True)
|
||||||
except:
|
except:
|
||||||
raise GulagException(str(sys.exc_info()))
|
raise GulagException(str(sys.exc_info()))
|
||||||
|
|
||||||
# Use IMAP´s APPEND command to store the message into mailbox
|
|
||||||
imap_mb = None
|
imap_mb = None
|
||||||
try:
|
try:
|
||||||
imap_mb = IMAPmailbox(mailbox)
|
imap_mb = IMAPmailbox(mailbox)
|
||||||
imap_mb.append_message(msg)
|
imap_mb.append_message(msg)
|
||||||
except IMAPmailboxException as e:
|
except IMAPmailboxException as e:
|
||||||
raise GulagException(e.message) from e
|
raise GulagException(e.message) from e
|
||||||
|
|
||||||
|
# def send_mail(self,args):
|
||||||
# try:
|
# try:
|
||||||
# if not mailbox['smtp_server']:
|
|
||||||
# raise GulagException("No SMTP server configured for mailbox " + mailbox_id)
|
|
||||||
# # FIXME: SMTP tranaport security and authentication!
|
# # FIXME: SMTP tranaport security and authentication!
|
||||||
# with SMTP(host=mailbox['smtp_server'],port=mailbox['smtp_port']) as smtp:
|
# # with SMTP(host=mailbox['smtp_server'],port=mailbox['smtp_port']) as smtp:
|
||||||
# try:
|
# # try:
|
||||||
# smtp.sendmail(
|
# # smtp.sendmail(
|
||||||
# request.headers.get('X-Rspamd-From'),
|
# # request.headers.get('X-Rspamd-From'),
|
||||||
# mailbox_id,
|
# # mailbox_id,
|
||||||
# msg
|
# # msg
|
||||||
# )
|
# # )
|
||||||
# except (SMTPRecipientsRefused,SMTPHeloError,SMTPSenderRefused,SMTPDataError) as e:
|
# # except (SMTPRecipientsRefused,SMTPHeloError,SMTPSenderRefused,SMTPDataError) as e:
|
||||||
# raise GulagException(str(e)) from e
|
# # raise GulagException(str(e)) from e
|
||||||
# except TimeoutError as e:
|
# except TimeoutError as e:
|
||||||
# raise GulagException(str(e)) from e
|
# raise GulagException(str(e)) from e
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ class GulagDB:
|
|||||||
conn = None
|
conn = None
|
||||||
uri_prefixes = None
|
uri_prefixes = None
|
||||||
|
|
||||||
# def __init__(self, server, user, password, name, uri_prefixes):
|
|
||||||
def __init__(self, args, uri_prefixes):
|
def __init__(self, args, uri_prefixes):
|
||||||
try:
|
try:
|
||||||
if 'unix_socket' in args:
|
if 'unix_socket' in args:
|
||||||
@ -114,7 +113,11 @@ class GulagDB:
|
|||||||
def get_quarmails(self):
|
def get_quarmails(self):
|
||||||
try:
|
try:
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
cursor.execute("select * from QuarMails;")
|
# cursor.execute("select * from QuarMails;")
|
||||||
|
query = "select *,(select count(*) from QuarMail2Attachment"
|
||||||
|
query += " where QuarMails.id=QuarMail2Attachment.quarmail_id) as attach_count"
|
||||||
|
query += " from QuarMails;"
|
||||||
|
cursor.execute(query)
|
||||||
results = []
|
results = []
|
||||||
data = cursor.fetchall()
|
data = cursor.fetchall()
|
||||||
if not data:
|
if not data:
|
||||||
@ -138,7 +141,10 @@ class GulagDB:
|
|||||||
try:
|
try:
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
# TODO: build SQL query by args
|
# TODO: build SQL query by args
|
||||||
query = "select * from QuarMails where id='" + args['id'] + "';"
|
#query = "select * from QuarMails where id='" + args['id'] + "';"
|
||||||
|
query = "select *,(select count(*) from QuarMail2Attachment"
|
||||||
|
query += " where QuarMails.id=QuarMail2Attachment.quarmail_id) as attach_count"
|
||||||
|
query += " from QuarMails where QuarMails.id="+ str(args['id']) +";"
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
data = cursor.fetchall()
|
data = cursor.fetchall()
|
||||||
if not data:
|
if not data:
|
||||||
@ -153,6 +159,10 @@ class GulagDB:
|
|||||||
else:
|
else:
|
||||||
dict[name[0]] = value
|
dict[name[0]] = value
|
||||||
dict['href'] = self.uri_prefixes['quarmails'] + str(dict['id'])
|
dict['href'] = self.uri_prefixes['quarmails'] + str(dict['id'])
|
||||||
|
try:
|
||||||
|
dict['attachments'] = self.get_attachments_by_quarmail(args['id'])
|
||||||
|
except GulagDBException as e:
|
||||||
|
pass
|
||||||
return QuarMail(dict).__dict__
|
return QuarMail(dict).__dict__
|
||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
@ -160,7 +170,8 @@ class GulagDB:
|
|||||||
def get_deprecated_mails(self,retention_period):
|
def get_deprecated_mails(self,retention_period):
|
||||||
try:
|
try:
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
query = "select ctime,mailbox_id,imap_uid from QuarMails where ctime < date_sub(NOW(), INTERVAL "+ retention_period +");"
|
query = "select ctime,mailbox_id,imap_uid from QuarMails"
|
||||||
|
query += " where ctime < date_sub(NOW(), INTERVAL "+ str(retention_period) +");"
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
results = []
|
results = []
|
||||||
data = cursor.fetchall()
|
data = cursor.fetchall()
|
||||||
@ -187,6 +198,46 @@ class GulagDB:
|
|||||||
except mariadb.Error as e:
|
except mariadb.Error as e:
|
||||||
raise GulagDBException(e) from e
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
|
def get_attachment(self, args):
|
||||||
|
try:
|
||||||
|
cursor = self.conn.cursor()
|
||||||
|
cursor.execute("select * from Attachments where id=" + str(args['id']) + ";")
|
||||||
|
data = cursor.fetchall()
|
||||||
|
if not data:
|
||||||
|
raise GulagDBException("Attachment("+ str(args['id']) +") does not exist!")
|
||||||
|
desc = cursor.description
|
||||||
|
tuple = data[0]
|
||||||
|
dict = {}
|
||||||
|
for (name, value) in zip(desc, tuple):
|
||||||
|
dict[name[0]] = value
|
||||||
|
dict['href'] = self.uri_prefixes['attachments'] + str(dict['id'])
|
||||||
|
return Attachment(dict).__dict__
|
||||||
|
except mariadb.Error as e:
|
||||||
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
|
def get_attachments_by_quarmail(self,quarmail_id):
|
||||||
|
try:
|
||||||
|
query = "select Attachments.* from QuarMail2Attachment"
|
||||||
|
query += " left join QuarMails ON QuarMails.id = QuarMail2Attachment.quarmail_id"
|
||||||
|
query += " left join Attachments ON Attachments.id = QuarMail2Attachment.attachment_id"
|
||||||
|
query += " where QuarMails.id = " + str(quarmail_id) + ";"
|
||||||
|
cursor = self.conn.cursor()
|
||||||
|
cursor.execute(query)
|
||||||
|
results = []
|
||||||
|
data = cursor.fetchall()
|
||||||
|
if not data:
|
||||||
|
raise GulagDBException("QuarMail("+ str(quarmail_id) +") has no attachments!")
|
||||||
|
desc = cursor.description
|
||||||
|
for tuple in data:
|
||||||
|
dict = {}
|
||||||
|
for (name, value) in zip(desc, tuple):
|
||||||
|
dict[name[0]] = value
|
||||||
|
dict['href'] = self.uri_prefixes['attachments'] + str(dict['id'])
|
||||||
|
results.append(Attachment(dict).__dict__)
|
||||||
|
return results
|
||||||
|
except mariadb.Error as e:
|
||||||
|
raise GulagDBException(e) from e
|
||||||
|
|
||||||
def quarmail2attachment(self,quarmail_id,attachment_id):
|
def quarmail2attachment(self,quarmail_id,attachment_id):
|
||||||
try:
|
try:
|
||||||
cursor = self.conn.cursor()
|
cursor = self.conn.cursor()
|
||||||
|
|||||||
@ -65,7 +65,11 @@ class ResAttachments(GulagResource):
|
|||||||
|
|
||||||
class ResAttachment(GulagResource):
|
class ResAttachment(GulagResource):
|
||||||
def get(self,id):
|
def get(self,id):
|
||||||
return {"resource": "Attachment by ID"}
|
args = {"id": id}
|
||||||
|
try:
|
||||||
|
return self.gulag.get_attachment(args)
|
||||||
|
except GulagException as e:
|
||||||
|
abort(400, message=e.message)
|
||||||
|
|
||||||
class ResRSPAMDImporter(GulagResource):
|
class ResRSPAMDImporter(GulagResource):
|
||||||
def post(self,mailbox_id):
|
def post(self,mailbox_id):
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from flask_restful import Api
|
|||||||
from Gulag import Gulag,GulagException
|
from Gulag import Gulag,GulagException
|
||||||
from Resources import (ResRoot,ResMailboxes,
|
from Resources import (ResRoot,ResMailboxes,
|
||||||
ResQuarMails,ResQuarMail,ResAttachments,
|
ResQuarMails,ResQuarMail,ResAttachments,
|
||||||
ResRSPAMDImporter
|
ResAttachment,ResRSPAMDImporter
|
||||||
)
|
)
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--config', required=True, help="Path to config file")
|
parser.add_argument('--config', required=True, help="Path to config file")
|
||||||
@ -39,6 +39,10 @@ try:
|
|||||||
'/api/v1/attachments/',
|
'/api/v1/attachments/',
|
||||||
resource_class_kwargs={'gulag_object': gulag}
|
resource_class_kwargs={'gulag_object': gulag}
|
||||||
)
|
)
|
||||||
|
api.add_resource(ResAttachment,
|
||||||
|
'/api/v1/attachments/<string:id>',
|
||||||
|
resource_class_kwargs={'gulag_object': gulag}
|
||||||
|
)
|
||||||
api.add_resource(ResRSPAMDImporter,
|
api.add_resource(ResRSPAMDImporter,
|
||||||
'/api/v1/mailboxes/<string:mailbox_id>/rspamdimporter/',
|
'/api/v1/mailboxes/<string:mailbox_id>/rspamdimporter/',
|
||||||
resource_class_kwargs={'gulag_object': gulag}
|
resource_class_kwargs={'gulag_object': gulag}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user