Add the dovecot stuff I was working on awhile ago
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/mail/files/dovecot-10-auth-lua.conf Wed Jul 07 01:43:48 2021 -0500
@@ -0,0 +1,10 @@
+ args = file=/etc/dovecot/auth-imf-hub.lua blocking=yes + args = file=/etc/dovecot/auth-imf-hub.lua blocking=yes --- a/roles/mail/tasks/dovecot.yaml Wed Jul 07 01:24:58 2021 -0500
+++ b/roles/mail/tasks/dovecot.yaml Wed Jul 07 01:43:48 2021 -0500
@@ -36,4 +36,21 @@
+- name: "check for packaged 10-auth.conf" + path: "/etc/dovecot/conf.d/10-auth.conf" + register: "packaged_10_auth_conf" +- name: "move 10-auth.conf out of the way" + command: "mv /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig" + when: "false and packaged_10_auth_conf.stat.exists" +- name: "add lua based auth configuration" + src: "dovecot-10-auth-lua.conf" + dest: "/etc/dovecot/conf.d/10-auth-lua.conf" --- a/roles/mail/tasks/software.yaml Wed Jul 07 01:24:58 2021 -0500
+++ b/roles/mail/tasks/software.yaml Wed Jul 07 01:43:48 2021 -0500
@@ -1,14 +1,15 @@
-- name: install software
+- name: "install dovecot" name: "{{ mail_packages }}"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/mail/templates/auth-imf-hub.lua.j2 Wed Jul 07 01:43:48 2021 -0500
@@ -0,0 +1,121 @@
+-- This is a templated file created by ansible and any changes made to it will +-- be over written during the next run. So do NOT edit this file, please go +-- through the ansible workflow to keep everyone happy. +local string = require("string") +local mime = require("mime") +local hub_url = "{{ mail_hub_url }}" +local hub_scopes = "{{ mail_hub_scopes }}" +local hub_client_id = "{{ mail_hub_client_id }}" +local hub_client_secret = "{{ mail_hub_client_secret }}" +local hub_domain_groups = { + "pidgin.im" = { "Pidgin Developer", "Pidgin Contributor", "Pidgin Email" }; + "imfreedom.org" = {"IMF Board"}; +-- The following code is borrowed from prosody's util.http. + local u = format("%%%02x", i); + url_codes[u:upper()] = c; +local function urlencode(s) + return s and (s:gsub("[^a-zA-Z0-9.~_-]", url_codes)); +local function _formencodepart(s) + return s and (urlencode(s):gsub("%%20", "+")); +local function formencode(form) + if form[1] then -- Array of ordered { name, value } + for _, field in ipairs(form) do + table.insert(result, _formencodepart(field.name).."=".._formencodepart(field.value)); + else -- Unordered map of name -> value + for name, value in pairs(form) do + table.insert(result, _formencodepart(name).."=".._formencodepart(value)); + return table.concat(result, "&"); +function http_request(url, headers, body) + local ltn12 = require("ltn12") + if string.sub(url, 1, string.len("https")) == "https" then + request = require("ssl.https").request + request = require("socket.http").request + sink = ltn12.sink.table(t), + if body and #body > 0 then + request["body"] = formencode(body) + content = table.concat(t) +-- end of prosody util.http +-- verify the users password +function auth_password_verify(request, password) + if request.domain == "" then + return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no domain specified" + if hub_domain_groups[request.domain] == nil then + return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "unknown domain" + request.log_info("testing password for " . request.user) + local token = mime.b64(string.format("%s:%s", hub_client_id, hub_client_secret)) + Authorization = string.format("Basic %s", token); + "grant_type" = "password"; + "username" = request.username; + local resp = http_request(hub_url.."/api/rest/oauth2/token", headers, body); +-- verify the user exists +function auth_userdb_lookup(request) +function script_deinit()