d79652b494
- Introduced new authentication settings in config.py including `auth_enabled`, `admin_username`, `admin_password`, and `session_secret`. - Added validation for `session_secret` to ensure it meets security requirements when authentication is enabled. - Updated main.py to conditionally mount static files and log warnings if the directory is not found. - Removed unused email template files and added new authentication and notification setup documentation. - Implemented authentication configuration validation in validators.py and updated settings display. - Enhanced the user interface with a new login template and SVG assets for branding. - Added comprehensive guides for setting up authentication and notifications in the documentation.
244 lines
9.4 KiB
Python
244 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import socket
|
|
import logging
|
|
from app.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def validate_email_config():
|
|
"""Validates email configuration settings"""
|
|
issues = []
|
|
|
|
# Check for required email settings
|
|
if not getattr(settings, 'email_host', None):
|
|
issues.append("EMAIL_HOST is not configured")
|
|
if not getattr(settings, 'email_port', None):
|
|
issues.append("EMAIL_PORT is not configured")
|
|
|
|
# Test SMTP server connectivity if host is configured
|
|
if getattr(settings, 'email_host', None) and getattr(settings, 'email_port', None):
|
|
try:
|
|
# Attempt to resolve the hostname
|
|
socket.gethostbyname(settings.email_host)
|
|
except socket.gaierror:
|
|
issues.append(f"Cannot resolve email host: {settings.email_host}")
|
|
|
|
# Check for authentication settings
|
|
if not getattr(settings, 'email_username', None):
|
|
issues.append("EMAIL_USERNAME is not configured")
|
|
if not getattr(settings, 'email_password', None):
|
|
issues.append("EMAIL_PASSWORD is not configured")
|
|
|
|
return issues
|
|
|
|
def validate_auth_config():
|
|
"""Validates authentication configuration settings"""
|
|
issues = []
|
|
|
|
# If auth is enabled, check for required settings
|
|
if getattr(settings, 'auth_enabled', False):
|
|
# Check for session secret
|
|
if not getattr(settings, 'session_secret', None):
|
|
issues.append("SESSION_SECRET is not configured but AUTH_ENABLED is True")
|
|
elif len(getattr(settings, 'session_secret', '')) < 32:
|
|
issues.append("SESSION_SECRET must be at least 32 characters long")
|
|
|
|
# Check if using simple authentication or OIDC
|
|
using_simple_auth = bool(getattr(settings, 'admin_username', None) and
|
|
getattr(settings, 'admin_password', None))
|
|
|
|
using_oidc = bool(getattr(settings, 'authentik_client_id', None) and
|
|
getattr(settings, 'authentik_client_secret', None) and
|
|
getattr(settings, 'authentik_config_url', None))
|
|
|
|
if not using_simple_auth and not using_oidc:
|
|
issues.append("Neither simple authentication nor OIDC are properly configured")
|
|
|
|
# If using OIDC, check for provider name
|
|
if using_oidc and not getattr(settings, 'oauth_provider_name', None):
|
|
issues.append("OAUTH_PROVIDER_NAME is not configured but OIDC is enabled")
|
|
|
|
return issues
|
|
|
|
def validate_storage_configs():
|
|
"""Validates configuration for all storage providers"""
|
|
issues = {}
|
|
|
|
# Validate Dropbox config
|
|
dropbox_issues = []
|
|
if not (getattr(settings, 'dropbox_app_key', None) and
|
|
getattr(settings, 'dropbox_app_secret', None) and
|
|
getattr(settings, 'dropbox_refresh_token', None)):
|
|
dropbox_issues.append("Dropbox credentials are not fully configured")
|
|
issues['dropbox'] = dropbox_issues
|
|
|
|
# Validate Nextcloud config
|
|
nextcloud_issues = []
|
|
if not (getattr(settings, 'nextcloud_upload_url', None) and
|
|
getattr(settings, 'nextcloud_username', None) and
|
|
getattr(settings, 'nextcloud_password', None)):
|
|
nextcloud_issues.append("Nextcloud credentials are not fully configured")
|
|
issues['nextcloud'] = nextcloud_issues
|
|
|
|
# Validate SFTP config
|
|
sftp_issues = []
|
|
if not getattr(settings, 'sftp_host', None):
|
|
sftp_issues.append("SFTP_HOST is not configured")
|
|
|
|
sftp_key_path = getattr(settings, 'sftp_private_key', None)
|
|
if sftp_key_path and not os.path.exists(sftp_key_path):
|
|
sftp_issues.append(f"SFTP_KEY_PATH file not found: {sftp_key_path}")
|
|
|
|
if not sftp_key_path and not getattr(settings, 'sftp_password', None):
|
|
sftp_issues.append("Neither SFTP_KEY_PATH nor SFTP_PASSWORD is configured")
|
|
|
|
issues['sftp'] = sftp_issues
|
|
|
|
# Validate Email sending
|
|
email_issues = []
|
|
if not getattr(settings, 'email_host', None):
|
|
email_issues.append("EMAIL_HOST is not configured")
|
|
if not getattr(settings, 'email_default_recipient', None):
|
|
email_issues.append("EMAIL_DEFAULT_RECIPIENT is not configured")
|
|
issues['email'] = email_issues
|
|
|
|
# Validate S3
|
|
s3_issues = []
|
|
if not getattr(settings, 's3_bucket_name', None):
|
|
s3_issues.append("S3_BUCKET_NAME is not configured")
|
|
if not (getattr(settings, 'aws_access_key_id', None) and
|
|
getattr(settings, 'aws_secret_access_key', None)):
|
|
s3_issues.append("AWS credentials are not configured")
|
|
issues['s3'] = s3_issues
|
|
|
|
# Validate FTP
|
|
ftp_issues = []
|
|
if not getattr(settings, 'ftp_host', None):
|
|
ftp_issues.append("FTP_HOST is not configured")
|
|
if not getattr(settings, 'ftp_username', None):
|
|
ftp_issues.append("FTP_USERNAME is not configured")
|
|
if not getattr(settings, 'ftp_password', None):
|
|
ftp_issues.append("FTP_PASSWORD is not configured")
|
|
issues['ftp'] = ftp_issues
|
|
|
|
# Validate WebDAV
|
|
webdav_issues = []
|
|
if not getattr(settings, 'webdav_url', None):
|
|
webdav_issues.append("WEBDAV_URL is not configured")
|
|
if not getattr(settings, 'webdav_username', None):
|
|
webdav_issues.append("WEBDAV_USERNAME is not configured")
|
|
if not getattr(settings, 'webdav_password', None):
|
|
webdav_issues.append("WEBDAV_PASSWORD is not configured")
|
|
issues['webdav'] = webdav_issues
|
|
|
|
# Validate Google Drive
|
|
gdrive_issues = []
|
|
if not getattr(settings, 'google_drive_credentials_json', None):
|
|
gdrive_issues.append("GOOGLE_DRIVE_CREDENTIALS_JSON is not configured")
|
|
if not getattr(settings, 'google_drive_folder_id', None):
|
|
gdrive_issues.append("GOOGLE_DRIVE_FOLDER_ID is not configured")
|
|
issues['google_drive'] = gdrive_issues
|
|
|
|
# Validate Paperless
|
|
paperless_issues = []
|
|
if not getattr(settings, 'paperless_host', None):
|
|
paperless_issues.append("PAPERLESS_HOST is not configured")
|
|
if not getattr(settings, 'paperless_ngx_api_token', None):
|
|
paperless_issues.append("PAPERLESS_NGX_API_TOKEN is not configured")
|
|
issues['paperless'] = paperless_issues
|
|
|
|
# Validate OneDrive
|
|
onedrive_issues = []
|
|
if not (getattr(settings, 'onedrive_client_id', None) and
|
|
getattr(settings, 'onedrive_client_secret', None) and
|
|
getattr(settings, 'onedrive_refresh_token', None)):
|
|
onedrive_issues.append("OneDrive credentials are not fully configured")
|
|
issues['onedrive'] = onedrive_issues
|
|
|
|
# Validate Uptime Kuma
|
|
uptime_kuma_issues = []
|
|
if not getattr(settings, 'uptime_kuma_url', None):
|
|
uptime_kuma_issues.append("UPTIME_KUMA_URL is not configured")
|
|
issues['uptime_kuma'] = uptime_kuma_issues
|
|
|
|
return issues
|
|
|
|
def validate_notification_config():
|
|
"""Check notification configuration"""
|
|
issues = []
|
|
|
|
# Check if any notification URLs are configured
|
|
if not getattr(settings, 'notification_urls', None):
|
|
issues.append("No notification URLs configured")
|
|
else:
|
|
try:
|
|
# Try initializing Apprise to validate URLs
|
|
import apprise
|
|
a = apprise.Apprise()
|
|
|
|
for url in settings.notification_urls:
|
|
try:
|
|
if not a.add(url):
|
|
issues.append(f"Invalid notification URL format: {url}")
|
|
except Exception as e:
|
|
issues.append(f"Error with notification URL: {str(e)}")
|
|
|
|
except ImportError:
|
|
issues.append("Apprise module not installed")
|
|
|
|
if not issues:
|
|
logger.info("Notification configuration valid")
|
|
else:
|
|
logger.warning(f"Notification configuration issues: {', '.join(issues)}")
|
|
|
|
return issues
|
|
|
|
def check_all_configs():
|
|
"""Run all configuration validations and log results"""
|
|
from app.utils.config_validator.settings_display import dump_all_settings
|
|
|
|
logger.info("Validating application configuration...")
|
|
|
|
# Check if debug is enabled and dump all settings if it is
|
|
if hasattr(settings, 'debug') and settings.debug:
|
|
dump_all_settings()
|
|
|
|
# Check auth config
|
|
auth_issues = validate_auth_config()
|
|
if auth_issues:
|
|
logger.warning(f"Authentication configuration issues: {', '.join(auth_issues)}")
|
|
else:
|
|
logger.info("Authentication configuration OK")
|
|
|
|
# Check email config
|
|
email_issues = validate_email_config()
|
|
if email_issues:
|
|
logger.warning(f"Email configuration issues: {', '.join(email_issues)}")
|
|
else:
|
|
logger.info("Email configuration OK")
|
|
|
|
# Check storage configs
|
|
storage_issues = validate_storage_configs()
|
|
for provider, issues in storage_issues.items():
|
|
if issues:
|
|
logger.warning(f"{provider.capitalize()} configuration issues: {', '.join(issues)}")
|
|
else:
|
|
logger.info(f"{provider.capitalize()} configuration OK")
|
|
|
|
# Check notification configuration
|
|
notification_issues = validate_notification_config()
|
|
if notification_issues:
|
|
logger.warning(f"Notification configuration issues: {', '.join(notification_issues)}")
|
|
else:
|
|
logger.info("Notification configuration OK")
|
|
|
|
# Return all identified issues
|
|
return {
|
|
'auth': auth_issues,
|
|
'email': email_issues,
|
|
'storage': storage_issues,
|
|
'notification': notification_issues
|
|
}
|