Files
PyMTA-server/email_server/settings_loader.py

80 lines
3.0 KiB
Python
Raw Normal View History

2025-05-31 16:32:11 +01:00
"""
Settings loader for the SMTP server.
Automatically generates settings.ini with default values if not present.
"""
import configparser
from pathlib import Path
SETTINGS_PATH = Path(__file__).parent.parent / 'settings.ini'
2025-06-07 08:28:22 +01:00
# Default values and comments for settings.ini
2025-05-31 16:32:11 +01:00
DEFAULTS = {
'Server': {
2025-06-07 08:28:22 +01:00
'; Server configuration for SMTP ports and hostname': None,
'; Plain SMTP port for internal/whitelisted IPs': None,
2025-05-31 16:32:11 +01:00
'SMTP_PORT': '4025',
2025-06-07 08:28:22 +01:00
'; STARTTLS SMTP port for authenticated users': None,
2025-05-31 16:32:11 +01:00
'SMTP_TLS_PORT': '40587',
2025-06-07 08:28:22 +01:00
'; Server hostname for HELO/EHLO identification': None,
'HOSTNAME': 'mail.example.com',
2025-06-07 08:28:22 +01:00
'; Override HELO hostname': None,
'helo_hostname': 'mail.example.com',
2025-06-07 08:28:22 +01:00
'; IP address to bind to (0.0.0.0 = all interfaces), on Windows must use specific IP': None,
2025-05-31 16:32:11 +01:00
'BIND_IP': '0.0.0.0',
2025-06-07 08:28:22 +01:00
'; Custom server banner (to make it empty use "" must be double quotes)': None,
'server_banner': "",
2025-05-31 16:32:11 +01:00
},
'Database': {
2025-06-07 08:28:22 +01:00
'; Database configuration': None,
2025-05-31 16:32:11 +01:00
'DATABASE_URL': 'sqlite:///email_server/server_data/smtp_server.db',
},
'Logging': {
2025-06-07 08:28:22 +01:00
'; Logging configuration': None,
'; Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL': None,
2025-05-31 16:32:11 +01:00
'LOG_LEVEL': 'INFO',
2025-06-07 08:28:22 +01:00
'; Hide verbose aiosmtpd INFO messages when LOG_LEVEL = INFO': None,
2025-05-31 16:32:11 +01:00
'hide_info_aiosmtpd': 'true',
},
'Relay': {
2025-06-07 08:28:22 +01:00
'; Timeout in seconds for external SMTP connections': None,
2025-05-31 16:32:11 +01:00
'RELAY_TIMEOUT': '10',
},
'TLS': {
2025-06-07 08:28:22 +01:00
'; TLS/SSL certificate configuration': None,
2025-05-31 16:32:11 +01:00
'TLS_CERT_FILE': 'email_server/ssl_certs/server.crt',
'TLS_KEY_FILE': 'email_server/ssl_certs/server.key',
},
'DKIM': {
2025-06-07 08:28:22 +01:00
'; DKIM signing configuration': None,
'; RSA key size for DKIM keys (1024, 2048, 4096)': None,
2025-05-31 16:32:11 +01:00
'DKIM_KEY_SIZE': '2048',
2025-06-07 14:43:00 +01:00
'; Provide Public IP address of server, used for SPF in case detection fails': None,
'SPF_SERVER_IP': '192.168.1.1',
2025-05-31 16:32:11 +01:00
},
}
def generate_settings_ini(settings_path: Path = SETTINGS_PATH) -> None:
2025-06-07 08:28:22 +01:00
"""Generate settings.ini with default values and comments if it does not exist."""
2025-05-31 16:32:11 +01:00
if settings_path.exists():
return
2025-06-07 08:28:22 +01:00
config_parser = configparser.ConfigParser(allow_no_value=True)
2025-05-31 16:32:11 +01:00
for section, values in DEFAULTS.items():
2025-06-07 08:28:22 +01:00
config_parser.add_section(section)
for key, value in values.items():
if key.startswith(';'):
# This is a comment line
config_parser.set(section, key)
else:
# This is a setting with value
config_parser.set(section, key, value)
2025-05-31 16:32:11 +01:00
with open(settings_path, 'w') as f:
config_parser.write(f)
def load_settings(settings_path: Path = SETTINGS_PATH) -> configparser.ConfigParser:
"""Load settings from settings.ini, generating it if needed."""
generate_settings_ini(settings_path)
config_parser = configparser.ConfigParser()
config_parser.read(settings_path)
return config_parser