mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-13 18:46:17 +05:00
Some checks failed
CI / Linters (push) Waiting to run
CI / Complete test suite (push) Waiting to run
CI / Sharded and plugin tests (push) Waiting to run
CI / Documentation and root tests (push) Waiting to run
CI / CodeQL (push) Waiting to run
CI / Tested Python artifacts (push) Waiting to run
CI / Tested Docker images (push) Waiting to run
CI / All required CI lanes (push) Blocked by required conditions
Deploy Publicsite to GitHub Pages / deploy (push) Has been cancelled
211 lines
8.0 KiB
Python
211 lines
8.0 KiB
Python
"""
|
|
LDAP authentication tests for ArchiveBox.
|
|
|
|
Tests LDAP configuration, validation, and integration with Django.
|
|
Per CLAUDE.md: NO MOCKS, NO SKIPS - all tests use real code paths.
|
|
"""
|
|
|
|
from importlib.util import find_spec
|
|
|
|
from archivebox.tests.conftest import run_archivebox_cmd
|
|
|
|
|
|
class TestLDAPConfig:
|
|
"""Test LDAP configuration loading and validation."""
|
|
|
|
def test_ldap_config_defaults(self):
|
|
"""Test that LDAP config loads with correct defaults."""
|
|
from archivebox.config.common import get_config
|
|
|
|
# Check default values
|
|
config = get_config()
|
|
assert not config.LDAP_ENABLED
|
|
assert config.LDAP_SERVER_URI is None
|
|
assert config.LDAP_BIND_DN is None
|
|
assert config.LDAP_BIND_PASSWORD is None
|
|
assert config.LDAP_USER_BASE is None
|
|
assert config.LDAP_USER_FILTER == "(uid=%(user)s)"
|
|
assert config.LDAP_USERNAME_ATTR == "username"
|
|
assert config.LDAP_FIRSTNAME_ATTR == "givenName"
|
|
assert config.LDAP_LASTNAME_ATTR == "sn"
|
|
assert config.LDAP_EMAIL_ATTR == "mail"
|
|
assert not config.LDAP_CREATE_SUPERUSER
|
|
|
|
def test_ldap_config_validation_disabled(self):
|
|
"""Test that validation passes when LDAP is disabled."""
|
|
from archivebox.config.ldap import LDAPConfig
|
|
|
|
config = LDAPConfig(LDAP_ENABLED=False)
|
|
is_valid, error_msg = config.validate_ldap_config()
|
|
|
|
assert is_valid
|
|
assert error_msg == ""
|
|
|
|
def test_ldap_config_validation_missing_fields(self):
|
|
"""Test that validation fails when required fields are missing."""
|
|
from archivebox.config.ldap import LDAPConfig
|
|
|
|
# Enable LDAP but don't provide required fields
|
|
config = LDAPConfig(LDAP_ENABLED=True)
|
|
is_valid, error_msg = config.validate_ldap_config()
|
|
|
|
assert not is_valid
|
|
assert "LDAP_* config options must all be set" in error_msg
|
|
assert "LDAP_SERVER_URI" in error_msg
|
|
assert "LDAP_BIND_DN" in error_msg
|
|
assert "LDAP_BIND_PASSWORD" in error_msg
|
|
assert "LDAP_USER_BASE" in error_msg
|
|
|
|
def test_ldap_config_validation_complete(self):
|
|
"""Test that validation passes when all required fields are provided."""
|
|
from archivebox.config.ldap import LDAPConfig
|
|
|
|
config = LDAPConfig(
|
|
LDAP_ENABLED=True,
|
|
LDAP_SERVER_URI="ldap://ldap-test.localhost:389",
|
|
LDAP_BIND_DN="cn=admin,dc=example,dc=com",
|
|
LDAP_BIND_PASSWORD="password",
|
|
LDAP_USER_BASE="ou=users,dc=example,dc=com",
|
|
)
|
|
is_valid, error_msg = config.validate_ldap_config()
|
|
|
|
assert is_valid
|
|
assert error_msg == ""
|
|
|
|
def test_ldap_config_in_get_config(self):
|
|
"""Test that LDAP_CONFIG is included in the typed config sections."""
|
|
from archivebox.config.common import get_all_configs
|
|
|
|
all_config = get_all_configs()
|
|
assert "LDAP_CONFIG" in all_config
|
|
assert all_config["LDAP_CONFIG"].__class__.__name__ == "LDAPConfig"
|
|
|
|
|
|
class TestLDAPIntegration:
|
|
"""Test LDAP integration with Django settings."""
|
|
|
|
def test_django_settings_without_ldap_enabled(self):
|
|
"""Test that Django settings work correctly when LDAP is disabled."""
|
|
# Import Django settings (LDAP_ENABLED should be False by default)
|
|
from django.conf import settings
|
|
|
|
# Should have default authentication backends
|
|
assert "django.contrib.auth.backends.RemoteUserBackend" in settings.AUTHENTICATION_BACKENDS
|
|
assert "django.contrib.auth.backends.ModelBackend" in settings.AUTHENTICATION_BACKENDS
|
|
|
|
# LDAP backend should not be present when disabled
|
|
ldap_backends = [b for b in settings.AUTHENTICATION_BACKENDS if "ldap" in b.lower()]
|
|
assert len(ldap_backends) == 0, "LDAP backend should not be present when LDAP_ENABLED=False"
|
|
|
|
def test_django_settings_with_ldap_enabled(self, initialized_archive):
|
|
"""Test the real enabled LDAP settings path with installed libraries."""
|
|
assert find_spec("django_auth_ldap") is not None
|
|
assert find_spec("ldap") is not None
|
|
|
|
result = run_archivebox_cmd(
|
|
[
|
|
"manage",
|
|
"shell",
|
|
"-c",
|
|
(
|
|
"from django.conf import settings; "
|
|
"print('LDAP_BACKENDS=' + ','.join(settings.AUTHENTICATION_BACKENDS)); "
|
|
"print('LDAP_SERVER_URI=' + settings.AUTH_LDAP_SERVER_URI)"
|
|
),
|
|
],
|
|
cwd=initialized_archive,
|
|
timeout=45,
|
|
env={
|
|
"LDAP_ENABLED": "True",
|
|
"LDAP_SERVER_URI": "ldap://ldap-test.localhost:389",
|
|
"LDAP_BIND_DN": "cn=admin,dc=example,dc=com",
|
|
"LDAP_BIND_PASSWORD": "password",
|
|
"LDAP_USER_BASE": "ou=users,dc=example,dc=com",
|
|
},
|
|
default_cli_env=True,
|
|
disable_extractors=True,
|
|
)
|
|
|
|
assert result.returncode == 0, result.stderr or result.stdout
|
|
assert "LDAP_BACKENDS=archivebox.ldap.auth.ArchiveBoxLDAPBackend," in result.stdout
|
|
assert "LDAP_SERVER_URI=ldap://ldap-test.localhost:389" in result.stdout
|
|
|
|
|
|
class TestLDAPAuthBackend:
|
|
"""Test custom LDAP authentication backend."""
|
|
|
|
def test_ldap_backend_class_exists(self):
|
|
"""Test that ArchiveBoxLDAPBackend class is defined."""
|
|
from archivebox.ldap.auth import ArchiveBoxLDAPBackend
|
|
|
|
assert ArchiveBoxLDAPBackend.authenticate_ldap_user is not None
|
|
|
|
def test_ldap_backend_inherits_correctly(self):
|
|
"""Test that ArchiveBoxLDAPBackend has correct inheritance."""
|
|
from archivebox.ldap.auth import ArchiveBoxLDAPBackend
|
|
|
|
# Should have authenticate_ldap_user method (from base or overridden)
|
|
assert callable(ArchiveBoxLDAPBackend.authenticate_ldap_user)
|
|
|
|
|
|
class TestArchiveBoxWithLDAP:
|
|
"""Test ArchiveBox commands with LDAP configuration."""
|
|
|
|
def test_archivebox_init_without_ldap(self, tmp_path):
|
|
"""Test that archivebox init works without LDAP enabled."""
|
|
_cmd_result = run_archivebox_cmd(
|
|
["init"],
|
|
cwd=tmp_path,
|
|
timeout=45,
|
|
env={"LDAP_ENABLED": "False"},
|
|
default_cli_env=True,
|
|
disable_extractors=True,
|
|
)
|
|
_, stderr, code = _cmd_result.stdout, _cmd_result.stderr, _cmd_result.returncode
|
|
|
|
# Should succeed
|
|
assert code == 0, f"archivebox init failed: {stderr}"
|
|
|
|
def test_archivebox_version_with_ldap_config(self, tmp_path):
|
|
"""Test that archivebox version works with LDAP config set."""
|
|
_cmd_result = run_archivebox_cmd(
|
|
["version"],
|
|
cwd=tmp_path,
|
|
timeout=10,
|
|
env={
|
|
"LDAP_ENABLED": "False",
|
|
"LDAP_SERVER_URI": "ldap://ldap-test.localhost:389",
|
|
},
|
|
default_cli_env=True,
|
|
disable_extractors=True,
|
|
)
|
|
_, stderr, code = _cmd_result.stdout, _cmd_result.stderr, _cmd_result.returncode
|
|
|
|
# Should succeed
|
|
assert code == 0, f"archivebox version failed: {stderr}"
|
|
|
|
|
|
class TestLDAPConfigValidationInArchiveBox:
|
|
"""Test LDAP config validation when running ArchiveBox commands."""
|
|
|
|
def test_archivebox_init_with_incomplete_ldap_config(self, tmp_path):
|
|
"""Test that archivebox init fails with helpful error when LDAP config is incomplete."""
|
|
_cmd_result = run_archivebox_cmd(
|
|
["init"],
|
|
cwd=tmp_path,
|
|
timeout=45,
|
|
env={
|
|
"LDAP_ENABLED": "True",
|
|
# Missing: LDAP_SERVER_URI, LDAP_BIND_DN, etc.
|
|
},
|
|
default_cli_env=True,
|
|
disable_extractors=True,
|
|
)
|
|
_, stderr, code = _cmd_result.stdout, _cmd_result.stderr, _cmd_result.returncode
|
|
|
|
# Should fail with validation error
|
|
assert code != 0, "Should fail with incomplete LDAP config"
|
|
|
|
# Check error message
|
|
assert "LDAP_* config options must all be set" in stderr, f"Expected validation error message in: {stderr}"
|