From 1d571dedfc5df67dd9b47d1f235edbc1198afbca Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 9 Oct 2021 17:11:12 +0200 Subject: [PATCH 1/6] split localpart into user and tag --- core/admin/mailu/internal/views/postfix.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index 928f4faf..d2c9f877 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -140,7 +140,8 @@ def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) if localpart is None: return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404) - destination = models.Email.resolve_destination(localpart, domain_name, True) + user, plus = localpart.split("+", 1) + destination = models.Email.resolve_destination(user, domain_name, True) destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders] return flask.jsonify(",".join(destination)) if destination else flask.abort(404) From 22ed2b7f904271d2a7b524b390ccbbc00536fdfd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 9 Oct 2021 17:17:40 +0200 Subject: [PATCH 2/6] add newsfragment --- towncrier/newsfragments/2006.enhancement | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/2006.enhancement diff --git a/towncrier/newsfragments/2006.enhancement b/towncrier/newsfragments/2006.enhancement new file mode 100644 index 00000000..802e6d36 --- /dev/null +++ b/towncrier/newsfragments/2006.enhancement @@ -0,0 +1 @@ +allow sending emails as user+detail@domain.tld From 6a8066c0ae1597fc0b85d9130978ff1af778d70f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 9 Oct 2021 17:18:53 +0200 Subject: [PATCH 3/6] renamed newsfragment --- towncrier/newsfragments/{2006.enhancement => 2007.enhancement} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename towncrier/newsfragments/{2006.enhancement => 2007.enhancement} (100%) diff --git a/towncrier/newsfragments/2006.enhancement b/towncrier/newsfragments/2007.enhancement similarity index 100% rename from towncrier/newsfragments/2006.enhancement rename to towncrier/newsfragments/2007.enhancement From 8c59f3569760513774ad8a48d1a30d336ce2f259 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 Oct 2021 17:43:09 +0200 Subject: [PATCH 4/6] use RECIPIENT_DELIMITER for splitting --- core/admin/mailu/configuration.py | 1 + core/admin/mailu/internal/views/postfix.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index 4401888a..8d4d334a 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -49,6 +49,7 @@ DEFAULT_CONFIG = { 'DKIM_PATH': '/dkim/{domain}.{selector}.key', 'DEFAULT_QUOTA': 1000000000, 'MESSAGE_RATELIMIT': '200/day', + 'RECIPIENT_DELIMITER': None, # Web settings 'SITENAME': 'Mailu', 'WEBSITE': 'https://mailu.io', diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index d2c9f877..44a685c9 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -140,8 +140,9 @@ def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) if localpart is None: return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404) - user, plus = localpart.split("+", 1) - destination = models.Email.resolve_destination(user, domain_name, True) + if delim := flask.current_app.config.get('RECIPIENT_DELIMITER'): + localpart = localpart.split(delim, 1)[0] + destination = models.Email.resolve_destination(localpart, domain_name, True) destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders] return flask.jsonify(",".join(destination)) if destination else flask.abort(404) From 14360f8926461c62c019c62338fef1be2308f133 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 9 Oct 2021 18:28:50 +0200 Subject: [PATCH 5/6] RECIPIENT_DELIMITER can have several characters --- core/admin/mailu/configuration.py | 2 +- core/admin/mailu/internal/views/postfix.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index 8d4d334a..1f2a9239 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -49,7 +49,7 @@ DEFAULT_CONFIG = { 'DKIM_PATH': '/dkim/{domain}.{selector}.key', 'DEFAULT_QUOTA': 1000000000, 'MESSAGE_RATELIMIT': '200/day', - 'RECIPIENT_DELIMITER': None, + 'RECIPIENT_DELIMITER': '', # Web settings 'SITENAME': 'Mailu', 'WEBSITE': 'https://mailu.io', diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index 44a685c9..ab965967 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -140,8 +140,7 @@ def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) if localpart is None: return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404) - if delim := flask.current_app.config.get('RECIPIENT_DELIMITER'): - localpart = localpart.split(delim, 1)[0] + localpart = localpart[:next((i for i, ch in enumerate(localpart) if ch in flask.current_app.config.get('RECIPIENT_DELIMITER')), None)] destination = models.Email.resolve_destination(localpart, domain_name, True) destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders] return flask.jsonify(",".join(destination)) if destination else flask.abort(404) From e127e6b32f8cf83123a5bcfa9431f4caeab80e22 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 9 Oct 2021 18:58:51 +0200 Subject: [PATCH 6/6] clarify the documentation --- docs/configuration.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 5f17b57e..5d8e87b1 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -93,9 +93,10 @@ go and fetch new email if available. Do not use too short delays if you do not want to be blacklisted by external services, but not too long delays if you want to receive your email in time. -The ``RECIPIENT_DELIMITER`` is a character used to delimit localpart from a -custom address part. For instance, if set to ``+``, users can use addresses -like ``localpart+custom@domain.tld`` to deliver mail to ``localpart@domain.tld``. +The ``RECIPIENT_DELIMITER`` is a list of characters used to delimit localpart +from a custom address part. For instance, if set to ``+-``, users can use +addresses like ``localpart+custom@example.com`` or ``localpart-custom@example.com`` +to deliver mail to ``localpart@example.com``. This is useful to provide external parties with different email addresses and later classify incoming mail based on the custom part.