Skip to content

Commit

Permalink
Merge pull request #563 from modoboa/feature/dovecot_oauth2_setup
Browse files Browse the repository at this point in the history
Added setup instructions for Dovecot oauth2 support
  • Loading branch information
tonioo authored Aug 2, 2024
2 parents d05618e + 81f1332 commit cb06459
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 8 deletions.
1 change: 0 additions & 1 deletion modoboa_installer/config_dict_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ def is_email(user_input):
"option": "extensions",
"default": (
"modoboa-amavis "
"modoboa-postfix-autoreply modoboa-sievefilters "
"modoboa-webmail modoboa-contacts "
"modoboa-radicale"
),
Expand Down
40 changes: 34 additions & 6 deletions modoboa_installer/scripts/dovecot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import pwd
import shutil
import uuid

from .. import database
from .. import package
Expand All @@ -14,7 +15,6 @@


class Dovecot(base.Installer):

"""Dovecot installer."""

appname = "dovecot"
Expand All @@ -27,7 +27,9 @@ class Dovecot(base.Installer):
}
config_files = [
"dovecot.conf", "dovecot-dict-sql.conf.ext", "conf.d/10-ssl.conf",
"conf.d/10-master.conf", "conf.d/20-lmtp.conf", "conf.d/10-ssl-keys.try"]
"conf.d/10-master.conf", "conf.d/20-lmtp.conf", "conf.d/10-ssl-keys.try",
"conf.d/dovecot-oauth2.conf.ext"
]
with_user = True

def setup_user(self):
Expand All @@ -53,17 +55,35 @@ def get_packages(self):
if package.backend.FORMAT == "deb":
if "pop3" in self.config.get("dovecot", "extra_protocols"):
packages += ["dovecot-pop3d"]
return super(Dovecot, self).get_packages() + packages
return super().get_packages() + packages

def install_packages(self):
"""Preconfigure Dovecot if needed."""
package.backend.preconfigure(
"dovecot-core", "create-ssl-cert", "boolean", "false")
super(Dovecot, self).install_packages()
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(Dovecot, self).get_template_context()
context = super().get_template_context()
pw_mailbox = pwd.getpwnam(self.mailboxes_owner)
dovecot_package = {"deb": "dovecot-core", "rpm": "dovecot"}
ssl_protocol_parameter = "ssl_protocols"
Expand All @@ -84,6 +104,13 @@ def get_template_context(self):
# Protocols are automatically guessed on debian/ubuntu
protocols = ""

oauth2_client_id, oauth2_client_secret = self.create_oauth2_app()
hostname = self.config.get("general", "hostname")
oauth2_introspection_url = (
f"https://{oauth2_client_id}:{oauth2_client_secret}"
f"@{hostname}/api/o/introspect/"
)

context.update({
"db_driver": self.db_driver,
"mailboxes_owner_uid": pw_mailbox[2],
Expand All @@ -100,7 +127,8 @@ def get_template_context(self):
"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 "#"
"not_modoboa_2_2_or_greater": "" if not self.modoboa_2_2_or_greater else "#",
"oauth2_introspection_url": oauth2_introspection_url
})
return context

Expand Down
3 changes: 2 additions & 1 deletion modoboa_installer/scripts/files/dovecot/conf.d/10-auth.conf
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ auth_master_user_separator = *
# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
# gss-spnego
# NOTE: See also disable_plaintext_auth setting.
auth_mechanisms = plain login
auth_mechanisms = plain login oauthbearer xoauth2

##
## Password and user databases
Expand All @@ -120,6 +120,7 @@ auth_mechanisms = plain login

#!include auth-system.conf.ext
!include auth-sql.conf.ext
!include auth-oauth2.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
passdb {
driver = oauth2
mechanisms = xoauth2 oauthbearer
args = /etc/dovecot/conf.d/dovecot-oauth2.conf.ext
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
introspection_mode = post
introspection_url = %{oauth2_introspection_url}
username_attribute = username
tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt
active_attribute = active
active_value = true
1 change: 1 addition & 0 deletions modoboa_installer/scripts/files/uwsgi/modoboa.ini.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ socket = %uwsgi_socket_path
chmod-socket = 660
vacuum = true
single-interpreter = True
buffer-size = 8192

0 comments on commit cb06459

Please sign in to comment.