88 lines
3.1 KiB
Python
88 lines
3.1 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.test import override_settings
|
|
|
|
from apps.core.auth_backends import EmailOrUsernameModelBackend
|
|
from apps.core.entra import (
|
|
EntraConfigError,
|
|
domain_allowed,
|
|
entra_enabled,
|
|
extract_identity,
|
|
load_config,
|
|
)
|
|
|
|
|
|
def test_auth_backend_rejects_missing_and_unknown_credentials(db):
|
|
backend = EmailOrUsernameModelBackend()
|
|
assert backend.authenticate(None, username=None, password=None) is None
|
|
assert backend.authenticate(None, username="unknown@example.invalid", password="secret") is None
|
|
|
|
|
|
def test_auth_backend_rejects_inactive_and_wrong_password(db):
|
|
user = get_user_model().objects.create_user(
|
|
username="inactive", email="inactive@example.invalid", password="correct", is_active=False
|
|
)
|
|
backend = EmailOrUsernameModelBackend()
|
|
|
|
assert backend.authenticate(None, username=user.email, password="wrong") is None
|
|
assert backend.authenticate(None, username=user.email, password="correct") is None
|
|
|
|
|
|
def test_auth_backend_handles_duplicate_email_without_ambiguous_login(db):
|
|
user_model = get_user_model()
|
|
first = user_model.objects.create_user(
|
|
username="first", email="shared@example.invalid", password="correct"
|
|
)
|
|
user_model.objects.create_user(
|
|
username="second", email="shared@example.invalid", password="correct"
|
|
)
|
|
backend = EmailOrUsernameModelBackend()
|
|
|
|
assert backend.authenticate(None, username="shared@example.invalid", password="correct") is None
|
|
assert backend.authenticate(None, username="first", password="correct") == first
|
|
|
|
|
|
@override_settings(ENTRA_ID_ENABLED=True)
|
|
def test_entra_enabled_reflects_configuration():
|
|
assert entra_enabled() is True
|
|
|
|
|
|
@override_settings(
|
|
ENTRA_ID_ENABLED=True, ENTRA_CLIENT_ID="", ENTRA_CLIENT_SECRET="", ENTRA_TENANT_ID=""
|
|
)
|
|
def test_entra_config_fails_closed_when_credentials_are_incomplete():
|
|
try:
|
|
load_config()
|
|
except EntraConfigError as exc:
|
|
assert "niet allemaal ingesteld" in str(exc)
|
|
else: # pragma: no cover - defensive assertion
|
|
raise AssertionError("Onvolledige Entra-configuratie werd geaccepteerd")
|
|
|
|
|
|
@override_settings(
|
|
ENTRA_CLIENT_ID="client",
|
|
ENTRA_CLIENT_SECRET="secret",
|
|
ENTRA_TENANT_ID="tenant",
|
|
ENTRA_SCOPES=["User.Read"],
|
|
ENTRA_ALLOWED_DOMAINS=["@Example.COM"],
|
|
ENTRA_REDIRECT_URI="https://example.invalid/callback",
|
|
)
|
|
def test_entra_config_normalizes_domains_and_identity_claims():
|
|
config = load_config()
|
|
assert config.authority.endswith("/tenant")
|
|
assert config.allowed_domains == ("example.com",)
|
|
assert domain_allowed(config, "person@example.com") is True
|
|
assert domain_allowed(config, "person@other.invalid") is False
|
|
assert extract_identity(
|
|
{"id_token_claims": {"preferred_username": " person@example.com ", "name": " Person "}}
|
|
) == ("person@example.com", "Person")
|
|
|
|
|
|
@override_settings(
|
|
ENTRA_CLIENT_ID="client",
|
|
ENTRA_CLIENT_SECRET="secret",
|
|
ENTRA_TENANT_ID="tenant",
|
|
ENTRA_ALLOWED_DOMAINS=[],
|
|
)
|
|
def test_entra_allows_any_domain_only_when_allowlist_is_empty():
|
|
assert domain_allowed(load_config(), "person@example.invalid") is True
|