diff --git a/app/Gulag.py b/app/Gulag.py index a5d22f6..09bff37 100644 --- a/app/Gulag.py +++ b/app/Gulag.py @@ -83,7 +83,6 @@ class Gulag: uris = {} uid = unseen['imap_uid'] msg = email.message_from_bytes(unseen['msg']) -# msg_size = len(msg) msg_size = len(msg.as_string()) r5321_from = email.header.decode_header(msg['Return-Path'])[0][0] if(r5321_from is not '<>'): @@ -168,7 +167,6 @@ class Gulag: ctype = part.get_content_type() if(ctype == 'text/plain' or ctype == 'text/html'): curis = {} -# curis = extract_uris(part.get_payload(decode=True).decode("utf-8")) curis = extract_uris(part.get_payload(decode=True).decode("utf-8","replace")) if(len(curis) > 0): logging.info(whoami(self) + "CURIS: " + str(curis)) @@ -225,7 +223,7 @@ class Gulag: ) from e if 'rfc822_message' not in args: return qms_db - # collect all IMAP mailboxes to read from + # recognise all IMAP mailboxes to read from mailboxes = {} for qm in qms_db: if qm['mailbox_id'] not in mailboxes: @@ -244,10 +242,13 @@ class Gulag: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e for qm_db in qms_db: - qm_db['rfc822_message'] = imap_mb.get_message(qm_db['imap_uid']).decode("utf-8") - logging.info(whoami(self) + - str(qm_db['imap_uid']) + " size: " + str(qm_db['msg_size']) - ) + try: + qm_db['rfc822_message'] = imap_mb.get_message( + 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 return qms_db def get_quarmail(self,args): @@ -275,6 +276,46 @@ class Gulag: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e + def delete_quarmail(self, args): + qm_db = None + try: + qm_db = self.db.get_quarmail({"id": args['quarmail_id']}) + except GulagDBException as e: + logging.warning(whoami(self) + e.message) + raise GulagException(whoami(self) + e.message) from e + mailbox = None + try: + mailbox = self.db.get_mailbox(qm_db['mailbox_id']) + except GulagDBException as e: + logging.warning(whoami(self) + e.message) + raise GulagException(whoami(self) + e.message) from e + # Delete QuarMail from IMAP mailbox + imap_mb = None + try: + imap_mb = IMAPmailbox(mailbox) + imap_mb.delete_message(qm_db['imap_uid']) + except IMAPmailboxException as e: + logging.warning(whoami(self) + e.message) + raise GulagException(whoami(self) + e.message) from e + # Try to remove related objects (attachments, uris, ...) + try: + self.db.delete_quarmail_attachments(args['quarmail_id']) + except GulagDBException as e: + logging.warning(whoami(self) + e.message) + # No exception, as other quarmails may pointer to one of the attachments as well + try: + self.db.delete_quarmail_uris(args['quarmail_id']) + except GulagDBException as e: + logging.warning(whoami(self) + e.message) + # No exception, as other quarmails may pointer to one of the uris as well + # Finally delete QuarMail from DB + try: + self.db.delete_quarmail(args['quarmail_id']) + except GulagDBException as e: + logging.warning(whoami(self) + e.message) + raise GulagException(whoami(self) + e.message) from e + return True + def get_quarmail_attachments(self,args): try: return self.db.get_quarmail_attachments(args['quarmail_id']) diff --git a/app/GulagDB.py b/app/GulagDB.py index dc8659b..4253cd8 100644 --- a/app/GulagDB.py +++ b/app/GulagDB.py @@ -173,15 +173,15 @@ class GulagDB: except mariadb.Error as e: raise GulagDBException(whoami(self) + (e)) from e - def del_quarmail(self, id): + def delete_quarmail(self, id): try: cursor = self.conn.cursor() - cursor.execute("delete from QuarMails where id=%s;", (id)) + cursor.execute("delete from QuarMails where id=" + str(id)) cursor.close() return True except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e)) from e - + def get_quarmails(self,args): try: cursor = self.conn.cursor() @@ -378,6 +378,19 @@ class GulagDB: except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e)) from e + def delete_quarmail_attachments(self, quarmail_id): + cursor = None + try: + cursor = self.conn.cursor() + except mariadb.Error as e: + raise GulagDBException(whoami(self) + str(e)) from e + for qm_at in self.get_quarmail_attachments(quarmail_id): + try: + cursor.execute("delete from Attachments where id=" + str(qm_at['id'])) + except mariadb.Error as e: + raise GulagDBException(whoami(self) + str(e)) from e + cursor.close() + return True def quarmail2attachment(self,quarmail_id,attachment_id): try: @@ -400,17 +413,6 @@ class GulagDB: except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e)) from e - def del_uri(self,uri_id): - try: - cursor = self.conn.cursor() - cursor.execute( - "delete from URIs where uri_id=" + uri_id + ";" - ) - return cursor.lastrowid - except mariadb.Error as e: - raise GulagDBException(whoami(self) + str(e)) from e - - def quarmail2uri(self,quarmail_id,uri_id): try: cursor = self.conn.cursor() @@ -447,3 +449,18 @@ class GulagDB: return results except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e)) from e + + def delete_quarmail_uris(self, quarmail_id): + cursor = None + try: + cursor = self.conn.cursor() + except mariadb.Error as e: + raise GulagDBException(whoami(self) + str(e)) from e + for qm_uri in self.get_quarmail_uris(quarmail_id): + try: + cursor.execute("delete from URIs where id=" + str(qm_uri['id'])) + except mariadb.Error as e: + raise GulagDBException(whoami(self) + str(e)) from e + cursor.close() + return True + diff --git a/app/GulagMailbox.py b/app/GulagMailbox.py index 427397e..473d713 100644 --- a/app/GulagMailbox.py +++ b/app/GulagMailbox.py @@ -69,6 +69,19 @@ class IMAPmailbox: ) return data[0][1] + def delete_message(self,imap_uid): + rv, data = self.mailbox.uid('STORE', str(imap_uid), '+FLAGS', '(\\Deleted)') + if rv != 'OK': + raise IMAPmailboxException(whoami(self) + + "ERROR flagging message for deletion: %s", str(imap_uid) + ) + rv, data = self.mailbox.expunge() + if rv != 'OK': + raise IMAPmailboxException(whoami(self) + + "ERROR expunging mailbox" + ) + return True + def get_attachment(self,imap_uid,filename): msg = email.message_from_bytes(self.get_message(imap_uid)) for part in msg.walk(): diff --git a/app/Resources.py b/app/Resources.py index a40a275..6c07c82 100644 --- a/app/Resources.py +++ b/app/Resources.py @@ -58,6 +58,12 @@ class ResQuarMail(GulagResource): return self.gulag.get_quarmail(args) except GulagException as e: abort(400, message=e.message) + def delete(self,quarmail_id): + args = {"quarmail_id": quarmail_id} + try: + return self.gulag.delete_quarmail(args) + except GulagException as e: + abort(400, message=e.message) class ResQuarMailAttachments(GulagResource): def get(self,quarmail_id): diff --git a/gulag-openapi-2.0.yaml b/gulag-openapi-2.0.yaml index 79f2957..7749a46 100644 --- a/gulag-openapi-2.0.yaml +++ b/gulag-openapi-2.0.yaml @@ -113,6 +113,11 @@ paths: description: IMAP UID of a quarantined email type: string required: false + - in: query + name: rfc822_message + type: string + required: false + description: get full RFC822 email message for each QuarMail object responses: 200: description: search results matching criteria