mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
feat(UI): fix migration, errors happening in local deploy and swarm integraton issues, tor merged and implement stalwart with tor
This commit is contained in:
18 files changed
+421
-37
No files matched your search
@@ -309,6 +309,68 @@ class TestEmailLookup(unittest.TestCase):
|
||||
self.assertTrue(result["auth"])
|
||||
self.assertFalse(result["start_tls"])
|
||||
|
||||
def test_a_provider_without_plaintext_submission_falls_back_to_its_mx(
|
||||
self,
|
||||
) -> None:
|
||||
"""Stalwart's default config binds the implicit-TLS client ports and the
|
||||
MX, never 587, so the onion path (which drops TLS) has no submission
|
||||
listener to reach. The port follows what the provider declares, and AUTH
|
||||
drops with it: an MX offers none, and announcing it aborts msmtp with
|
||||
EX_UNAVAILABLE before a message is ever sent."""
|
||||
_write_role_config(
|
||||
self._tmp,
|
||||
"web-app-mailprov",
|
||||
{"mailprov": {"ports": {"public": {"smtp": 25, "smtps": 465}}}},
|
||||
)
|
||||
variables = {
|
||||
"MAIL_PROVIDER": "web-app-mailprov",
|
||||
"group_names": ["web-app-mailprov"],
|
||||
"groups": {"web-app-mailprov": ["host1"]},
|
||||
"SYSTEM_EMAIL_HOST": "mail.x.onion",
|
||||
"TLS_ENABLED": True,
|
||||
"DOMAIN_PRIMARY": "x.onion",
|
||||
"inventory_hostname": "host1",
|
||||
}
|
||||
result = self.lookup.run(
|
||||
[], variables=variables, roles_dir=str(self._tmp / "roles")
|
||||
)[0]
|
||||
self.assertFalse(result["tls"])
|
||||
self.assertEqual(result["port"], 25)
|
||||
self.assertFalse(result["auth"])
|
||||
self.assertEqual(result["auth_mechanism"], "off")
|
||||
|
||||
def test_a_provider_declaring_submission_keeps_the_authenticated_path(
|
||||
self,
|
||||
) -> None:
|
||||
"""Mailu binds 587, so the same onion target stays on plaintext
|
||||
submission with AUTH PLAIN. The MX fallback above must not reach a
|
||||
provider that declares a submission listener."""
|
||||
_write_role_config(
|
||||
self._tmp,
|
||||
"web-app-mailprov",
|
||||
{
|
||||
"mailprov": {
|
||||
"ports": {"public": {"smtp": 25, "smtps": 465, "submission": 587}}
|
||||
}
|
||||
},
|
||||
)
|
||||
variables = {
|
||||
"MAIL_PROVIDER": "web-app-mailprov",
|
||||
"group_names": ["web-app-mailprov"],
|
||||
"groups": {"web-app-mailprov": ["host1"]},
|
||||
"SYSTEM_EMAIL_HOST": "mail.x.onion",
|
||||
"TLS_ENABLED": True,
|
||||
"DOMAIN_PRIMARY": "x.onion",
|
||||
"inventory_hostname": "host1",
|
||||
}
|
||||
result = self.lookup.run(
|
||||
[], variables=variables, roles_dir=str(self._tmp / "roles")
|
||||
)[0]
|
||||
self.assertFalse(result["tls"])
|
||||
self.assertEqual(result["port"], 587)
|
||||
self.assertTrue(result["auth"])
|
||||
self.assertEqual(result["auth_mechanism"], "plain")
|
||||
|
||||
def test_sso_relay_active_with_untemplated_enabled_gate(self) -> None:
|
||||
# The role default gates sso.enabled on group_names (raw Jinja here);
|
||||
# the guard must not treat the untemplated string as false.
|
||||
|
||||
@@ -37,6 +37,21 @@ class _DummyTemplar:
|
||||
return value
|
||||
|
||||
|
||||
class _RenderingTemplar:
|
||||
"""A templar that actually resolves expressions, like the real one.
|
||||
|
||||
``_DummyTemplar`` returns its input unchanged, so it cannot expose a value
|
||||
that only misbehaves while still an unrendered template.
|
||||
"""
|
||||
|
||||
def __init__(self, available_variables=None, rendered=None):
|
||||
self.available_variables = available_variables or {}
|
||||
self._rendered = rendered or {}
|
||||
|
||||
def template(self, value):
|
||||
return self._rendered.get(value, value)
|
||||
|
||||
|
||||
def _email(external=True, host=RELAY):
|
||||
return {"external": external, "host": host}
|
||||
|
||||
@@ -67,6 +82,18 @@ class TestSmtpHostLookup(unittest.TestCase):
|
||||
vars_ = {"DOCKER_IN_CONTAINER": True, "DEPLOYMENT_MODE": "compose"}
|
||||
self.assertEqual(self._resolve(vars_), "127.0.0.1")
|
||||
|
||||
def test_an_unrendered_group_var_still_reaches_the_rig_loopback(self):
|
||||
"""DOCKER_IN_CONTAINER is a group_vars expression, and a lookup receives it
|
||||
raw. Read unrendered it is neither true nor false, so the rig kept the
|
||||
configured relay instead of loopback — and on an onion node that relay is a
|
||||
.onion, which msmtp cannot route (EX_UNAVAILABLE, 'proxy failure')."""
|
||||
raw = "{{ (ansible_facts['env']['container'] | default('')) != '' }}"
|
||||
vars_ = {"DOCKER_IN_CONTAINER": raw, "DEPLOYMENT_MODE": "compose"}
|
||||
lm = self.LookupModule()
|
||||
lm._templar = _RenderingTemplar(vars_, {raw: True})
|
||||
lm._loader = None
|
||||
self.assertEqual(lm.run([_email()], variables=vars_)[0], "127.0.0.1")
|
||||
|
||||
def test_swarm_node_uses_loopback(self):
|
||||
vars_ = {
|
||||
"DOCKER_IN_CONTAINER": True,
|
||||
|
||||
Reference in new issue
Block a user