Compat with Modoboa 2.4.0

This commit is contained in:
Antoine Nguyen
2025-07-03 10:43:07 +02:00
parent 5fe3e49b9a
commit 53669b48de
12 changed files with 50 additions and 66 deletions

View File

@@ -142,7 +142,7 @@ class Backup:
"""
Custom config :
- DKIM keys: {{keys_storage_dir}}
- Radicale collection (calendat, contacts): {{home_dir}}
- Radicale collection (calendars, contacts): {{home_dir}}
- Amavis : /etc/amavis/conf.d/99-custom
- Postwhite : /etc/postwhite.conf
Feel free to suggest to add others!

View File

@@ -72,24 +72,6 @@ class Dovecot(base.Installer):
"dovecot-core", "create-ssl-cert", "boolean", "false")
super().install_packages()
def create_oauth2_app(self):
"""Create a application for Oauth2 authentication."""
# FIXME: how can we check that application already exists ?
venv_path = self.config.get("modoboa", "venv_path")
python_path = os.path.join(venv_path, "bin", "python")
instance_path = self.config.get("modoboa", "instance_path")
script_path = os.path.join(instance_path, "manage.py")
client_id = "dovecot"
client_secret = str(uuid.uuid4())
cmd = (
f"{python_path} {script_path} createapplication "
f"--name=Dovecot --skip-authorization "
f"--client-id={client_id} --client-secret={client_secret} "
f"confidential client-credentials"
)
utils.exec_cmd(cmd)
return client_id, client_secret
def get_template_context(self):
"""Additional variables."""
context = super().get_template_context()
@@ -113,7 +95,8 @@ class Dovecot(base.Installer):
# Protocols are automatically guessed on debian/ubuntu
protocols = ""
oauth2_client_id, oauth2_client_secret = self.create_oauth2_app()
oauth2_client_id, oauth2_client_secret = utils.create_oauth2_app(
"Dovecot", "dovecot", self.config)
hostname = self.config.get("general", "hostname")
oauth2_introspection_url = (
f"https://{oauth2_client_id}:{oauth2_client_secret}"
@@ -132,9 +115,6 @@ class Dovecot(base.Installer):
"protocols": protocols,
"ssl_protocols": ssl_protocols,
"ssl_protocol_parameter": ssl_protocol_parameter,
"radicale_user": self.config.get("radicale", "user"),
"radicale_auth_socket_path": os.path.basename(
self.config.get("dovecot", "radicale_auth_socket_path")),
"modoboa_2_2_or_greater": "" if self.modoboa_2_2_or_greater else "#",
"not_modoboa_2_2_or_greater": "" if not self.modoboa_2_2_or_greater else "#",
"oauth2_introspection_url": oauth2_introspection_url

View File

@@ -131,13 +131,6 @@ service auth {
group = postfix
}
# Radicale auth
%{radicale_enabled}unix_listener %{radicale_auth_socket_path} {
%{radicale_enabled} mode = 0666
%{radicale_enabled} user = %{radicale_user}
%{radicale_enabled} group = %{radicale_user}
%{radicale_enabled}}
# Auth process is run as this user.
#user = $default_internal_user
}

View File

@@ -37,7 +37,13 @@ server {
try_files $uri $uri/ =404;
}
location ^~ /new-admin {
location ~ ^/(api|accounts) {
include uwsgi_params;
uwsgi_param UWSGI_SCRIPT instance.wsgi:application;
uwsgi_pass modoboa;
}
location / {
alias %{app_instance_path}/frontend/;
index index.html;
@@ -48,10 +54,5 @@ server {
try_files $uri $uri/ /index.html = 404;
}
location / {
include uwsgi_params;
uwsgi_param UWSGI_SCRIPT instance.wsgi:application;
uwsgi_pass modoboa;
}
%{extra_config}
}

View File

@@ -124,11 +124,6 @@ mailman unix - n n - - pipe
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
${nexthop} ${user}
# Modoboa autoreply service
#
autoreply unix - n n - - pipe
flags= user=%{dovecot_mailboxes_owner}:%{dovecot_mailboxes_owner} argv=%{modoboa_venv_path}/bin/python %{modoboa_instance_path}/manage.py autoreply $sender $mailbox
# Amavis return path
#
%{amavis_enabled}127.0.0.1:10025 inet n - n - - smtpd

View File

@@ -71,7 +71,7 @@
# Authentication method
# Value: none | htpasswd | remote_user | http_x_remote_user
type = dovecot
type = radicale_modoboa_auth_oauth2
# Htpasswd filename
# htpasswd_filename = users
@@ -85,7 +85,7 @@ type = dovecot
# Incorrect authentication delay (seconds)
#delay = 1
dovecot_socket = %{auth_socket_path}
oauth2_introspection_endpoint = %{oauth2_introspection_url}
[rights]

View File

@@ -13,4 +13,5 @@ socket = %uwsgi_socket_path
chmod-socket = 660
vacuum = true
single-interpreter = True
max-requests = 5000
buffer-size = 8192

View File

@@ -56,9 +56,6 @@ class Modoboa(base.Installer):
self.amavis_enabled = True
else:
self.extensions.remove("modoboa-amavis")
if "modoboa-radicale" in self.extensions:
if not self.config.getboolean("radicale", "enabled"):
self.extensions.remove("modoboa-radicale")
self.dovecot_enabled = self.config.getboolean("dovecot", "enabled")
self.opendkim_enabled = self.config.getboolean("opendkim", "enabled")
self.dkim_cron_enabled = False
@@ -243,8 +240,6 @@ class Modoboa(base.Installer):
),
"dovecot_mailboxes_owner": (
self.config.get("dovecot", "mailboxes_owner")),
"radicale_enabled": (
"" if "modoboa-radicale" in extensions else "#"),
"opendkim_user": self.config.get("opendkim", "user"),
"minutes": random.randint(1, 59),
"hours": f"{random_hour},{random_hour+12}",
@@ -276,7 +271,7 @@ class Modoboa(base.Installer):
"pdfcredentials": {
"storage_dir": pdf_storage_dir
},
"modoboa_radicale": {
"calendars": {
"server_location": "https://{}/radicale/".format(
self.config.get("general", "hostname")),
"rights_file_path": "{}/rights".format(

View File

@@ -33,7 +33,7 @@ class Radicale(base.Installer):
"""Prepare a dedicated virtualenv."""
python.setup_virtualenv(self.venv_path, sudo_user=self.user)
packages = [
"Radicale", "pytz"
"Radicale", "pytz", "radicale-modoboa-auth-oauth2"
]
python.install_packages(packages, self.venv_path, sudo_user=self.user)
python.install_package_from_repository(
@@ -43,17 +43,22 @@ class Radicale(base.Installer):
def get_template_context(self):
"""Additional variables."""
context = super(Radicale, self).get_template_context()
radicale_auth_socket_path = self.config.get(
"dovecot", "radicale_auth_socket_path")
context = super().get_template_context()
oauth2_client_id, oauth2_client_secret = utils.create_oauth2_app(
"Radicale", "radicale", self.config)
hostname = self.config.get("general", "hostname")
oauth2_introspection_url = (
f"https://{oauth2_client_id}:{oauth2_client_secret}"
f"@{hostname}/api/o/introspect/"
)
context.update({
"auth_socket_path": radicale_auth_socket_path
"oauth2_introspection_url": oauth2_introspection_url,
})
return context
def get_config_files(self):
"""Return appropriate path."""
config_files = super(Radicale, self).get_config_files()
config_files = super().get_config_files()
if package.backend.FORMAT == "deb":
path = "supervisor=/etc/supervisor/conf.d/radicale.conf"
else: