Add hierarchical mail servers and credentials

This commit is contained in:
2026-07-28 19:32:56 +02:00
parent 2813c671c0
commit 3735027b3d
15 changed files with 4105 additions and 246 deletions

View File

@@ -13,6 +13,7 @@ from govoplan_mail.backend.mail_profiles import (
_assert_campaign_inherits_profile_credentials,
_campaign_mail_profile_reference_id,
_apply_profile_transport_update,
campaign_mail_selection_from_json,
campaign_profile_transport_revisions,
create_mail_server_profile,
_merge_policy,
@@ -496,14 +497,26 @@ class MailProfileTransportHelperTests(unittest.TestCase):
class MailProfilePolicyHelperTests(unittest.TestCase):
def test_campaign_contract_accepts_only_mail_profile_reference(self):
def test_campaign_contract_accepts_only_mail_owned_references(self):
self.assertEqual(
_campaign_mail_profile_reference_id({"mail_profile_id": " profile-1 "}),
"profile-1",
)
for legacy in ("smtp", "imap", "credentials", "inherit_smtp_credentials"):
with self.subTest(legacy=legacy), self.assertRaisesRegex(MailProfileError, "select a Mail profile"):
with self.subTest(legacy=legacy), self.assertRaisesRegex(MailProfileError, "select Mail resources"):
_campaign_mail_profile_reference_id({"mail_profile_id": "profile-1", legacy: {}})
self.assertEqual(
campaign_mail_selection_from_json(
{
"server": {
"mail_profile_id": "profile-1",
"smtp_server_id": "smtp-1",
"smtp_credential_id": "credential-1",
}
}
)["smtp_credential_id"],
"credential-1",
)
def test_campaign_delivery_fails_when_policy_requires_local_credentials(self):
profile = SimpleNamespace(imap_config=None)
@@ -511,7 +524,7 @@ class MailProfilePolicyHelperTests(unittest.TestCase):
smtp_credentials=EffectiveCredentialPolicy(inherit=False),
)
with self.assertRaisesRegex(MailProfileError, "Store the credentials on a Mail profile"):
with self.assertRaisesRegex(MailProfileError, "explicit credential selection"):
_assert_campaign_inherits_profile_credentials(profile, policy)
def test_merge_policy_respects_locked_lower_level_limits(self):

View File

@@ -409,6 +409,7 @@ class ProfileActorAuthorizationTests(unittest.TestCase):
"govoplan_mail.backend.router._profile_response",
return_value=profile,
),
patch("govoplan_mail.backend.router.sync_default_profile_server"),
):
result = router.update_profile(
profile.id,
@@ -446,6 +447,7 @@ class ProfileActorAuthorizationTests(unittest.TestCase):
"govoplan_mail.backend.router._profile_response",
return_value=profile,
),
patch("govoplan_mail.backend.router.sync_default_profile_server"),
):
router.update_profile(
profile.id,

View File

@@ -166,6 +166,7 @@ class MailProfileDeletionRouteTests(unittest.TestCase):
with (
patch("govoplan_mail.backend.router._require_profile_write_scope"),
patch("govoplan_mail.backend.router.create_mail_server_profile", return_value=system_profile),
patch("govoplan_mail.backend.router.initialize_profile_hierarchy"),
patch("govoplan_mail.backend.router._record_mail_change") as create_change,
patch("govoplan_mail.backend.router._profile_response", return_value=system_profile),
):