1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2026-03-17 17:57:23 +01:00

support "domain aliases" (@domain => @domain aliases)

This seemed to already be technically supported but the validation is now stricter and the admin is more helpful:

* Postfix seems to allow @domain.tld as an alias destination address but only if it is the only destination address (see the virtual man page).
 * Allow @domain.tld if it is the whole destination address string.
 * Otherwise, do not allow email addresses without local parts in the destination.
* In the admin, add a third tab for making it clear how to add a domain alias.

closes #265
This commit is contained in:
Joshua Tauberer
2014-11-14 13:33:12 +00:00
parent 9b9f5abf8f
commit 7e7abf3b53
2 changed files with 53 additions and 21 deletions

View File

@@ -15,7 +15,7 @@ def validate_email(email, mode=None):
if mode == 'user':
# For Dovecot's benefit, only allow basic characters.
ATEXT = r'[\w\-]'
elif mode == 'alias':
elif mode in (None, 'alias'):
# For aliases, we can allow any valid email address.
# Based on RFC 2822 and https://github.com/SyrusAkbary/validate_email/blob/master/validate_email.py,
# these characters are permitted in email addresses.
@@ -27,7 +27,8 @@ def validate_email(email, mode=None):
DOT_ATOM_TEXT_LOCAL = ATEXT + r'+(?:\.' + ATEXT + r'+)*'
if mode == 'alias':
# For aliases, Postfix accepts '@domain.tld' format for
# catch-all addresses. Make the local part optional.
# catch-all addresses on the source side and domain aliases
# on the destination side. Make the local part optional.
DOT_ATOM_TEXT_LOCAL = '(?:' + DOT_ATOM_TEXT_LOCAL + ')?'
# as above, but we can require that the host part have at least
@@ -356,19 +357,28 @@ def add_mail_alias(source, destination, env, update_if_exists=False, do_kick=Tru
if not validate_email(source, mode='alias'):
return ("Invalid incoming email address (%s)." % source, 400)
# parse comma and \n-separated destination emails & validate
# validate destination
dests = []
for line in destination.split("\n"):
for email in line.split(","):
email = email.strip()
if email == "": continue
if not validate_email(email, mode='alias'):
return ("Invalid destination email address (%s)." % email, 400)
dests.append(email)
destination = destination.strip()
if validate_email(destination, mode='alias'):
# Oostfix allows a single @domain.tld as the destination, which means
# the local part on the address is preserved in the rewrite.
dests.append(destination)
else:
# Parse comma and \n-separated destination emails & validate. In this
# case, the recipients must be complete email addresses.
for line in destination.split("\n"):
for email in line.split(","):
email = email.strip()
if email == "": continue
if not validate_email(email):
return ("Invalid destination email address (%s)." % email, 400)
dests.append(email)
if len(destination) == 0:
return ("No destination email address(es) provided.", 400)
destination = ",".join(dests)
# save to db
conn, c = open_database(env, with_connection=True)
try:
c.execute("INSERT INTO aliases (source, destination) VALUES (?, ?)", (source, destination))