From 7facf79b3c33fc88507ff9cff5398258d3879df2 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:36:30 +1300 Subject: [PATCH] Apply suggestions from code review --- docs/content/config/environment.md | 6 +++++- mailserver.env | 1 + target/dovecot/dovecot-oauth2.conf.ext | 3 ++- test/config/oauth2/provider.py | 6 ++++++ test/tests/serial/mail_with_oauth2.bats | 7 ++++--- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index 9efec26f..bd210c6c 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -55,10 +55,13 @@ The Group ID assigned to the static vmail group for `/var/mail` (_Mail storage m Configures the provisioning source of user accounts (including aliases) for user queries and authentication by services managed by DMS (_Postfix and Dovecot_). !!! tip "OAuth2 Support" + Presently DMS supports OAuth2 only as an supplementary authentication method. + - A third-party service must provide a valid token for the user which Dovecot validates with the authentication service provider. To enable this feature reference the [OAuth2 configuration example guide][docs::auth::oauth2-config-guide]. - User accounts must be provisioned to receive mail via one of the supported `ACCOUNT_PROVISIONER` providers. - User provisioning via OAUTH2 is planned for the future, see [this tracking issue](https://github.com/docker-mailserver/docker-mailserver/issues/2713). + [docs::auth::oauth2-config-guide]: ./advanced/auth-oauth2.md - **empty** => use FILE @@ -620,7 +623,8 @@ Enable or disable `getmail`. ##### OAUTH2_INTROSPECTION_URL -- => Specify the user info endpoint URL of the oauth2 provider. E.g. `https://oauth2.example.com/userinfo/`, where the trailing slash is MANDATORY (at least for Authentik) +- => Specify the user info endpoint URL of the oauth2 provider (_eg: `https://oauth2.example.com/userinfo/`_) + #### LDAP ##### LDAP_START_TLS diff --git a/mailserver.env b/mailserver.env index c9b3ddd3..6dcc0bd6 100644 --- a/mailserver.env +++ b/mailserver.env @@ -427,6 +427,7 @@ GETMAIL_POLL=5 ENABLE_OAUTH2= # Specify the user info endpoint URL of the oauth2 provider. The trailing slash is MANDATORY (at least for Authentik) +# Example: https://oauth2.example.com/userinfo/ OAUTH2_INTROSPECTION_URL= # ----------------------------------------------- diff --git a/target/dovecot/dovecot-oauth2.conf.ext b/target/dovecot/dovecot-oauth2.conf.ext index b93f5208..c3128900 100644 --- a/target/dovecot/dovecot-oauth2.conf.ext +++ b/target/dovecot/dovecot-oauth2.conf.ext @@ -1 +1,2 @@ -introspection_url = +introspection_url = +introspection_mode = auth diff --git a/test/config/oauth2/provider.py b/test/config/oauth2/provider.py index 726edd3c..22fc8129 100644 --- a/test/config/oauth2/provider.py +++ b/test/config/oauth2/provider.py @@ -1,3 +1,8 @@ +# OAuth2 mock service +# +# Dovecot will query this service with the token it was provided. +# If the session for the token is valid, a response provides an attribute to perform a UserDB lookup on (default: email). + import json import base64 from http.server import BaseHTTPRequestHandler, HTTPServer @@ -25,6 +30,7 @@ class HTTPRequestHandler(BaseHTTPRequestHandler): self.end_headers() return auth = auth.split()[1] + # Valid session, respond with JSON containing the expected `email` claim to match as Dovecot username: if auth == token: self.send_response(200) self.send_header('Content-Type', 'application/json') diff --git a/test/tests/serial/mail_with_oauth2.bats b/test/tests/serial/mail_with_oauth2.bats index d9f6310e..ba3bf261 100644 --- a/test/tests/serial/mail_with_oauth2.bats +++ b/test/tests/serial/mail_with_oauth2.bats @@ -32,7 +32,7 @@ function setup_file() { # Add OAUTH2 configuration so that Dovecot can reach out to our mock provider (CONTAINER2) local ENV_OAUTH2_CONFIG=( --env ENABLE_OAUTH2=1 - --env OAUTH2_INTROSPECTION_URL=http://oauth2.example.test/ + --env OAUTH2_INTROSPECTION_URL=http://oauth2.example.test/userinfo/ ) export CONTAINER_NAME=${CONTAINER1_NAME} @@ -45,7 +45,7 @@ function setup_file() { _init_with_defaults _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' - _wait_for_smtp_port_in_container + _wait_for_tcp_port_in_container 143 # Set default implicit container fallback for helpers: export CONTAINER_NAME=${CONTAINER1_NAME} @@ -58,8 +58,9 @@ function teardown_file() { @test "oauth2: imap connect and authentication works" { + # An initial connection needs to be made first, otherwise the auth attempt fails _run_in_container_bash 'nc -vz 0.0.0.0 143' - _run_in_container_bash 'sleep 5' + _run_in_container_bash 'nc -w 1 0.0.0.0 143 < /tmp/docker-mailserver-test/auth/imap-oauth2-auth.txt' assert_output --partial 'Examine completed' }