mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
feat: Auth - OAuth2 (Dovecot PassDB) (#3480)
Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
This commit is contained in:
parent
06fab3f129
commit
52c4582f7b
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
.env
|
.env
|
||||||
|
compose.override.yaml
|
||||||
docs/site/
|
docs/site/
|
||||||
docker-data/
|
docker-data/
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,13 @@ All notable changes to this project will be documented in this file. The format
|
||||||
|
|
||||||
> **Note**: Changes and additions listed here are contained in the `:edge` image tag. These changes may not be as stable as released changes.
|
> **Note**: Changes and additions listed here are contained in the `:edge` image tag. These changes may not be as stable as released changes.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- **Authentication with OIDC / OAuth 2.0** 🎉
|
||||||
|
- DMS now supports authentication via OAuth2 (_via `XOAUTH2` or `OAUTHBEARER` SASL mechanisms_) from capable services (_like Roundcube_).
|
||||||
|
- This does not replace the need for an `ACCOUNT_PROVISIONER` (`FILE` / `LDAP`), which is required for an account to receive or send mail.
|
||||||
|
- Successful authentication (_via Dovecot PassDB_) still requires an existing account (_lookup via Dovecot UserDB_).
|
||||||
|
|
||||||
### Updates
|
### Updates
|
||||||
|
|
||||||
- **Tests**:
|
- **Tests**:
|
||||||
|
|
|
@ -108,6 +108,13 @@ EOF
|
||||||
COPY target/rspamd/local.d/ /etc/rspamd/local.d/
|
COPY target/rspamd/local.d/ /etc/rspamd/local.d/
|
||||||
COPY target/rspamd/scores.d/* /etc/rspamd/scores.d/
|
COPY target/rspamd/scores.d/* /etc/rspamd/scores.d/
|
||||||
|
|
||||||
|
# -----------------------------------------------
|
||||||
|
# --- OAUTH2 ------------------------------------
|
||||||
|
# -----------------------------------------------
|
||||||
|
|
||||||
|
COPY target/dovecot/auth-oauth2.conf.ext /etc/dovecot/conf.d
|
||||||
|
COPY target/dovecot/dovecot-oauth2.conf.ext /etc/dovecot
|
||||||
|
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
# --- LDAP & SpamAssassin's Cron ----------------
|
# --- LDAP & SpamAssassin's Cron ----------------
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
|
|
|
@ -48,3 +48,4 @@ If you have issues, please search through [the documentation][documentation::web
|
||||||
- Support for [LetsEncrypt](https://letsencrypt.org/), manual and self-signed certificates
|
- Support for [LetsEncrypt](https://letsencrypt.org/), manual and self-signed certificates
|
||||||
- A [setup script](https://docker-mailserver.github.io/docker-mailserver/latest/config/setup.sh) for easy configuration and maintenance
|
- A [setup script](https://docker-mailserver.github.io/docker-mailserver/latest/config/setup.sh) for easy configuration and maintenance
|
||||||
- SASLauthd with LDAP authentication
|
- SASLauthd with LDAP authentication
|
||||||
|
- OAuth2 authentication (_via `XOAUTH2` or `OAUTHBEARER` SASL mechanisms_)
|
||||||
|
|
69
docs/content/config/advanced/auth-oauth2.md
Normal file
69
docs/content/config/advanced/auth-oauth2.md
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
---
|
||||||
|
title: 'Advanced | Basic OAuth2 Authentication'
|
||||||
|
---
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
!!! warning "This is only a supplement to the existing account provisioners"
|
||||||
|
|
||||||
|
Accounts must still be managed via the configured [`ACCOUNT_PROVISIONER`][env::account-provisioner] (FILE or LDAP).
|
||||||
|
|
||||||
|
Reasoning for this can be found in [#3480][gh-pr::oauth2]. Future iterations on this feature may allow it to become a full account provisioner.
|
||||||
|
|
||||||
|
[gh-pr::oauth2]: https://github.com/docker-mailserver/docker-mailserver/pull/3480
|
||||||
|
[env::account-provisioner]: ../environment.md#account_provisioner
|
||||||
|
|
||||||
|
The present OAuth2 support provides the capability for 3rd-party applications such as Roundcube to authenticate with DMS (dovecot) by using a token obtained from an OAuth2 provider, instead of passing passwords around.
|
||||||
|
|
||||||
|
## Example (Authentik & Roundcube)
|
||||||
|
|
||||||
|
This example assumes you have:
|
||||||
|
|
||||||
|
- A working DMS server set up
|
||||||
|
- An Authentik server set up ([documentation](https://goauthentik.io/docs/installation/))
|
||||||
|
- A Roundcube server set up (either [docker](https://hub.docker.com/r/roundcube/roundcubemail/) or [bare metal](https://github.com/roundcube/roundcubemail/wiki/Installation))
|
||||||
|
|
||||||
|
!!! example "Setup Instructions"
|
||||||
|
|
||||||
|
=== "1. Docker Mailserver"
|
||||||
|
Edit the following values in `mailserver.env`:
|
||||||
|
```env
|
||||||
|
# -----------------------------------------------
|
||||||
|
# --- OAUTH2 Section ----------------------------
|
||||||
|
# -----------------------------------------------
|
||||||
|
|
||||||
|
# empty => OAUTH2 authentication is disabled
|
||||||
|
# 1 => OAUTH2 authentication is enabled
|
||||||
|
ENABLE_OAUTH2=1
|
||||||
|
|
||||||
|
# Specify the user info endpoint URL of the oauth2 provider
|
||||||
|
OAUTH2_INTROSPECTION_URL=https://authentik.example.com/application/o/userinfo/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "2. Authentik"
|
||||||
|
1. Create a new OAuth2 provider
|
||||||
|
2. Note the client id and client secret
|
||||||
|
3. Set the allowed redirect url to the equivalent of `https://roundcube.example.com/index.php/login/oauth` for your RoundCube instance.
|
||||||
|
|
||||||
|
=== "3. Roundcube"
|
||||||
|
Add the following to `oauth2.inc.php` ([documentation](https://github.com/roundcube/roundcubemail/wiki/Configuration)):
|
||||||
|
|
||||||
|
```php
|
||||||
|
$config['oauth_provider'] = 'generic';
|
||||||
|
$config['oauth_provider_name'] = 'Authentik';
|
||||||
|
$config['oauth_client_id'] = '<insert client id here>';
|
||||||
|
$config['oauth_client_secret'] = '<insert client secret here>';
|
||||||
|
$config['oauth_auth_uri'] = 'https://authentik.example.com/application/o/authorize/';
|
||||||
|
$config['oauth_token_uri'] = 'https://authentik.example.com/application/o/token/';
|
||||||
|
$config['oauth_identity_uri'] = 'https://authentik.example.com/application/o/userinfo/';
|
||||||
|
|
||||||
|
// Optional: disable SSL certificate check on HTTP requests to OAuth server. For possible values, see:
|
||||||
|
// http://docs.guzzlephp.org/en/stable/request-options.html#verify
|
||||||
|
$config['oauth_verify_peer'] = false;
|
||||||
|
|
||||||
|
$config['oauth_scope'] = 'email openid profile';
|
||||||
|
$config['oauth_identity_fields'] = ['email'];
|
||||||
|
|
||||||
|
// Boolean: automatically redirect to OAuth login when opening Roundcube without a valid session
|
||||||
|
$config['oauth_login_redirect'] = false;
|
||||||
|
```
|
|
@ -54,7 +54,15 @@ 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_).
|
Configures the provisioning source of user accounts (including aliases) for user queries and authentication by services managed by DMS (_Postfix and Dovecot_).
|
||||||
|
|
||||||
User provisioning via OIDC is planned for the future, see [this tracking issue](https://github.com/docker-mailserver/docker-mailserver/issues/2713).
|
!!! 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 OIDC 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
|
- **empty** => use FILE
|
||||||
- LDAP => use LDAP authentication
|
- LDAP => use LDAP authentication
|
||||||
|
@ -716,10 +724,20 @@ Enable or disable `getmail`.
|
||||||
|
|
||||||
- **5** => `getmail` The number of minutes for the interval. Min: 1; Max: 30; Default: 5.
|
- **5** => `getmail` The number of minutes for the interval. Min: 1; Max: 30; Default: 5.
|
||||||
|
|
||||||
|
|
||||||
|
#### OAUTH2
|
||||||
|
|
||||||
|
##### ENABLE_OAUTH2
|
||||||
|
|
||||||
|
- **empty** => OAUTH2 authentication is disabled
|
||||||
|
- 1 => OAUTH2 authentication is enabled
|
||||||
|
|
||||||
|
##### OAUTH2_INTROSPECTION_URL
|
||||||
|
|
||||||
|
- => Specify the user info endpoint URL of the oauth2 provider (_eg: `https://oauth2.example.com/userinfo/`_)
|
||||||
|
|
||||||
#### LDAP
|
#### LDAP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### LDAP_START_TLS
|
##### LDAP_START_TLS
|
||||||
|
|
||||||
- **empty** => no
|
- **empty** => no
|
||||||
|
|
|
@ -142,6 +142,7 @@ nav:
|
||||||
- 'Postfix': config/advanced/override-defaults/postfix.md
|
- 'Postfix': config/advanced/override-defaults/postfix.md
|
||||||
- 'Modifications via Script': config/advanced/override-defaults/user-patches.md
|
- 'Modifications via Script': config/advanced/override-defaults/user-patches.md
|
||||||
- 'LDAP Authentication': config/advanced/auth-ldap.md
|
- 'LDAP Authentication': config/advanced/auth-ldap.md
|
||||||
|
- 'OAuth2 Authentication': config/advanced/auth-oauth2.md
|
||||||
- 'Email Filtering with Sieve': config/advanced/mail-sieve.md
|
- 'Email Filtering with Sieve': config/advanced/mail-sieve.md
|
||||||
- 'Email Gathering with Fetchmail': config/advanced/mail-fetchmail.md
|
- 'Email Gathering with Fetchmail': config/advanced/mail-fetchmail.md
|
||||||
- 'Email Gathering with Getmail': config/advanced/mail-getmail.md
|
- 'Email Gathering with Getmail': config/advanced/mail-getmail.md
|
||||||
|
|
|
@ -419,6 +419,18 @@ ENABLE_GETMAIL=0
|
||||||
# The number of minutes for the interval. Min: 1; Max: 30.
|
# The number of minutes for the interval. Min: 1; Max: 30.
|
||||||
GETMAIL_POLL=5
|
GETMAIL_POLL=5
|
||||||
|
|
||||||
|
# -----------------------------------------------
|
||||||
|
# --- OAUTH2 Section ----------------------------
|
||||||
|
# -----------------------------------------------
|
||||||
|
|
||||||
|
# empty => OAUTH2 authentication is disabled
|
||||||
|
# 1 => OAUTH2 authentication is enabled
|
||||||
|
ENABLE_OAUTH2=
|
||||||
|
|
||||||
|
# Specify the user info endpoint URL of the oauth2 provider
|
||||||
|
# Example: https://oauth2.example.com/userinfo/
|
||||||
|
OAUTH2_INTROSPECTION_URL=
|
||||||
|
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
# --- LDAP Section ------------------------------
|
# --- LDAP Section ------------------------------
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
|
|
|
@ -123,6 +123,7 @@ auth_mechanisms = plain login
|
||||||
#!include auth-sql.conf.ext
|
#!include auth-sql.conf.ext
|
||||||
#!include auth-ldap.conf.ext
|
#!include auth-ldap.conf.ext
|
||||||
!include auth-passwdfile.inc
|
!include auth-passwdfile.inc
|
||||||
|
#!include auth-oauth2.conf.ext
|
||||||
#!include auth-checkpassword.conf.ext
|
#!include auth-checkpassword.conf.ext
|
||||||
#!include auth-vpopmail.conf.ext
|
#!include auth-vpopmail.conf.ext
|
||||||
#!include auth-static.conf.ext
|
#!include auth-static.conf.ext
|
||||||
|
|
7
target/dovecot/auth-oauth2.conf.ext
Normal file
7
target/dovecot/auth-oauth2.conf.ext
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
auth_mechanisms = $auth_mechanisms oauthbearer xoauth2
|
||||||
|
|
||||||
|
passdb {
|
||||||
|
driver = oauth2
|
||||||
|
mechanisms = xoauth2 oauthbearer
|
||||||
|
args = /etc/dovecot/dovecot-oauth2.conf.ext
|
||||||
|
}
|
4
target/dovecot/dovecot-oauth2.conf.ext
Normal file
4
target/dovecot/dovecot-oauth2.conf.ext
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
introspection_url =
|
||||||
|
# Dovecot defaults:
|
||||||
|
introspection_mode = auth
|
||||||
|
username_attribute = email
|
|
@ -71,6 +71,11 @@ function _register_functions() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if [[ ${ENABLE_OAUTH2} -eq 1 ]]; then
|
||||||
|
_environment_variables_oauth2
|
||||||
|
_register_setup_function '_setup_oauth2'
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]]; then
|
if [[ ${ENABLE_SASLAUTHD} -eq 1 ]]; then
|
||||||
_environment_variables_saslauthd
|
_environment_variables_saslauthd
|
||||||
_register_setup_function '_setup_saslauthd'
|
_register_setup_function '_setup_saslauthd'
|
||||||
|
|
11
target/scripts/startup/setup.d/oauth2.sh
Normal file
11
target/scripts/startup/setup.d/oauth2.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function _setup_oauth2() {
|
||||||
|
_log 'debug' 'Setting up OAUTH2'
|
||||||
|
|
||||||
|
# Enable OAuth2 PassDB (Authentication):
|
||||||
|
sedfile -i -e '/\!include auth-oauth2\.conf\.ext/s/^#//' /etc/dovecot/conf.d/10-auth.conf
|
||||||
|
_replace_by_env_in_file 'OAUTH2_' '/etc/dovecot/dovecot-oauth2.conf.ext'
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
|
@ -151,6 +151,12 @@ function __environment_variables_general_setup() {
|
||||||
VARS[UPDATE_CHECK_INTERVAL]="${UPDATE_CHECK_INTERVAL:=1d}"
|
VARS[UPDATE_CHECK_INTERVAL]="${UPDATE_CHECK_INTERVAL:=1d}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _environment_variables_oauth2() {
|
||||||
|
_log 'debug' 'Setting OAUTH2-related environment variables now'
|
||||||
|
|
||||||
|
VARS[OAUTH2_INTROSPECTION_URL]="${OAUTH2_INTROSPECTION_URL:=}"
|
||||||
|
}
|
||||||
|
|
||||||
# This function handles environment variables related to LDAP.
|
# This function handles environment variables related to LDAP.
|
||||||
# NOTE: SASLAuthd and Dovecot LDAP support inherit these common ENV.
|
# NOTE: SASLAuthd and Dovecot LDAP support inherit these common ENV.
|
||||||
function _environment_variables_ldap() {
|
function _environment_variables_ldap() {
|
||||||
|
|
56
test/config/oauth2/provider.py
Normal file
56
test/config/oauth2/provider.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# OAuth2.0 Bearer token (paste into https://jwt.io/ to check it's contents).
|
||||||
|
# You should never need to edit this unless you REALLY need to change the issuer.
|
||||||
|
token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vcHJvdmlkZXIuZXhhbXBsZS50ZXN0OjgwMDAvIiwic3ViIjoiODJjMWMzMzRkY2M2ZTMxMWFlNGFhZWJmZTk0NmM1ZTg1OGYwNTVhZmYxY2U1YTM3YWE3Y2M5MWFhYjE3ZTM1YyIsImF1ZCI6Im1haWxzZXJ2ZXIiLCJ1aWQiOiI4OU4zR0NuN1M1Y090WkZNRTVBeVhNbmxURFdVcnEzRmd4YWlyWWhFIn0.zuCytArbphhJn9XT_y9cBdGqDCNo68tBrtOwPIsuKNyF340SaOuZa0xarZofygytdDpLtYr56QlPTKImi-n1ZWrHkRZkwrQi5jQ-j_n2hEAL0vUToLbDnXYfc5q2w7z7X0aoCmiK8-fV7Kx4CVTM7riBgpElf6F3wNAIcX6R1ijUh6ISCL0XYsdogf8WUNZipXY-O4R7YHXdOENuOp3G48hWhxuUh9PsUqE5yxDwLsOVzCTqg9S5gxPQzF2eCN9J0I2XiIlLKvLQPIZ2Y_K7iYvVwjpNdgb4xhm9wuKoIVinYkF_6CwIzAawBWIDJAbix1IslkUPQMGbupTDtOgTiQ"
|
||||||
|
|
||||||
|
# This is the string the user-facing client (e.g. Roundcube) should send via IMAP to Dovecot.
|
||||||
|
# We include the user and the above token separated by '\1' chars as per the XOAUTH2 spec.
|
||||||
|
xoauth2 = base64.b64encode(f"user=user1@localhost.localdomain\1auth=Bearer {token}\1\1".encode("utf-8"))
|
||||||
|
# If changing the user above, use the new output from the below line with the contents of the AUTHENTICATE command in test/test-files/auth/imap-oauth2-auth.txt
|
||||||
|
print("XOAUTH2 string: " + str(xoauth2))
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPRequestHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
auth = self.headers.get("Authorization")
|
||||||
|
if auth is None:
|
||||||
|
self.send_response(401)
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
if len(auth.split()) != 2:
|
||||||
|
self.send_response(401)
|
||||||
|
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')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(json.dumps({
|
||||||
|
"email": "user1@localhost.localdomain",
|
||||||
|
"email_verified": True,
|
||||||
|
"sub": "82c1c334dcc6e311ae4aaebfe946c5e858f055aff1ce5a37aa7cc91aab17e35c"
|
||||||
|
}).encode("utf-8"))
|
||||||
|
else:
|
||||||
|
self.send_response(401)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
server = HTTPServer(('', 80), HTTPRequestHandler)
|
||||||
|
print("Starting server", flush=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print()
|
||||||
|
print("Received keyboard interrupt")
|
||||||
|
finally:
|
||||||
|
print("Exiting")
|
4
test/files/auth/imap-oauth2-auth.txt
Normal file
4
test/files/auth/imap-oauth2-auth.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
a0 NOOP See test/config/oauth2/provider.py to generate the below XOAUTH2 string
|
||||||
|
a1 AUTHENTICATE XOAUTH2 dXNlcj11c2VyMUBsb2NhbGhvc3QubG9jYWxkb21haW4BYXV0aD1CZWFyZXIgZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnBjM01pT2lKb2RIUndPaTh2Y0hKdmRtbGtaWEl1WlhoaGJYQnNaUzUwWlhOME9qZ3dNREF2SWl3aWMzVmlJam9pT0RKak1XTXpNelJrWTJNMlpUTXhNV0ZsTkdGaFpXSm1aVGswTm1NMVpUZzFPR1l3TlRWaFptWXhZMlUxWVRNM1lXRTNZMk01TVdGaFlqRTNaVE0xWXlJc0ltRjFaQ0k2SW0xaGFXeHpaWEoyWlhJaUxDSjFhV1FpT2lJNE9VNHpSME51TjFNMVkwOTBXa1pOUlRWQmVWaE5ibXhVUkZkVmNuRXpSbWQ0WVdseVdXaEZJbjAuenVDeXRBcmJwaGhKbjlYVF95OWNCZEdxRENObzY4dEJydE93UElzdUtOeUYzNDBTYU91WmEweGFyWm9meWd5dGREcEx0WXI1NlFsUFRLSW1pLW4xWldySGtSWmt3clFpNWpRLWpfbjJoRUFMMHZVVG9MYkRuWFlmYzVxMnc3ejdYMGFvQ21pSzgtZlY3S3g0Q1ZUTTdyaUJncEVsZjZGM3dOQUljWDZSMWlqVWg2SVNDTDBYWXNkb2dmOFdVTlppcFhZLU80UjdZSFhkT0VOdU9wM0c0OGhXaHh1VWg5UHNVcUU1eXhEd0xzT1Z6Q1RxZzlTNWd4UFF6RjJlQ045SjBJMlhpSWxMS3ZMUVBJWjJZX0s3aVl2VndqcE5kZ2I0eGhtOXd1S29JVmluWWtGXzZDd0l6QWF3QldJREpBYml4MUlzbGtVUFFNR2J1cFREdE9nVGlRAQE=
|
||||||
|
a2 EXAMINE INBOX
|
||||||
|
a3 LOGOUT
|
66
test/tests/serial/mail_with_oauth2.bats
Normal file
66
test/tests/serial/mail_with_oauth2.bats
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
load "${REPOSITORY_ROOT}/test/helper/setup"
|
||||||
|
load "${REPOSITORY_ROOT}/test/helper/common"
|
||||||
|
|
||||||
|
BATS_TEST_NAME_PREFIX='[OAuth2] '
|
||||||
|
CONTAINER1_NAME='dms-test_oauth2'
|
||||||
|
CONTAINER2_NAME='dms-test_oauth2_provider'
|
||||||
|
|
||||||
|
function setup_file() {
|
||||||
|
export DMS_TEST_NETWORK='test-network-oauth2'
|
||||||
|
export DMS_DOMAIN='example.test'
|
||||||
|
export FQDN_MAIL="mail.${DMS_DOMAIN}"
|
||||||
|
export FQDN_OAUTH2="oauth2.${DMS_DOMAIN}"
|
||||||
|
|
||||||
|
# Link the test containers to separate network:
|
||||||
|
# NOTE: If the network already exists, test will fail to start.
|
||||||
|
docker network create "${DMS_TEST_NETWORK}"
|
||||||
|
|
||||||
|
# Setup local oauth2 provider service:
|
||||||
|
docker run --rm -d --name "${CONTAINER2_NAME}" \
|
||||||
|
--hostname "${FQDN_OAUTH2}" \
|
||||||
|
--network "${DMS_TEST_NETWORK}" \
|
||||||
|
--volume "${REPOSITORY_ROOT}/test/config/oauth2/:/app/" \
|
||||||
|
docker.io/library/python:latest \
|
||||||
|
python /app/provider.py
|
||||||
|
|
||||||
|
_run_until_success_or_timeout 20 sh -c "docker logs ${CONTAINER2_NAME} 2>&1 | grep 'Starting server'"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup DMS container
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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/userinfo/
|
||||||
|
)
|
||||||
|
|
||||||
|
export CONTAINER_NAME=${CONTAINER1_NAME}
|
||||||
|
local CUSTOM_SETUP_ARGUMENTS=(
|
||||||
|
"${ENV_OAUTH2_CONFIG[@]}"
|
||||||
|
|
||||||
|
--hostname "${FQDN_MAIL}"
|
||||||
|
--network "${DMS_TEST_NETWORK}"
|
||||||
|
)
|
||||||
|
|
||||||
|
_init_with_defaults
|
||||||
|
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||||
|
_wait_for_tcp_port_in_container 143
|
||||||
|
|
||||||
|
# Set default implicit container fallback for helpers:
|
||||||
|
export CONTAINER_NAME=${CONTAINER1_NAME}
|
||||||
|
}
|
||||||
|
|
||||||
|
function teardown_file() {
|
||||||
|
docker rm -f "${CONTAINER1_NAME}" "${CONTAINER2_NAME}"
|
||||||
|
docker network rm "${DMS_TEST_NETWORK}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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'
|
||||||
|
|
||||||
|
_nc_wrapper 'auth/imap-oauth2-auth.txt' '-w 1 0.0.0.0 143'
|
||||||
|
assert_output --partial 'Examine completed'
|
||||||
|
}
|
Loading…
Reference in a new issue