mirror of
https://github.com/chatmail/relay.git
synced 2026-05-13 17:34:38 +00:00
Compare commits
2 Commits
turnserver
...
lmtp_heade
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
735493845c | ||
|
|
ed664cd9cd |
@@ -10,12 +10,7 @@ from chatmaild.user import User
|
|||||||
def read_config(inipath):
|
def read_config(inipath):
|
||||||
assert Path(inipath).exists(), inipath
|
assert Path(inipath).exists(), inipath
|
||||||
cfg = iniconfig.IniConfig(inipath)
|
cfg = iniconfig.IniConfig(inipath)
|
||||||
params = cfg.sections["params"]
|
return Config(inipath, params=cfg.sections["params"])
|
||||||
default_config_content = get_default_config_content(params["mail_domain"])
|
|
||||||
df_params = iniconfig.IniConfig("ini", data=default_config_content)["params"]
|
|
||||||
new_params = dict(df_params.items())
|
|
||||||
new_params.update(params)
|
|
||||||
return Config(inipath, params=new_params)
|
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@@ -36,16 +31,18 @@ class Config:
|
|||||||
|
|
||||||
self.max_user_send_per_minute = int(params.get("max_user_send_per_minute", 60))
|
self.max_user_send_per_minute = int(params.get("max_user_send_per_minute", 60))
|
||||||
self.max_user_send_burst_size = int(params.get("max_user_send_burst_size", 10))
|
self.max_user_send_burst_size = int(params.get("max_user_send_burst_size", 10))
|
||||||
self.max_mailbox_size = params["max_mailbox_size"]
|
self.max_mailbox_size = params.get("max_mailbox_size", "500M")
|
||||||
self.max_message_size = int(params.get("max_message_size", "31457280"))
|
self.max_message_size = int(params.get("max_message_size", 31457280))
|
||||||
self.delete_mails_after = params["delete_mails_after"]
|
self.delete_mails_after = params.get("delete_mails_after", "20")
|
||||||
self.delete_large_after = params["delete_large_after"]
|
self.delete_large_after = params.get("delete_large_after", "7")
|
||||||
self.delete_inactive_users_after = int(params["delete_inactive_users_after"])
|
self.delete_inactive_users_after = int(
|
||||||
self.username_min_length = int(params["username_min_length"])
|
params.get("delete_inactive_users_after", 90)
|
||||||
self.username_max_length = int(params["username_max_length"])
|
)
|
||||||
self.password_min_length = int(params["password_min_length"])
|
self.username_min_length = int(params.get("username_min_length", 9))
|
||||||
self.passthrough_senders = params["passthrough_senders"].split()
|
self.username_max_length = int(params.get("username_max_length", 9))
|
||||||
self.passthrough_recipients = params["passthrough_recipients"].split()
|
self.password_min_length = int(params.get("password_min_length", 9))
|
||||||
|
self.passthrough_senders = params.get("passthrough_senders", "").split()
|
||||||
|
self.passthrough_recipients = params.get("passthrough_recipients", "").split()
|
||||||
self.www_folder = params.get("www_folder", "")
|
self.www_folder = params.get("www_folder", "")
|
||||||
self.filtermail_smtp_port = int(params.get("filtermail_smtp_port", "10080"))
|
self.filtermail_smtp_port = int(params.get("filtermail_smtp_port", "10080"))
|
||||||
self.filtermail_smtp_port_incoming = int(
|
self.filtermail_smtp_port_incoming = int(
|
||||||
@@ -164,31 +161,7 @@ def get_default_config_content(mail_domain, **overrides):
|
|||||||
for name, value in extra.items():
|
for name, value in extra.items():
|
||||||
new_line = f"{name} = {value}"
|
new_line = f"{name} = {value}"
|
||||||
new_lines.append(new_line)
|
new_lines.append(new_line)
|
||||||
|
return "\n".join(new_lines)
|
||||||
content = "\n".join(new_lines)
|
|
||||||
|
|
||||||
# apply testrun privacy overrides
|
|
||||||
|
|
||||||
if mail_domain.endswith(".testrun.org"):
|
|
||||||
override_inipath = inidir.joinpath("override-testrun.ini")
|
|
||||||
privacy = iniconfig.IniConfig(override_inipath)["privacy"]
|
|
||||||
lines = []
|
|
||||||
for line in content.split("\n"):
|
|
||||||
for key, value in privacy.items():
|
|
||||||
value_lines = value.format(mail_domain=mail_domain).strip().split("\n")
|
|
||||||
if not line.startswith(f"{key} =") or not value_lines:
|
|
||||||
continue
|
|
||||||
if len(value_lines) == 1:
|
|
||||||
lines.append(f"{key} = {value}")
|
|
||||||
else:
|
|
||||||
lines.append(f"{key} =")
|
|
||||||
for vl in value_lines:
|
|
||||||
lines.append(f" {vl}")
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
lines.append(line)
|
|
||||||
content = "\n".join(lines)
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def is_valid_ipv4(address: str) -> bool:
|
def is_valid_ipv4(address: str) -> bool:
|
||||||
|
|||||||
@@ -12,42 +12,42 @@ mail_domain = {mail_domain}
|
|||||||
#
|
#
|
||||||
|
|
||||||
# email sending rate per user and minute
|
# email sending rate per user and minute
|
||||||
max_user_send_per_minute = 60
|
#max_user_send_per_minute = 60
|
||||||
|
|
||||||
# per-user max burst size for sending rate limiting (GCRA bucket capacity)
|
# per-user max burst size for sending rate limiting (GCRA bucket capacity)
|
||||||
max_user_send_burst_size = 10
|
#max_user_send_burst_size = 10
|
||||||
|
|
||||||
# maximum mailbox size of a chatmail address
|
# maximum mailbox size of a chatmail address
|
||||||
# Oldest messages will be removed automatically, so mailboxes never run full.
|
# (Oldest messages will be removed automatically, so mailboxes never run full)
|
||||||
max_mailbox_size = 500M
|
#max_mailbox_size = 500M
|
||||||
|
|
||||||
# maximum message size for an e-mail in bytes
|
# maximum message size for an e-mail in bytes
|
||||||
max_message_size = 31457280
|
#max_message_size = 31457280
|
||||||
|
|
||||||
# days after which mails are unconditionally deleted
|
# days after which mails are unconditionally deleted
|
||||||
delete_mails_after = 20
|
#delete_mails_after = 20
|
||||||
|
|
||||||
# days after which large messages (>200k) are unconditionally deleted
|
# days after which large messages (>200k) are unconditionally deleted
|
||||||
delete_large_after = 7
|
#delete_large_after = 7
|
||||||
|
|
||||||
# days after which users without a successful login are deleted (database and mails)
|
# days after which users without a successful login are deleted (database and mails)
|
||||||
delete_inactive_users_after = 90
|
#delete_inactive_users_after = 90
|
||||||
|
|
||||||
# minimum length a username must have
|
# minimum length a username must have
|
||||||
username_min_length = 9
|
#username_min_length = 9
|
||||||
|
|
||||||
# maximum length a username can have
|
# maximum length a username can have
|
||||||
username_max_length = 9
|
#username_max_length = 9
|
||||||
|
|
||||||
# minimum length a password must have
|
# minimum length a password must have
|
||||||
password_min_length = 9
|
#password_min_length = 9
|
||||||
|
|
||||||
# list of chatmail addresses which can send outbound un-encrypted mail
|
# list of chatmail addresses which can send outbound un-encrypted mail
|
||||||
passthrough_senders =
|
#passthrough_senders =
|
||||||
|
|
||||||
# list of e-mail recipients for which to accept outbound un-encrypted mails
|
# list of e-mail recipients for which to accept outbound un-encrypted mails
|
||||||
# (space-separated, item may start with "@" to whitelist whole recipient domains)
|
# (space-separated, item may start with "@" to whitelist whole recipient domains)
|
||||||
passthrough_recipients =
|
#passthrough_recipients =
|
||||||
|
|
||||||
# Use externally managed TLS certificates instead of built-in acmetool.
|
# Use externally managed TLS certificates instead of built-in acmetool.
|
||||||
# Paths refer to files on the deployment server (not the build machine).
|
# Paths refer to files on the deployment server (not the build machine).
|
||||||
@@ -63,19 +63,11 @@ passthrough_recipients =
|
|||||||
# Deployment Details
|
# Deployment Details
|
||||||
#
|
#
|
||||||
|
|
||||||
# SMTP outgoing filtermail and reinjection
|
|
||||||
filtermail_smtp_port = 10080
|
|
||||||
postfix_reinject_port = 10025
|
|
||||||
|
|
||||||
# SMTP incoming filtermail and reinjection
|
|
||||||
filtermail_smtp_port_incoming = 10081
|
|
||||||
postfix_reinject_port_incoming = 10026
|
|
||||||
|
|
||||||
# if set to "True" IPv6 is disabled
|
# if set to "True" IPv6 is disabled
|
||||||
disable_ipv6 = False
|
#disable_ipv6 = False
|
||||||
|
|
||||||
# Your email adress, which will be used in acmetool to manage Let's Encrypt SSL certificates
|
# Your email adress, which will be used in acmetool to manage Let's Encrypt SSL certificates
|
||||||
acme_email =
|
#acme_email =
|
||||||
|
|
||||||
# Defaults to https://iroh.{{mail_domain}} and running `iroh-relay` on the chatmail
|
# Defaults to https://iroh.{{mail_domain}} and running `iroh-relay` on the chatmail
|
||||||
# service.
|
# service.
|
||||||
@@ -108,13 +100,13 @@ acme_email =
|
|||||||
# in per-maildir ".in/.out" files.
|
# in per-maildir ".in/.out" files.
|
||||||
# Note that you need to manually cleanup these files
|
# Note that you need to manually cleanup these files
|
||||||
# so use this option with caution on production servers.
|
# so use this option with caution on production servers.
|
||||||
imap_rawlog = false
|
#imap_rawlog = false
|
||||||
|
|
||||||
# set to true if you want to enable the IMAP COMPRESS Extension,
|
# set to true if you want to enable the IMAP COMPRESS Extension,
|
||||||
# which allows IMAP connections to be efficiently compressed.
|
# which allows IMAP connections to be efficiently compressed.
|
||||||
# WARNING: Enabling this makes it impossible to hibernate IMAP
|
# WARNING: Enabling this makes it impossible to hibernate IMAP
|
||||||
# processes which will result in much higher memory/RAM usage.
|
# processes which will result in much higher memory/RAM usage.
|
||||||
imap_compress = false
|
#imap_compress = false
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
[privacy]
|
|
||||||
|
|
||||||
passthrough_recipients = privacy@testrun.org echo@{mail_domain}
|
|
||||||
|
|
||||||
privacy_postal =
|
|
||||||
Merlinux GmbH, Represented by the managing director H. Krekel,
|
|
||||||
Reichgrafen Str. 20, 79102 Freiburg, Germany
|
|
||||||
|
|
||||||
privacy_mail = privacy@testrun.org
|
|
||||||
privacy_pdo =
|
|
||||||
Prof. Dr. Fabian Schmieder, lexICT UG (limited), Ostfeldstr. 49, 30559 Hannover.
|
|
||||||
You can contact him at *delta-privacy@merlinux.eu* (Keyword: DPO)
|
|
||||||
privacy_supervisor =
|
|
||||||
State Commissioner for Data Protection and Freedom of Information of
|
|
||||||
Baden-Württemberg in 70173 Stuttgart, Germany.
|
|
||||||
@@ -13,7 +13,12 @@ def test_read_config_basic(example_config):
|
|||||||
assert not example_config.privacy_pdo and not example_config.privacy_postal
|
assert not example_config.privacy_pdo and not example_config.privacy_postal
|
||||||
|
|
||||||
inipath = example_config._inipath
|
inipath = example_config._inipath
|
||||||
inipath.write_text(inipath.read_text().replace("60", "37"))
|
inipath.write_text(
|
||||||
|
inipath.read_text().replace(
|
||||||
|
"#max_user_send_per_minute = 60",
|
||||||
|
"max_user_send_per_minute = 37",
|
||||||
|
)
|
||||||
|
)
|
||||||
example_config = read_config(inipath)
|
example_config = read_config(inipath)
|
||||||
assert example_config.max_user_send_per_minute == 37
|
assert example_config.max_user_send_per_minute == 37
|
||||||
assert example_config.mail_domain == "chat.example.org"
|
assert example_config.mail_domain == "chat.example.org"
|
||||||
@@ -31,26 +36,17 @@ def test_read_config_basic_using_defaults(tmp_path, maildomain):
|
|||||||
example_config = read_config(inipath)
|
example_config = read_config(inipath)
|
||||||
assert example_config.max_user_send_per_minute == 60
|
assert example_config.max_user_send_per_minute == 60
|
||||||
assert example_config.filtermail_smtp_port_incoming == 10081
|
assert example_config.filtermail_smtp_port_incoming == 10081
|
||||||
|
assert example_config.filtermail_smtp_port == 10080
|
||||||
|
assert example_config.postfix_reinject_port == 10025
|
||||||
def test_read_config_testrun(make_config):
|
assert example_config.max_user_send_per_minute == 60
|
||||||
config = make_config("something.testrun.org")
|
assert example_config.max_mailbox_size == "500M"
|
||||||
assert config.mail_domain == "something.testrun.org"
|
assert example_config.delete_mails_after == "20"
|
||||||
assert len(config.privacy_postal.split("\n")) > 1
|
assert example_config.delete_large_after == "7"
|
||||||
assert len(config.privacy_supervisor.split("\n")) > 1
|
assert example_config.username_min_length == 9
|
||||||
assert len(config.privacy_pdo.split("\n")) > 1
|
assert example_config.username_max_length == 9
|
||||||
assert config.privacy_mail == "privacy@testrun.org"
|
assert example_config.password_min_length == 9
|
||||||
assert config.filtermail_smtp_port == 10080
|
assert example_config.passthrough_recipients == []
|
||||||
assert config.postfix_reinject_port == 10025
|
assert example_config.passthrough_senders == []
|
||||||
assert config.max_user_send_per_minute == 60
|
|
||||||
assert config.max_mailbox_size == "500M"
|
|
||||||
assert config.delete_mails_after == "20"
|
|
||||||
assert config.delete_large_after == "7"
|
|
||||||
assert config.username_min_length == 9
|
|
||||||
assert config.username_max_length == 9
|
|
||||||
assert config.password_min_length == 9
|
|
||||||
assert "privacy@testrun.org" in config.passthrough_recipients
|
|
||||||
assert config.passthrough_senders == []
|
|
||||||
|
|
||||||
|
|
||||||
def test_config_userstate_paths(make_config, tmp_path):
|
def test_config_userstate_paths(make_config, tmp_path):
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
/^DKIM-Signature:/ IGNORE
|
/^From:/ DUNNO
|
||||||
/^Authentication-Results:/ IGNORE
|
/^Message-Id:/ DUNNO
|
||||||
/^Received:/ IGNORE
|
/^Chat-Is-Post-Message:/ DUNNO
|
||||||
|
/^Content-Type:/ DUNNO
|
||||||
|
/^Subject:/ DUNNO
|
||||||
|
/.*/ IGNORE
|
||||||
|
|||||||
Reference in New Issue
Block a user