mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-04-06 07:47:53 +10:00
Implement native LDAP authentication support
- Create archivebox/config/ldap.py with LDAPConfig class - Create archivebox/ldap/ Django app with custom auth backend - Update core/settings.py to conditionally load LDAP when enabled - Add LDAP_CREATE_SUPERUSER support to auto-grant superuser privileges - Add comprehensive tests in test_auth_ldap.py (no mocks, no skips) - LDAP only activates if django-auth-ldap is installed and LDAP_ENABLED=True - Helpful error messages when LDAP libraries are missing or config is incomplete Fixes #1664 Co-authored-by: Nick Sweeting <pirate@users.noreply.github.com>
This commit is contained in:
@@ -92,6 +92,7 @@ def get_CONFIG():
|
||||
ARCHIVING_CONFIG,
|
||||
SEARCH_BACKEND_CONFIG,
|
||||
)
|
||||
from .ldap import LDAP_CONFIG
|
||||
return {
|
||||
'SHELL_CONFIG': SHELL_CONFIG,
|
||||
'STORAGE_CONFIG': STORAGE_CONFIG,
|
||||
@@ -99,4 +100,5 @@ def get_CONFIG():
|
||||
'SERVER_CONFIG': SERVER_CONFIG,
|
||||
'ARCHIVING_CONFIG': ARCHIVING_CONFIG,
|
||||
'SEARCHBACKEND_CONFIG': SEARCH_BACKEND_CONFIG,
|
||||
'LDAP_CONFIG': LDAP_CONFIG,
|
||||
}
|
||||
|
||||
56
archivebox/config/ldap.py
Normal file
56
archivebox/config/ldap.py
Normal file
@@ -0,0 +1,56 @@
|
||||
__package__ = "archivebox.config"
|
||||
|
||||
from typing import Optional
|
||||
from pydantic import Field
|
||||
|
||||
from archivebox.config.configset import BaseConfigSet
|
||||
|
||||
|
||||
class LDAPConfig(BaseConfigSet):
|
||||
"""
|
||||
LDAP authentication configuration.
|
||||
|
||||
Only loads and validates if django-auth-ldap is installed.
|
||||
These settings integrate with Django's LDAP authentication backend.
|
||||
"""
|
||||
toml_section_header: str = "LDAP_CONFIG"
|
||||
|
||||
LDAP_ENABLED: bool = Field(default=False)
|
||||
LDAP_SERVER_URI: Optional[str] = Field(default=None)
|
||||
LDAP_BIND_DN: Optional[str] = Field(default=None)
|
||||
LDAP_BIND_PASSWORD: Optional[str] = Field(default=None)
|
||||
LDAP_USER_BASE: Optional[str] = Field(default=None)
|
||||
LDAP_USER_FILTER: str = Field(default="(uid=%(user)s)")
|
||||
LDAP_USERNAME_ATTR: str = Field(default="username")
|
||||
LDAP_FIRSTNAME_ATTR: str = Field(default="givenName")
|
||||
LDAP_LASTNAME_ATTR: str = Field(default="sn")
|
||||
LDAP_EMAIL_ATTR: str = Field(default="mail")
|
||||
LDAP_CREATE_SUPERUSER: bool = Field(default=False)
|
||||
|
||||
def validate_ldap_config(self) -> tuple[bool, str]:
|
||||
"""
|
||||
Validate that all required LDAP settings are configured.
|
||||
|
||||
Returns:
|
||||
Tuple of (is_valid, error_message)
|
||||
"""
|
||||
if not self.LDAP_ENABLED:
|
||||
return True, ""
|
||||
|
||||
required_fields = [
|
||||
"LDAP_SERVER_URI",
|
||||
"LDAP_BIND_DN",
|
||||
"LDAP_BIND_PASSWORD",
|
||||
"LDAP_USER_BASE",
|
||||
]
|
||||
|
||||
missing = [field for field in required_fields if not getattr(self, field)]
|
||||
|
||||
if missing:
|
||||
return False, f"LDAP_* config options must all be set if LDAP_ENABLED=True\nMissing: {', '.join(missing)}"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
# Singleton instance
|
||||
LDAP_CONFIG = LDAPConfig()
|
||||
Reference in New Issue
Block a user