diff --git a/app/Gulag.py b/app/Gulag.py index fe2a86e..82d9174 100644 --- a/app/Gulag.py +++ b/app/Gulag.py @@ -353,6 +353,24 @@ class Gulag: logging.warning(whoami(self) + e.message) raise GulagException(whoami(self) + e.message) from e + def modify_quarmail(self, quarmail): + try: + if 'id' not in quarmail: + raise GulagBadInputException(whoami(self) + "'id' is mandatory!") + for field in quarmail: + if field not in self.fields['QuarMails']: + raise GulagBadInputException(whoami(self) + + "Unknown QuarMail field: " + field + ) + self.db.modify_quarmail(quarmail) + except GulagDBBadInputException as e: + raise GulagBadInputException(whoami(self) + e.message) from e + 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 + def delete_quarmail(self, args): qm_db = None try: diff --git a/app/GulagDB.py b/app/GulagDB.py index 61d9e01..f61a33f 100644 --- a/app/GulagDB.py +++ b/app/GulagDB.py @@ -278,10 +278,37 @@ class GulagDB: except mariadb.Error as e: raise GulagDBException(whoami(self) + (e.msg)) from e + def modify_quarmail(self, quarmail): + try: + cursor = self.conn.cursor() + mod_fields = "" + if 'id' not in quarmail: + raise GulagDBBadInputException("Missing QuarMail-ID!") + if len(quarmail) < 2: + raise GulagDBBadInputException("No fields specified to modify!") + for field in quarmail: + if field == 'id': + continue + mod_fields += " " + field + "='" + quarmail[field] + "'," + mod_fields = str(mod_fields).rstrip(',') + cursor.execute( + "update QuarMails set "+mod_fields+" where id="+str(quarmail['id']) + ) + if(cursor.rowcount == 0): + raise GulagDBNotFoundException(whoami(self) + "No QuarMails 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 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: diff --git a/app/Resources.py b/app/Resources.py index ecd695a..3036068 100644 --- a/app/Resources.py +++ b/app/Resources.py @@ -4,6 +4,7 @@ import json from Gulag import ( GulagException,GulagNotFoundException,GulagBadInputException ) +from GulagUtils import whoami class GulagResource(Resource): gulag = None @@ -39,7 +40,7 @@ class ResMailboxes(GulagResource): try: return self.gulag.get_mailboxes() except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResMailbox(GulagResource): def get(self,id): @@ -56,9 +57,9 @@ class ResQuarMails(GulagResource): try: return self.gulag.get_quarmails(args) except GulagBadInputException as e: - abort(400, message=e.message) + abort(400, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMail(GulagResource): def get(self,quarmail_id): @@ -68,20 +69,33 @@ class ResQuarMail(GulagResource): args['rfc822_message'] = True return self.gulag.get_quarmail(args) except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) - def delete(self,quarmail_id): - pass + abort(500, message=whoami(self)+e.message) + 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 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=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMailRelease(GulagResource): def get(self,quarmail_id): @@ -91,9 +105,9 @@ class ResQuarMailRelease(GulagResource): try: return self.gulag.release_quarmail(args) except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMailBounce(GulagResource): def get(self,quarmail_id): @@ -103,9 +117,9 @@ class ResQuarMailBounce(GulagResource): try: return self.gulag.bounce_quarmail(args) except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMailAttachments(GulagResource): def get(self,quarmail_id): @@ -115,7 +129,7 @@ class ResQuarMailAttachments(GulagResource): try: return self.gulag.get_quarmail_attachments(args) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMailAttachment(GulagResource): def get(self,quarmail_id,attachment_id): @@ -128,9 +142,9 @@ class ResQuarMailAttachment(GulagResource): try: return self.gulag.get_quarmail_attachment(args) except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMailURIs(GulagResource): def get(self,quarmail_id): @@ -142,7 +156,7 @@ class ResQuarMailURIs(GulagResource): try: return self.gulag.get_quarmail_uris(args) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResQuarMailURI(GulagResource): def get(self,quarmail_id,uri_id): @@ -153,9 +167,9 @@ class ResQuarMailURI(GulagResource): try: return self.gulag.get_quarmail_uri(args) except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResAttachments(GulagResource): def get(self): @@ -167,9 +181,9 @@ class ResAttachment(GulagResource): try: return self.gulag.get_attachment(args) except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResRspamd2Mailbox(GulagResource): def post(self,mailbox_id): @@ -181,11 +195,11 @@ class ResRspamd2Mailbox(GulagResource): }) return {} except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagBadInputException as e: - abort(400, message=e.message) + abort(400, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) class ResMailradar2Mailbox(GulagResource): def post(self,mailbox_id): @@ -197,8 +211,8 @@ class ResMailradar2Mailbox(GulagResource): }) return {} except GulagNotFoundException as e: - abort(404, message=e.message) + abort(404, message=whoami(self)+e.message) except GulagBadInputException as e: - abort(400, message=e.message) + abort(400, message=whoami(self)+e.message) except GulagException as e: - abort(500, message=e.message) + abort(500, message=whoami(self)+e.message) diff --git a/docker/gulag-db/debian/Dockerfile b/docker/gulag-db/debian/Dockerfile index 8c89103..4480c5f 100644 --- a/docker/gulag-db/debian/Dockerfile +++ b/docker/gulag-db/debian/Dockerfile @@ -2,6 +2,9 @@ ARG http_proxy ARG https_proxy FROM debian RUN apt update && \ - apt -yq --no-install-recommends install procps net-tools mariadb-server mariadb-client + apt -yq --no-install-recommends install procps net-tools \ + mariadb-server mariadb-client \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* COPY db/gulag.sql /. CMD ["/usr/bin/mysqld_safe"] diff --git a/docker/gulag-server/debian/Dockerfile b/docker/gulag-server/debian/Dockerfile index 762673f..0b4dcb6 100644 --- a/docker/gulag-server/debian/Dockerfile +++ b/docker/gulag-server/debian/Dockerfile @@ -14,7 +14,9 @@ RUN env; set -ex ; \ uwsgi uwsgi-plugin-python3 procps net-tools \ python3-pip libmagic1 python3-ssdeep \ && pip3 install python-magic \ - && /bin/mkdir /config /socket /app + && /bin/mkdir /config /socket /app \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* COPY app/*.py /app/ diff --git a/gulag-openapi-2.0.yaml b/gulag-openapi-2.0.yaml index 27f03c6..c90f86a 100644 --- a/gulag-openapi-2.0.yaml +++ b/gulag-openapi-2.0.yaml @@ -103,6 +103,29 @@ paths: description: not found 500: description: server error + patch: + summary: modifies a quarantined email + operationId: modify_quarmail + produces: + - application/json + parameters: + - in: path + name: quarmail_id + description: unique id of quarantined email + required: true + type: integer + - in: body + name: quarmail + description: quarmail fields to modify. + schema: + $ref: "#/definitions/QuarMail" + responses: + 202: + description: quarantined email deleted + 404: + description: not found + 500: + description: server error delete: summary: deletes a quarantined email operationId: delete_quarmail @@ -121,7 +144,6 @@ paths: description: not found 500: description: server error - /quarmails/{quarmail_id}/attachments: get: summary: retrieves meta data of all attachments of a quarantined email by quarmail_id