feat: Allow marking spam as read via a sieve filter (ENV MARK_SPAM_AS_READ=1) (#3489)

* add MARK_SPAM_AS_READ environment variable

* review changes

Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>

* update unit test

---------

Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
This commit is contained in:
H4R0 2023-08-21 00:32:26 +02:00 committed by GitHub
parent 5bada0a83b
commit bb2038e8c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 0 deletions

View file

@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file. The format
> **Note**: Changes and additions listed here are contained in the `:edge` image tag. These changes may not be as stable as released changes.
### Added
- New environment variable `MARK_SPAM_AS_READ`. When set to `1`, marks incoming junk as "read" to avoid unwanted notification of junk as new mail ([#3489](https://github.com/docker-mailserver/docker-mailserver/pull/3489))
## [v12.1.0](https://github.com/docker-mailserver/docker-mailserver/releases/tag/v12.1.0)
### Added

View file

@ -309,6 +309,18 @@ will be automatically moved to the Junk folder (with the help of a Sieve script)
- 0 => Spam messages will be delivered in the mailbox.
- **1** => Spam messages will be delivered in the `Junk` folder.
##### MARK_SPAM_AS_READ
Enable to treat received spam as "read" (_avoids notification to MUA client of new mail_).
Mail is received as spam when it has been marked with either header:
1. `X-Spam: Yes` (_by Rspamd_)
2. `X-Spam-Flag: YES` (_by SpamAssassin - requires [`SPAMASSASSIN_SPAM_TO_INBOX=1`](#spamassassin_spam_to_inbox)_)
- **0** => disabled
- 1 => Spam messages will be marked as read
#### Rspamd
##### ENABLE_RSPAMD

View file

@ -27,6 +27,7 @@ The following environment variables are related to Rspamd:
6. [`RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE`](../environment.md#rspamd_hfilter_hostname_unknown_score)
7. [`RSPAMD_LEARN`](../environment.md#rspamd_learn)
8. [`MOVE_SPAM_TO_JUNK`](../environment.md#move_spam_to_junk)
9. [`MARK_SPAM_AS_READ`](../environment.md#mark_spam_as_read)
With these variables, you can enable Rspamd itself and you can enable / disable certain features related to Rspamd.

View file

@ -368,6 +368,9 @@ ENABLE_SPAMASSASSIN_KAM=0
# spam messages will be moved in the Junk folder (SPAMASSASSIN_SPAM_TO_INBOX=1 required)
MOVE_SPAM_TO_JUNK=1
# spam messages wil be marked as read
MARK_SPAM_AS_READ=0
# add spam info headers if at, or above that level:
SA_TAG=2.0

View file

@ -48,6 +48,7 @@ function _register_functions() {
_register_setup_function '_setup_dovecot_dhparam'
_register_setup_function '_setup_dovecot_quota'
_register_setup_function '_setup_spam_to_junk'
_register_setup_function '_setup_spam_mark_as_read'
fi
case "${ACCOUNT_PROVISIONER}" in

View file

@ -271,3 +271,28 @@ EOF
_log 'debug' 'Spam emails will not be moved to the Junk folder'
fi
}
function _setup_spam_mark_as_read() {
if [[ ${MARK_SPAM_AS_READ} -eq 1 ]]; then
_log 'debug' 'Spam emails will be marked as read'
mkdir -p /usr/lib/dovecot/sieve-global/after/
# Header support: `X-Spam-Flag` (SpamAssassin), `X-Spam` (Rspamd)
cat >/usr/lib/dovecot/sieve-global/after/spam_mark_as_read.sieve << EOF
require ["mailbox","imap4flags"];
if anyof (header :contains "X-Spam-Flag" "YES",
header :contains "X-Spam" "Yes") {
setflag "\\\\Seen";
}
EOF
sievec /usr/lib/dovecot/sieve-global/after/spam_mark_as_read.sieve
chown dovecot:root /usr/lib/dovecot/sieve-global/after/spam_mark_as_read.{sieve,svbin}
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 0 ]]; then
_log 'warning' "'SPAMASSASSIN_SPAM_TO_INBOX=0' but it is required to be 1 for 'MARK_SPAM_AS_READ=1' to work"
fi
else
_log 'debug' 'Spam emails will not be marked as read'
fi
}

View file

@ -46,6 +46,7 @@ function __environment_variables_general_setup() {
VARS[CLAMAV_MESSAGE_SIZE_LIMIT]="${CLAMAV_MESSAGE_SIZE_LIMIT:=25M}"
VARS[FAIL2BAN_BLOCKTYPE]="${FAIL2BAN_BLOCKTYPE:=drop}"
VARS[MOVE_SPAM_TO_JUNK]="${MOVE_SPAM_TO_JUNK:=1}"
VARS[MARK_SPAM_AS_READ]="${MARK_SPAM_AS_READ:=0}"
VARS[POSTGREY_AUTO_WHITELIST_CLIENTS]="${POSTGREY_AUTO_WHITELIST_CLIENTS:=5}"
VARS[POSTGREY_DELAY]="${POSTGREY_DELAY:=300}"
VARS[POSTGREY_MAX_AGE]="${POSTGREY_MAX_AGE:=35}"

View file

@ -8,6 +8,7 @@ BATS_TEST_NAME_PREFIX='[Spam - Amavis] ENV SPAMASSASSIN_SPAM_TO_INBOX '
CONTAINER1_NAME='dms-test_spam-amavis_bounced'
CONTAINER2_NAME='dms-test_spam-amavis_env-move-spam-to-junk-0'
CONTAINER3_NAME='dms-test_spam-amavis_env-move-spam-to-junk-1'
CONTAINER4_NAME='dms-test_spam-amavis_env-mark-spam-as-read-1'
function teardown() { _default_teardown ; }
@ -69,6 +70,28 @@ function teardown() { _default_teardown ; }
_should_receive_spam_at '/var/mail/localhost.localdomain/user1/.Junk/new/'
}
# NOTE: Same as test for `CONTAINER3_NAME`, only differing by ENV `MARK_SPAM_AS_READ=1` + `_should_receive_spam_at` location
@test "(enabled + MARK_SPAM_AS_READ=1) should mark spam message as read" {
export CONTAINER_NAME=${CONTAINER4_NAME}
local CUSTOM_SETUP_ARGUMENTS=(
--env ENABLE_AMAVIS=1
--env ENABLE_SPAMASSASSIN=1
--env SA_SPAM_SUBJECT="SPAM: "
--env SPAMASSASSIN_SPAM_TO_INBOX=1
--env MARK_SPAM_AS_READ=1
--env PERMIT_DOCKER=container
)
_init_with_defaults
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
_should_send_spam_message
_should_be_received_by_amavis 'Passed SPAM {RelayedTaggedInbound,Quarantined}'
# Should move delivered spam to Junk folder as read (`cur` instead of `new`)
_should_receive_spam_at '/var/mail/localhost.localdomain/user1/.Junk/cur/'
}
function _should_send_spam_message() {
_wait_for_smtp_port_in_container
_wait_for_tcp_port_in_container 10024 # port 10024 is for Amavis