Files
VacatureRadar/tests/unit/test_microsoft365_oauth.py
T
Jens 67be350283
deploy / deploy (push) Canceled after 0s
Harden live mail OAuth and immutable releases
2026-07-30 02:00:09 +02:00

109 lines
3.5 KiB
Python

import base64
import pytest
from django.test import override_settings
from apps.core.services.microsoft365 import (
Microsoft365OAuthError,
acquire_exchange_access_token,
xoauth2_b64,
)
from apps.notifications.backends import Microsoft365OAuthEmailBackend
@override_settings(
M365_TENANT_ID="tenant-id",
M365_CLIENT_ID="client-id",
M365_CLIENT_SECRET="client-secret",
M365_EXCHANGE_SCOPE="https://outlook.office365.com/.default",
)
def test_app_only_token_uses_tenant_authority_and_exchange_scope():
calls = {}
class Client:
def acquire_token_for_client(self, *, scopes):
calls["scopes"] = scopes
return {"access_token": "access-token"}
def factory(client_id, *, authority, client_credential):
calls.update(
client_id=client_id,
authority=authority,
client_credential=client_credential,
)
return Client()
assert acquire_exchange_access_token(client_factory=factory) == "access-token"
assert calls == {
"client_id": "client-id",
"authority": "https://login.microsoftonline.com/tenant-id",
"client_credential": "client-secret",
"scopes": ["https://outlook.office365.com/.default"],
}
@override_settings(M365_TENANT_ID="", M365_CLIENT_ID="", M365_CLIENT_SECRET="")
def test_missing_oauth_configuration_fails_without_secret_material():
with pytest.raises(Microsoft365OAuthError, match="niet volledig") as error:
acquire_exchange_access_token()
assert "secret" not in str(error.value).lower()
def test_xoauth2_payload_is_encoded_exactly():
encoded = xoauth2_b64("mailbox@example.invalid", "token-value")
assert base64.b64decode(encoded) == (
b"user=mailbox@example.invalid\x01auth=Bearer token-value\x01\x01"
)
@override_settings(
M365_MAILBOX_USER="vacatureradar@example.invalid",
EMAIL_HOST="smtp.office365.com",
EMAIL_PORT=587,
DEFAULT_FROM_EMAIL="VacatureRadar <vacatureradar@example.invalid>",
M365_SMTP_TIMEOUT_SECONDS=10,
)
def test_oauth_smtp_backend_authenticates_and_sends(monkeypatch):
calls = []
class SMTP:
def __init__(self, host, port, *, timeout):
calls.append(("connect", host, port, timeout))
def __enter__(self):
return self
def __exit__(self, *args):
return None
def ehlo(self):
calls.append(("ehlo",))
def starttls(self, *, context):
calls.append(("starttls", bool(context)))
def docmd(self, command, argument):
calls.append((command, argument))
return 235, b"ok"
def sendmail(self, sender, recipients, message):
calls.append(("sendmail", sender, recipients, message))
monkeypatch.setattr("apps.notifications.backends.smtplib.SMTP", SMTP)
monkeypatch.setattr(
"apps.notifications.backends.acquire_exchange_access_token",
lambda: "token-value",
)
from django.core.mail import EmailMessage as DjangoEmailMessage
django_message = DjangoEmailMessage(
subject="Test",
body="test",
from_email="vacatureradar@example.invalid",
to=["recipient@example.invalid"],
)
assert Microsoft365OAuthEmailBackend().send_messages([django_message]) == 1
assert calls[0] == ("connect", "smtp.office365.com", 587, 10)
assert any(call[0] == "AUTH" and call[1].startswith("XOAUTH2 ") for call in calls)
assert any(call[0] == "sendmail" for call in calls)