Files
VacatureRadar/tests/unit/test_mailbox_credentials.py
T
2026-07-22 05:12:07 +02:00

111 lines
4.2 KiB
Python

import pytest
from cryptography.fernet import Fernet
from django.core.exceptions import ValidationError
from django.test import override_settings
from apps.sources.models import MailboxConnection
from apps.sources.services.imap_import import poll_imap_mailbox
from apps.sources.services.mailbox_connections import (
MailboxCredentialError,
decrypt_mailbox_password,
encrypt_mailbox_password,
rotate_mailbox_credentials,
)
from apps.sources.services.url_security import UnsafeUrlError
def test_mailbox_password_is_encrypted_and_supports_key_rotation():
old_key = Fernet.generate_key().decode("ascii")
new_key = Fernet.generate_key().decode("ascii")
with override_settings(MAILBOX_CREDENTIAL_KEYS=[old_key]):
ciphertext = encrypt_mailbox_password("app-password-value")
connection = MailboxConnection(encrypted_password=ciphertext)
assert "app-password-value" not in ciphertext
with override_settings(MAILBOX_CREDENTIAL_KEYS=[new_key, old_key]):
assert decrypt_mailbox_password(connection) == "app-password-value"
rotated = encrypt_mailbox_password("replacement-value")
assert Fernet(new_key.encode("ascii")).decrypt(rotated.encode("ascii")) == b"replacement-value"
def test_mailbox_password_fails_closed_without_valid_key():
with (
override_settings(MAILBOX_CREDENTIAL_KEYS=[]),
pytest.raises(MailboxCredentialError, match="niet geconfigureerd"),
):
encrypt_mailbox_password("never-stored")
with (
override_settings(MAILBOX_CREDENTIAL_KEYS=["invalid"]),
pytest.raises(MailboxCredentialError, match="ongeldige sleutel"),
):
encrypt_mailbox_password("never-stored")
@pytest.mark.parametrize("host", ["", "https://imap.example.org", "imap.example.org/path", "a b"])
def test_custom_mailbox_host_rejects_non_hostname_values(host):
connection = MailboxConnection(
platform=MailboxConnection.Platform.VDAB,
provider=MailboxConnection.Provider.CUSTOM,
custom_host=host,
port=993,
username="mailbox@example.invalid",
encrypted_password="ciphertext",
)
with pytest.raises(ValidationError):
connection.clean()
@pytest.mark.parametrize("port", [0, 65536])
def test_mailbox_rejects_invalid_port(port):
connection = MailboxConnection(
platform=MailboxConnection.Platform.VDAB,
provider=MailboxConnection.Provider.GMAIL,
port=port,
username="mailbox@example.invalid",
encrypted_password="ciphertext",
)
with pytest.raises(ValidationError):
connection.clean()
@pytest.mark.django_db
def test_rotation_reencrypts_existing_credentials_with_primary_key(user):
old_key = Fernet.generate_key().decode("ascii")
new_key = Fernet.generate_key().decode("ascii")
with override_settings(MAILBOX_CREDENTIAL_KEYS=[old_key]):
ciphertext = encrypt_mailbox_password("rotate-me")
connection = MailboxConnection.objects.create(
user=user,
platform=MailboxConnection.Platform.VDAB,
provider=MailboxConnection.Provider.GMAIL,
username="rotate@example.invalid",
encrypted_password=ciphertext,
)
with override_settings(MAILBOX_CREDENTIAL_KEYS=[new_key, old_key]):
assert rotate_mailbox_credentials() == 1
connection.refresh_from_db()
with override_settings(MAILBOX_CREDENTIAL_KEYS=[new_key]):
assert decrypt_mailbox_password(connection) == "rotate-me"
@pytest.mark.django_db
def test_private_imap_host_is_blocked_before_connection(user):
key = Fernet.generate_key().decode("ascii")
with override_settings(MAILBOX_CREDENTIAL_KEYS=[key]):
connection = MailboxConnection.objects.create(
user=user,
platform=MailboxConnection.Platform.VDAB,
provider=MailboxConnection.Provider.CUSTOM,
custom_host="127.0.0.1",
username="private@example.invalid",
encrypted_password=encrypt_mailbox_password("never-sent"),
)
with pytest.raises(UnsafeUrlError, match="Niet-publiek"):
poll_imap_mailbox(
connection,
client_factory=lambda *args, **kwargs: pytest.fail(
"Private IMAP-host had niet geconnecteerd mogen worden"
),
)