def get_quarmail(self, args): try: cursor = self.conn.cursor() query = "select *,(select count(*) from QuarMail2Attachment" query += " where QuarMails.id=QuarMail2Attachment.quarmail_id) as attach_count," query += " (select count(*) from QuarMail2URI" query += " where QuarMails.id=QuarMail2URI.quarmail_id) as uri_count" query += " from QuarMails where QuarMails.id=" + str( args['id']) + ";" cursor.execute(query) data = cursor.fetchall() if not data: raise GulagDBNotFoundException( whoami(self) + "Quarmail with id '" + str(args['id']) + "' does not exist!") desc = cursor.description cursor.close() tuple = data[0] dict = {} for (name, value) in zip(desc, tuple): if (name[0] == 'ctime'): dict[name[0]] = value.strftime('%Y-%m-%d %H:%M:%S') else: dict[name[0]] = value dict['href'] = self.uri_prefixes['quarmails'] + str(dict['id']) return QuarMail(dict).__dict__ except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e
def get_limit_clause(self, args): if ('query_offset' in args and 'query_limit' in args): try: int(args['query_offset']) except ValueError: raise GulagDBBadInputException( whoami(self) + "'query_offset' must be numeric!") try: int(args['query_limit']) except ValueError: raise GulagDBBadInputException( whoami(self) + "'query_limit' must be numeric!") return "limit " + args['query_offset'] + "," + args['query_limit'] elif ('query_offset' in args and 'query_limit' not in args): raise GulagDBBadInputException( whoami(self) + "'query_offset' without 'query_limit' is useless!") elif ('query_limit' in args and 'query_offset' not in args): try: int(args['query_limit']) except ValueError: raise GulagDBBadInputException( whoami(self) + "query_limit must be numeric!") return "limit " + args['query_limit'] else: return ""
def retag_message(self,imap_uid,tag): logging.info(whoami(self) + "UID: " + str(imap_uid)) rv, data = self.mailbox.uid('STORE', str(imap_uid.decode()), 'FLAGS', tag) if rv != 'OK': raise IMAPmailboxException(whoami(self) + "ERROR flagging message for deletion: %s", str(imap_uid) )
def get_quarmail_uris(self, quarmail_id): try: query = "select URIs.*" query += " from QuarMail2URI" query += " left join QuarMails ON QuarMails.id = QuarMail2URI.quarmail_id" query += " left join URIs ON URIs.id = QuarMail2URI.uri_id" query += " where QuarMails.id = " + str(quarmail_id) + ";" cursor = self.conn.cursor() cursor.execute(query) results = [] data = cursor.fetchall() if not data: return results desc = cursor.description for tuple in data: dict = {} for (name, value) in zip(desc, tuple): dict[name[0]] = value #dict['href'] = self.uri_prefixes['uris'] + str(dict['id']) dict['href'] = self.uri_prefixes['quarmails'] + str( quarmail_id) dict['href'] += "/uris/" + str(dict['id']) results.append(URI(dict).__dict__) return results except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e except URIException as e: raise GulagDBException(whoami(self) + e.message) from e
def get_quarmail_attachment(self, quarmail_id, attachment_id): try: query = "select Attachments.*,QuarMails.mailbox_id,QuarMails.imap_uid" query += " 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) query += " and Attachments.id = " + str(attachment_id) + ";" cursor = self.conn.cursor() cursor.execute(query) data = cursor.fetchall() if not data: raise GulagDBNotFoundException( whoami(self) + "QuarMail(" + str(quarmail_id) + ") " + "has no attachment (" + str(attachment_id) + ")!") desc = cursor.description tuple = data[0] dict = {} for (name, value) in zip(desc, tuple): dict[name[0]] = value dict['href'] = self.uri_prefixes['quarmails'] + str(quarmail_id) dict['href'] += "/attachments/" + str(dict['id']) return Attachment(dict).__dict__ except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e except AttachmentException as e: raise GulagDBException(whoami(self) + e.message) from e
def get(self,uri_id): try: return self.gulag.get_uri(uri_id) except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def get_quarmail_uri(self, quarmail_id, uri_id): try: query = "select URIs.*" query += " from QuarMail2URI" query += " left join QuarMails ON QuarMails.id = QuarMail2URI.quarmail_id" query += " left join URIs ON URIs.id = QuarMail2URI.uri_id" query += " where QuarMails.id = " + str(quarmail_id) query += " and URIs.id = " + str(uri_id) + ";" cursor = self.conn.cursor() cursor.execute(query) data = cursor.fetchall() if not data: raise GulagDBNotFoundException( whoami(self) + "QuarMail(" + str(quarmail_id) + ")" + " has no uri (" + str(uri_id) + ")!") desc = cursor.description tuple = data[0] dict = {} for (name, value) in zip(desc, tuple): dict[name[0]] = value #dict['href'] = self.uri_prefixes['uris'] + str(dict['id']) dict['href'] = self.uri_prefixes['quarmails'] + str( quarmail_id) dict['href'] += "/uris/" + str(dict['id']) try: return URI(dict).__dict__ except URIException as e: raise GulagDBException(whoami(self) + e.message) from e except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e
def modify_uri(self, uri): try: cursor = self.conn.cursor() mod_fields = "" if 'id' not in uri: raise GulagDBBadInputException("Missing URI-ID!") if len(uri) < 2: raise GulagDBBadInputException( "No fields specified to modify!") for field in uri: if field == 'id': continue mod_fields += " " + field + "='" + uri[field] + "'," mod_fields = str(mod_fields).rstrip(',') cursor.execute("update URI set " + mod_fields + " where id=" + str(uri['id'])) if (cursor.rowcount == 0): raise GulagDBNotFoundException( whoami(self) + "No URIs modified!") cursor.close() return True except GulagDBBadInputException as e: raise GulagDBBadInputException(whoami(self) + e.message) from e except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e
def get_uri(self, uri_id): try: return self.db.get_uri(uri_id) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: raise GulagException(whoami(self) + e.message) from e
def init_folders(self): # Check for all mandatory folders mandatory_folders = { "failed": False } rv, data = self.mailbox.list('""', '*') if rv != 'OK': raise IMAPmailboxException(whoami(self) + "ERROR: Unable to list mailbox: " + self.imap_inbox ) for folder in data: # (\HasChildren \Trash) "." Trash p = re.compile(r'^.+".+" (\S+)$') m = p.search(folder.decode()) name = m.group(1) if name == 'failed': mandatory_folders['failed'] = True # create mandatory folders if needed for folder in mandatory_folders: if mandatory_folders[folder] == False: rv, data = self.mailbox.create(folder) if rv != 'OK': raise IMAPmailboxException(whoami(self) + "ERROR: Unable to create folder: " + folder )
def get_quarmail_uri(self, args): try: return self.db.get_quarmail_uri(args['quarmail_id'], args['uri_id']) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: raise GulagException(whoami(self) + e.message) from e
def delete(self,quarmail_id): args = {"quarmail_id": quarmail_id} try: self.gulag.delete_quarmail(args) return Response(response=None,status=202,mimetype=None) except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def get(self,attachment_id): args = {"id": attachment_id} if(request.args.get('data')): args['data'] = True try: return self.gulag.get_attachment(args) except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def get(self,quarmail_id): args = {"quarmail_id": quarmail_id} try: if(request.args.get('rfc822_message')): args['rfc822_message'] = True return self.gulag.get_quarmail(args) except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def post(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=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def get_quarmail_uris(self, args): if ('from_rfc822_message' not in args): try: return self.db.get_quarmail_uris(args['quarmail_id']) except GulagDBException as e: raise GulagException(whoami(self) + e.message) from e # get URIs from email@IMAP qm_db = None try: qm_db = self.db.get_quarmail({"id": args['quarmail_id']}) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e 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 GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e imap_mb = None try: imap_mb = IMAPmailbox(mailbox) uris = [] for part in imap_mb.get_main_parts(qm_db['imap_uid']): for uri in extract_uris(part.decode("utf-8")): uris.append({"uri": uri, "fqdn": extract_fqdn(uri)}) imap_mb.close() return uris except IMAPmailboxException as e: logging.warning(whoami(self) + e.message) 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(self,quarmail_id,uri_id): args = { "quarmail_id": quarmail_id, "uri_id": uri_id } try: return self.gulag.get_quarmail_uri(args) except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def delete_quarmail(self, id): try: cursor = self.conn.cursor() cursor.execute("delete from QuarMails where id=" + str(id)) if (cursor.rowcount == 0): raise GulagDBNotFoundException( whoami(self) + "No QuarMails deleted!") cursor.close() return True except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e
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(self): args = request.args.to_dict() if 'filters' in args: try: args['filters'] = json.loads(args['filters']) except json.JSONDecodeError as e: abort(400, message="Invalid filters: " + e.msg) try: return self.gulag.get_quarmails(args) except GulagBadInputException as e: abort(400, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def get_quarmail(self, args): qm_db = None try: qm_db = self.db.get_quarmail({"id": args['quarmail_id']}) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e if 'rfc822_message' not in args and 'headers' not in args: return qm_db # pull full RFC822 message from IMAP mailbox mailbox = None try: mailbox = self.db.get_mailbox(qm_db['mailbox_id']) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e imap_mb = None try: imap_mb = IMAPmailbox(mailbox) 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['rfc822_message'] = imap_mb.get_headers( qm_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 get_quarmail_attachment(self, args): qmat_db = None try: qmat_db = self.db.get_quarmail_attachment(args['quarmail_id'], args['attachment_id']) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e if 'data' not in args: return qmat_db # pull attachment from IMAP mailbox mailbox = None try: mailbox = self.db.get_mailbox(qmat_db['mailbox_id']) except GulagDBNotFoundException as e: raise GulagNotFoundException(whoami(self) + e.message) from e except GulagDBException as e: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e imap_mb = None try: imap_mb = IMAPmailbox(mailbox) qmat_db['data'] = imap_mb.get_attachment(qmat_db['imap_uid'], qmat_db['filename']) imap_mb.close return qmat_db except IMAPmailboxException as e: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e
def post(self,mailbox_id): try: self.gulag.mailradar2mailbox({ "mailbox_id": mailbox_id, "req_headers": request.headers, "rfc822_message": request.get_data(as_text=True) }) return {} except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagBadInputException as e: abort(400, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
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.msg)) from e cursor.close() return True
def patch(self,quarmail_id): try: args = json.loads(request.get_data(as_text=True)) args['id'] = quarmail_id except json.JSONDecodeError as e: abort(400, message=whoami(self) + "Invalid JSON: " + e.msg) try: self.gulag.modify_quarmail(args) return Response(response=None,status=204,mimetype=None) except GulagBadInputException as e: abort(400, message=whoami(self)+e.message) except GulagNotFoundException as e: abort(404, message=whoami(self)+e.message) except GulagException as e: abort(500, message=whoami(self)+e.message)
def get_message(self,imap_uid): rv, data = self.mailbox.uid('FETCH', str(imap_uid), '(RFC822)') if rv != 'OK': raise IMAPmailboxException(whoami(self) + "ERROR getting message: %s", str(imap_uid) ) return data[0][1]
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 check_max_body_size(self): body_len = len(request.get_data(as_text=True)) if(body_len > self.gulag.config['dos_protection']['max_body_bytes']): raise GulagBadInputException(whoami(self) + "Request exceedes maximum body size (" + self.gulag.config['dos_protection']['max_body_bytes'] + " bytes)!" )
def get_attachments(self): try: query = "select Attachments.*,QuarMails.mailbox_id,QuarMails.imap_uid" query += " from QuarMail2Attachment" query += " left join QuarMails ON QuarMails.id = QuarMail2Attachment.quarmail_id" query += " left join Attachments ON Attachments.id = QuarMail2Attachment.attachment_id" query += " group by id;" cursor = self.conn.cursor() cursor.execute(query) results = [] data = cursor.fetchall() if not data: return results 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']) dict['href'] = self.uri_prefixes['quarmails'] + str( quarmail_id) dict['href'] += "/attachments/" + str(dict['id']) results.append(Attachment(dict).__dict__) return results except mariadb.Error as e: raise GulagDBException(whoami(self) + str(e.msg)) from e