Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 14 additions & 41 deletions chatmaild/src/chatmaild/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@
def read_config(inipath):
assert Path(inipath).exists(), inipath
cfg = iniconfig.IniConfig(inipath)
params = cfg.sections["params"]
default_config_content = get_default_config_content(params["mail_domain"])
Comment thread
missytake marked this conversation as resolved.
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)
return Config(inipath, params=cfg.sections["params"])


class Config:
Expand All @@ -36,16 +31,18 @@ def __init__(self, inipath, params):

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_mailbox_size = params["max_mailbox_size"]
self.max_message_size = int(params.get("max_message_size", "31457280"))
self.delete_mails_after = params["delete_mails_after"]
self.delete_large_after = params["delete_large_after"]
self.delete_inactive_users_after = int(params["delete_inactive_users_after"])
self.username_min_length = int(params["username_min_length"])
self.username_max_length = int(params["username_max_length"])
self.password_min_length = int(params["password_min_length"])
self.passthrough_senders = params["passthrough_senders"].split()
self.passthrough_recipients = params["passthrough_recipients"].split()
self.max_mailbox_size = params.get("max_mailbox_size", "500M")
self.max_message_size = int(params.get("max_message_size", 31457280))
self.delete_mails_after = params.get("delete_mails_after", "20")
self.delete_large_after = params.get("delete_large_after", "7")
self.delete_inactive_users_after = int(
params.get("delete_inactive_users_after", 90)
)
self.username_min_length = int(params.get("username_min_length", 9))
self.username_max_length = int(params.get("username_max_length", 9))
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.filtermail_smtp_port = int(params.get("filtermail_smtp_port", "10080"))
self.filtermail_smtp_port_incoming = int(
Expand Down Expand Up @@ -164,31 +161,7 @@ def get_default_config_content(mail_domain, **overrides):
for name, value in extra.items():
new_line = f"{name} = {value}"
new_lines.append(new_line)

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
return "\n".join(new_lines)


def is_valid_ipv4(address: str) -> bool:
Expand Down
42 changes: 21 additions & 21 deletions chatmaild/src/chatmaild/ini/chatmail.ini.f
Original file line number Diff line number Diff line change
Expand Up @@ -12,42 +12,42 @@
#

# 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)
max_user_send_burst_size = 10
#max_user_send_burst_size = 10

# maximum mailbox size of a chatmail address
# Oldest messages will be removed automatically, so mailboxes never run full.
max_mailbox_size = 500M
# (Oldest messages will be removed automatically, so mailboxes never run full)
#max_mailbox_size = 500M

# maximum message size for an e-mail in bytes
max_message_size = 31457280
#max_message_size = 31457280

# days after which mails are unconditionally deleted
delete_mails_after = 20
#delete_mails_after = 20

# 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)
delete_inactive_users_after = 90
#delete_inactive_users_after = 90

# minimum length a username must have
username_min_length = 9
#username_min_length = 9

# maximum length a username can have
username_max_length = 9
#username_max_length = 9

# 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
passthrough_senders =
#passthrough_senders =

# list of e-mail recipients for which to accept outbound un-encrypted mails
# (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.
# Paths refer to files on the deployment server (not the build machine).
Expand All @@ -64,18 +64,18 @@
#

# SMTP outgoing filtermail and reinjection
filtermail_smtp_port = 10080
postfix_reinject_port = 10025
#filtermail_smtp_port = 10080
#postfix_reinject_port = 10025

# SMTP incoming filtermail and reinjection
filtermail_smtp_port_incoming = 10081
postfix_reinject_port_incoming = 10026
#filtermail_smtp_port_incoming = 10081
#postfix_reinject_port_incoming = 10026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd remove them entirely from chatmail.ini
filtermail_http_port_incoming and filtermail_lmtp_port_transport are already missing.
If someone really wants to fiddle at this level, they need to read the source for config.py.

# 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
acme_email =
#acme_email =

# Defaults to https://iroh.{{mail_domain}} and running `iroh-relay` on the chatmail
# service.
Expand Down Expand Up @@ -108,13 +108,13 @@
# in per-maildir ".in/.out" files.
# Note that you need to manually cleanup these files
# 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,
# which allows IMAP connections to be efficiently compressed.
# WARNING: Enabling this makes it impossible to hibernate IMAP
# processes which will result in much higher memory/RAM usage.
imap_compress = false
#imap_compress = false


#
Expand Down
16 changes: 0 additions & 16 deletions chatmaild/src/chatmaild/ini/override-testrun.ini

This file was deleted.

38 changes: 17 additions & 21 deletions chatmaild/src/chatmaild/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ def test_read_config_basic(example_config):
assert not example_config.privacy_pdo and not example_config.privacy_postal

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)
assert example_config.max_user_send_per_minute == 37
assert example_config.mail_domain == "chat.example.org"
Expand All @@ -31,26 +36,17 @@ def test_read_config_basic_using_defaults(tmp_path, maildomain):
example_config = read_config(inipath)
assert example_config.max_user_send_per_minute == 60
assert example_config.filtermail_smtp_port_incoming == 10081


def test_read_config_testrun(make_config):
config = make_config("something.testrun.org")
assert config.mail_domain == "something.testrun.org"
assert len(config.privacy_postal.split("\n")) > 1
assert len(config.privacy_supervisor.split("\n")) > 1
assert len(config.privacy_pdo.split("\n")) > 1
assert config.privacy_mail == "privacy@testrun.org"
assert config.filtermail_smtp_port == 10080
assert config.postfix_reinject_port == 10025
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 == []
assert example_config.filtermail_smtp_port == 10080
assert example_config.postfix_reinject_port == 10025
assert example_config.max_user_send_per_minute == 60
assert example_config.max_mailbox_size == "500M"
assert example_config.delete_mails_after == "20"
assert example_config.delete_large_after == "7"
assert example_config.username_min_length == 9
assert example_config.username_max_length == 9
assert example_config.password_min_length == 9
assert example_config.passthrough_recipients == []
assert example_config.passthrough_senders == []


def test_config_userstate_paths(make_config, tmp_path):
Expand Down