From f013ff434e260f8e581d7eb00f6ed084fe839830 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Fri, 13 Oct 2023 10:42:44 +0200 Subject: [PATCH] rename chatctl to doveauth --- pyproject.toml | 3 + src/chatmail/chatctl/doveauth.lua | 60 ++++++++ .../chatctl/{chatctl.py => doveauth.py} | 0 src/chatmail/chatctl/test.lua | 138 ------------------ src/chatmail/chatctl/test_doveauth.lua | 76 ++++++++++ .../{test_chatctl.py => test_doveauth.py} | 9 +- 6 files changed, 144 insertions(+), 142 deletions(-) create mode 100644 src/chatmail/chatctl/doveauth.lua rename src/chatmail/chatctl/{chatctl.py => doveauth.py} (100%) delete mode 100644 src/chatmail/chatctl/test.lua create mode 100644 src/chatmail/chatctl/test_doveauth.lua rename src/chatmail/chatctl/{test_chatctl.py => test_doveauth.py} (69%) diff --git a/pyproject.toml b/pyproject.toml index 506fd7d2..55cc6382 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,9 @@ dependencies = [ "pyinfra", ] +[tool.pytest.ini_options] +addopts = "-v -ra --strict-markers" + [tool.tox] legacy_tox_ini = """ [tox] diff --git a/src/chatmail/chatctl/doveauth.lua b/src/chatmail/chatctl/doveauth.lua new file mode 100644 index 00000000..c7fe10be --- /dev/null +++ b/src/chatmail/chatctl/doveauth.lua @@ -0,0 +1,60 @@ + +-- Escape shell argument by hex encoding it and wrapping in quotes. +function escape(data) + b16 = data:gsub(".", function(char) return string.format("%2X", char:byte()) end) + return ("'"..b16.."'") +end + +-- call out to python program to actually manage authentication for dovecot + +function chatctl_verify(user, password) + local handle = io.popen("python doveauth.py hexauth "..escape(user).." "..escape(password)) + local result = handle:read("*a") + handle:close() + return split_chatctl(result) +end + +function chatctl_lookup(user) + assert(user) + local handle = io.popen("python doveauth.py hexlookup "..escape(user)) + local result = handle:read("*a") + handle:close() + return split_chatctl(result) +end + +function get_extra_dovecot_output(res) + return {homedir=res.homedir, uid=res.uid, gid=res.gid} +end + + +function auth_passdb_verify(request, password) + local res = chatctl_verify(request.user, password) + if res.status == "ok" then + return dovecot.auth.PASSDB_RESULT_OK, get_extra_dovecot_output(res) + end + return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "" +end + +function auth_passdb_lookup(request) + local res = chatctl_lookup(request.user) + if res.status == "ok" then + return dovecot.auth.PASSDB_RESULT_OK, get_extra_dovecot_output(res) + end + return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "no such user" +end + +function auth_userdb_lookup(request) + local res = chatctl_lookup(request.user) + if res.status == "ok" then + return dovecot.auth.USERDB_RESULT_OK, get_extra_dovecot_output(res) + end + return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user" +end + +function split_chatctl(output) + local ret = {} + for key, value in output:gmatch "(%w+)%s*=%s*(%w+)" do + ret[key] = value + end + return ret +end diff --git a/src/chatmail/chatctl/chatctl.py b/src/chatmail/chatctl/doveauth.py similarity index 100% rename from src/chatmail/chatctl/chatctl.py rename to src/chatmail/chatctl/doveauth.py diff --git a/src/chatmail/chatctl/test.lua b/src/chatmail/chatctl/test.lua deleted file mode 100644 index c36c2774..00000000 --- a/src/chatmail/chatctl/test.lua +++ /dev/null @@ -1,138 +0,0 @@ - --- To run this test: run "lua test.lua" while in the same directory as chatctl.py - -if dovecot == nil then - dovecot = { - auth = { - PASSDB_RESULT_OK="PASSWORD-OK", - PASSDB_RESULT_PASSWORD_MISMATCH="PASSWORD-MISMATCH", - USERDB_RESULT_OK="USERDB-OK", - USERDB_RESULT_USER_UNKNOWN="USERDB-UNKNOWN" - } - } -end - --- Escape shell argument by hex encoding it and wrapping in quotes. -function escape(data) - b16 = data:gsub(".", function(char) return string.format("%2X", char:byte()) end) - return ("'"..b16.."'") -end - --- call out to python program to actually manage authentication for dovecot - -function chatctl_verify(user, password) - local handle = io.popen("python chatctl.py hexauth "..escape(user).." "..escape(password)) - local result = handle:read("*a") - handle:close() - return split_chatctl(result) -end - -function chatctl_lookup(user) - assert(user) - local handle = io.popen("python chatctl.py hexlookup "..escape(user)) - local result = handle:read("*a") - handle:close() - return split_chatctl(result) -end - -function get_extra_dovecot_output(res) - return {homedir=res.homedir, uid=res.uid, gid=res.gid} -end - - -function auth_passdb_verify(request, password) - local res = chatctl_verify(request.user, password) - if res.status == "ok" then - return dovecot.auth.PASSDB_RESULT_OK, get_extra_dovecot_output(res) - end - return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "" -end - -function auth_passdb_lookup(request) - local res = chatctl_lookup(request.user) - if res.status == "ok" then - return dovecot.auth.PASSDB_RESULT_OK, get_extra_dovecot_output(res) - end - return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "no such user" -end - -function auth_userdb_lookup(request) - local res = chatctl_lookup(request.user) - if res.status == "ok" then - return dovecot.auth.USERDB_RESULT_OK, get_extra_dovecot_output(res) - end - return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user" -end - -function split_chatctl(output) - local ret = {} - for key, value in output:gmatch "(%w+)%s*=%s*(%w+)" do - ret[key] = value - end - return ret -end - - - - --- Tests for testing the lua<->python interaction - -function test_passdb_verify_ok(user, password) - local res, extra = auth_passdb_verify({user=user}, password) - assert(res==dovecot.auth.PASSDB_RESULT_OK) - assert(extra.uid == "vmail") - assert(extra.gid == "vmail") - -- assert(extra.homedir == "/home/vmail/link2xt") - print("OK test_passdb_verify_ok "..user.." "..password) -end - -function test_passdb_verify_mismatch(user, password) - local res = auth_passdb_verify({user=user}, password) - assert(res == dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH) - print("OK test_passdb_verify_mismatch "..user.." "..password) -end - -function test_userdb_lookup_ok(user) - local res, extra = auth_userdb_lookup({user=user}) - assert(extra.uid == "vmail") - assert(extra.gid == "vmail") - assert(res == dovecot.auth.USERDB_RESULT_OK) - print("OK test_userdb_lookup_ok "..user) -end - -function test_userdb_lookup_mismatch(user) - local res, extra = auth_userdb_lookup({user=user}) - assert(res == dovecot.auth.USERDB_RESULT_USER_UNKNOWN) - print("OK test_userdb_lookup_mismatch "..user) -end - -function test_passdb_lookup_ok(user) - local res, extra = auth_passdb_lookup({user=user}) - assert(extra.uid == "vmail") - assert(extra.gid == "vmail") - assert(res == dovecot.auth.PASSDB_RESULT_OK) - print("OK test_passdb_lookup_ok "..user) -end - -function test_passdb_lookup_mismatch(user) - local res, extra = auth_passdb_lookup({user=user}) - assert(res == dovecot.auth.PASSDB_RESULT_USER_UNKNOWN) - print("OK test_passdb_lookup_mismatch "..user) -end - -function test_split_chatctl() - local res = split_chatctl("a=3 b=4\nc=5") - assert(res["a"] == "3") - assert(res["b"] == "4") - assert(res["c"] == "5") - print("OK test_split_chatctl") -end - -test_split_chatctl() -test_passdb_verify_ok("link2xt@instant2.testrun.org", "Ahyei6ie") -test_passdb_verify_mismatch("link2xt@instant2.testrun.org", "Aqwlek") -test_userdb_lookup_ok("link2xt@instant2.testrun.org") -test_userdb_lookup_mismatch("wlekqjlew@xyz.org") -test_passdb_lookup_ok("link2xt@instant2.testrun.org") -test_passdb_lookup_mismatch("llqkwjelqwe@xyz.org") - diff --git a/src/chatmail/chatctl/test_doveauth.lua b/src/chatmail/chatctl/test_doveauth.lua new file mode 100644 index 00000000..a0f7090f --- /dev/null +++ b/src/chatmail/chatctl/test_doveauth.lua @@ -0,0 +1,76 @@ + +require "doveauth" + +-- simulate dovecot defined result codes + +dovecot = { + auth = { + PASSDB_RESULT_OK="PASSWORD-OK", + PASSDB_RESULT_PASSWORD_MISMATCH="PASSWORD-MISMATCH", + USERDB_RESULT_OK="USERDB-OK", + USERDB_RESULT_USER_UNKNOWN="USERDB-UNKNOWN" + } +} + + +-- Tests for testing the lua<->python interaction + +function test_passdb_verify_ok(user, password) + local res, extra = auth_passdb_verify({user=user}, password) + assert(res==dovecot.auth.PASSDB_RESULT_OK) + assert(extra.uid == "vmail") + assert(extra.gid == "vmail") + -- assert(extra.homedir == "/home/vmail/link2xt") + print("OK test_passdb_verify_ok "..user.." "..password) +end + +function test_passdb_verify_mismatch(user, password) + local res = auth_passdb_verify({user=user}, password) + assert(res == dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH) + print("OK test_passdb_verify_mismatch "..user.." "..password) +end + +function test_userdb_lookup_ok(user) + local res, extra = auth_userdb_lookup({user=user}) + assert(extra.uid == "vmail") + assert(extra.gid == "vmail") + assert(res == dovecot.auth.USERDB_RESULT_OK) + print("OK test_userdb_lookup_ok "..user) +end + +function test_userdb_lookup_mismatch(user) + local res, extra = auth_userdb_lookup({user=user}) + assert(res == dovecot.auth.USERDB_RESULT_USER_UNKNOWN) + print("OK test_userdb_lookup_mismatch "..user) +end + +function test_passdb_lookup_ok(user) + local res, extra = auth_passdb_lookup({user=user}) + assert(extra.uid == "vmail") + assert(extra.gid == "vmail") + assert(res == dovecot.auth.PASSDB_RESULT_OK) + print("OK test_passdb_lookup_ok "..user) +end + +function test_passdb_lookup_mismatch(user) + local res, extra = auth_passdb_lookup({user=user}) + assert(res == dovecot.auth.PASSDB_RESULT_USER_UNKNOWN) + print("OK test_passdb_lookup_mismatch "..user) +end + +function test_split_chatctl() + local res = split_chatctl("a=3 b=4\nc=5") + assert(res["a"] == "3") + assert(res["b"] == "4") + assert(res["c"] == "5") + print("OK test_split_chatctl") +end + +test_split_chatctl() +test_passdb_verify_ok("link2xt@instant2.testrun.org", "Ahyei6ie") +test_passdb_verify_mismatch("link2xt@instant2.testrun.org", "Aqwlek") +test_userdb_lookup_ok("link2xt@instant2.testrun.org") +test_userdb_lookup_mismatch("wlekqjlew@xyz.org") +test_passdb_lookup_ok("link2xt@instant2.testrun.org") +test_passdb_lookup_mismatch("llqkwjelqwe@xyz.org") + diff --git a/src/chatmail/chatctl/test_chatctl.py b/src/chatmail/chatctl/test_doveauth.py similarity index 69% rename from src/chatmail/chatctl/test_chatctl.py rename to src/chatmail/chatctl/test_doveauth.py index ecaba431..f9cfdacd 100644 --- a/src/chatmail/chatctl/test_chatctl.py +++ b/src/chatmail/chatctl/test_doveauth.py @@ -1,6 +1,7 @@ +import subprocess import pytest -from chatctl import get_user_data, verify_user +from doveauth import get_user_data, verify_user def test_basic(): @@ -17,6 +18,6 @@ def test_verify_or_create(): def test_lua_integration(request): - p = request.fspath.dirpath("test.lua") - assert p.exists() - assert 0 + p = request.fspath.dirpath("test_doveauth.lua") + proc = subprocess.run(["lua", str(p)]) + assert proc.returncode == 0