Option to allow html/plaintext emails in lists

This commit is contained in:
Tanguy Fardet 2022-10-02 10:25:14 +02:00 committed by Drew DeVault
parent 2015bd3ca6
commit 057b761178
3 changed files with 13 additions and 5 deletions

View File

@ -138,7 +138,7 @@ sock-group=postfix
# and each part is checked against this list. # and each part is checked against this list.
# #
# Uses fnmatch for wildcard expansion. # Uses fnmatch for wildcard expansion.
reject-mimetypes=text/html reject-mimetypes=
# #
# Link to include in the rejection message where senders can get help # Link to include in the rejection message where senders can get help
# correcting their email. # correcting their email.

View File

@ -197,23 +197,31 @@ class MailHandler:
sender = sender[0] or sender[1] sender = sender[0] or sender[1]
permit_mimetypes = permit_mimetypes.split(",") permit_mimetypes = permit_mimetypes.split(",")
reject_mimetypes = reject_mimetypes.split(",") + always_reject reject_mimetypes = reject_mimetypes.split(",") + always_reject
# check the email for plaintext part
for part in mail.walk(): for part in mail.walk():
content_type = part.get_content_type() content_type = part.get_content_type()
if content_type == "text/plain": if content_type == "text/plain":
found_textpart = True found_textpart = True
break
# check if the email is permitted or not
# rejection occur if any forbidden mimetype is present or if any
# non-permitted part is present, except for text/html which is ignored
# if there is also a text/plain part and it is not forbidden
for part in mail.walk():
content_type = part.get_content_type()
if fnmatch(content_type, "multipart/*"): if fnmatch(content_type, "multipart/*"):
continue continue
# check whether the type is permitted
permit = False permit = False
for whitelist in permit_mimetypes: for whitelist in permit_mimetypes:
if fnmatch(content_type, whitelist): if fnmatch(content_type, whitelist):
permit = True permit = True
break break
if not permit: if not permit:
if content_type == "text/html": if content_type == "text/html" and not found_textpart:
return html_error.format(sender) return html_error.format(sender)
else: else:
return forbidden_mimetype_error.format( return forbidden_mimetype_error.format(sender, content_type)
sender, content_type)
for blacklist in reject_mimetypes: for blacklist in reject_mimetypes:
if fnmatch(content_type, blacklist): if fnmatch(content_type, blacklist):
if content_type == "text/html": if content_type == "text/html":

View File

@ -57,7 +57,7 @@ CREATE TABLE list (
default_access integer DEFAULT 7 NOT NULL, default_access integer DEFAULT 7 NOT NULL,
mirror_id integer REFERENCES list(id), mirror_id integer REFERENCES list(id),
permit_mimetypes character varying DEFAULT 'text/*,application/pgp-signature,application/pgp-keys'::character varying NOT NULL, permit_mimetypes character varying DEFAULT 'text/*,application/pgp-signature,application/pgp-keys'::character varying NOT NULL,
reject_mimetypes character varying DEFAULT ''::character varying NOT NULL, reject_mimetypes character varying DEFAULT 'text/html'::character varying NOT NULL,
import_in_progress boolean DEFAULT false NOT NULL, import_in_progress boolean DEFAULT false NOT NULL,
visibility visibility NOT NULL, visibility visibility NOT NULL,
CONSTRAINT uq_list_owner_id_name UNIQUE (owner_id, name) CONSTRAINT uq_list_owner_id_name UNIQUE (owner_id, name)