浏览代码

changed 404 to info

zehe 1 月之前
父节点
当前提交
61df6b64bb
共有 1 个文件被更改,包括 258 次插入178 次删除
  1. 258 178
      main.py

+ 258 - 178
main.py

@@ -16,6 +16,7 @@ from typing import List, Tuple
 import base64
 import base64
 import signal
 import signal
 
 
+
 # Configure logging with custom handler
 # Configure logging with custom handler
 class NtfyLogHandler(logging.Handler):
 class NtfyLogHandler(logging.Handler):
     """Custom logging handler that sends logs to ntfy health backends"""
     """Custom logging handler that sends logs to ntfy health backends"""
@@ -26,51 +27,55 @@ class NtfyLogHandler(logging.Handler):
 
 
     def emit(self, record):
     def emit(self, record):
         """Send log record to health backends"""
         """Send log record to health backends"""
-        if hasattr(self.config, 'ntfy_backends_health') and self.config.send_all_logs:
+        if hasattr(self.config, "ntfy_backends_health") and self.config.send_all_logs:
             try:
             try:
                 log_message = self.format(record)
                 log_message = self.format(record)
                 # Get configured log level or default to WARNING
                 # Get configured log level or default to WARNING
-                min_level = getattr(logging, self.config.log_level.upper(), logging.WARNING)
+                min_level = getattr(
+                    logging, self.config.log_level.upper(), logging.WARNING
+                )
 
 
                 if record.levelno >= min_level:
                 if record.levelno >= min_level:
                     # Format message with appropriate emoji based on log level
                     # Format message with appropriate emoji based on log level
-                    emoji = "🚨" if record.levelno >= logging.ERROR else "⚠️" if record.levelno >= logging.WARNING else "ℹ️"
+                    emoji = (
+                        "🚨"
+                        if record.levelno >= logging.ERROR
+                        else "⚠️"
+                        if record.levelno >= logging.WARNING
+                        else "ℹ️"
+                    )
                     title = f"Emergency Access {record.levelname}"
                     title = f"Emergency Access {record.levelname}"
                     message = f"{emoji} {record.name}: {record.getMessage()}"
                     message = f"{emoji} {record.name}: {record.getMessage()}"
 
 
                     send_ntfy_notification(
                     send_ntfy_notification(
-                        self.config.ntfy_backends_health,
-                        message,
-                        title
+                        self.config.ntfy_backends_health, message, title
                     )
                     )
             except Exception:
             except Exception:
                 # Don't fail the application if logging notification fails
                 # Don't fail the application if logging notification fails
                 pass
                 pass
 
 
+
 # Configure logging with secure-file fallback
 # Configure logging with secure-file fallback
-log_path = '/var/log/emergency-access.log'
+log_path = "/var/log/emergency-access.log"
 try:
 try:
     os.makedirs(os.path.dirname(log_path), exist_ok=True)
     os.makedirs(os.path.dirname(log_path), exist_ok=True)
     # Ensure the log file exists with restrictive permissions
     # Ensure the log file exists with restrictive permissions
     if not os.path.exists(log_path):
     if not os.path.exists(log_path):
-        open(log_path, 'a').close()
+        open(log_path, "a").close()
         try:
         try:
             os.chmod(log_path, 0o600)
             os.chmod(log_path, 0o600)
         except Exception:
         except Exception:
             # Best-effort; if this fails we continue with stream logging
             # Best-effort; if this fails we continue with stream logging
             pass
             pass
-    log_handlers = [
-        logging.FileHandler(log_path),
-        logging.StreamHandler()
-    ]
+    log_handlers = [logging.FileHandler(log_path), logging.StreamHandler()]
 except Exception:
 except Exception:
     # If any issue creating the file (permissions, etc.), fall back to stream-only logging
     # If any issue creating the file (permissions, etc.), fall back to stream-only logging
     log_handlers = [logging.StreamHandler()]
     log_handlers = [logging.StreamHandler()]
 
 
 logging.basicConfig(
 logging.basicConfig(
     level=logging.INFO,
     level=logging.INFO,
-    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
-    handlers=log_handlers
+    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
+    handlers=log_handlers,
 )
 )
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
@@ -80,7 +85,6 @@ app = Flask(__name__)
 config = None
 config = None
 
 
 
 
-
 def require_auth(key_config=None, is_health=False):
 def require_auth(key_config=None, is_health=False):
     """Decorator for HTTP Basic Authentication with simple in-memory rate limiting.
     """Decorator for HTTP Basic Authentication with simple in-memory rate limiting.
 
 
@@ -100,24 +104,24 @@ def require_auth(key_config=None, is_health=False):
     # Initialize shared state on the require_auth function object (module-global alternative)
     # Initialize shared state on the require_auth function object (module-global alternative)
     if not hasattr(require_auth, "_state"):
     if not hasattr(require_auth, "_state"):
         require_auth._state = {
         require_auth._state = {
-            'attempts': {},  # (ip, username) -> list[timestamps]
-            'blocked': {},   # (ip, username) -> blocked_until_timestamp
-            'lock': threading.Lock()
+            "attempts": {},  # (ip, username) -> list[timestamps]
+            "blocked": {},  # (ip, username) -> blocked_until_timestamp
+            "lock": threading.Lock(),
         }
         }
 
 
     MAX_ATTEMPTS = 5
     MAX_ATTEMPTS = 5
-    WINDOW = 300      # seconds
-    LOCKOUT = 900     # seconds
+    WINDOW = 300  # seconds
+    LOCKOUT = 900  # seconds
 
 
     def decorator(f):
     def decorator(f):
         @wraps(f)
         @wraps(f)
         def decorated_function(*args, **kwargs):
         def decorated_function(*args, **kwargs):
             if config is None:
             if config is None:
                 logger.error("Configuration not loaded")
                 logger.error("Configuration not loaded")
-                return jsonify({'error': 'Server configuration error'}), 500
+                return jsonify({"error": "Server configuration error"}), 500
 
 
             auth = request.authorization
             auth = request.authorization
-            client_ip = request.remote_addr or 'unknown'
+            client_ip = request.remote_addr or "unknown"
 
 
             # determine username for rate limit key; use placeholder if missing
             # determine username for rate limit key; use placeholder if missing
             username_for_key = auth.username if auth and auth.username else "<no_auth>"
             username_for_key = auth.username if auth and auth.username else "<no_auth>"
@@ -128,46 +132,64 @@ def require_auth(key_config=None, is_health=False):
             state = require_auth._state
             state = require_auth._state
 
 
             # Check block list
             # Check block list
-            with state['lock']:
-                blocked_until = state['blocked'].get(key)
+            with state["lock"]:
+                blocked_until = state["blocked"].get(key)
                 if blocked_until and now_ts < blocked_until:
                 if blocked_until and now_ts < blocked_until:
                     retry_after = int(blocked_until - now_ts)
                     retry_after = int(blocked_until - now_ts)
-                    logger.warning(f"Blocked auth attempt from {client_ip} for user '{username_for_key}' (locked until {blocked_until})")
+                    logger.warning(
+                        f"Blocked auth attempt from {client_ip} for user '{username_for_key}' (locked until {blocked_until})"
+                    )
                     # Return 429 Too Many Requests
                     # Return 429 Too Many Requests
-                    return jsonify({'error': 'Too many authentication attempts, temporarily locked'}), 429, {
-                        'Retry-After': str(retry_after)
-                    }
+                    return (
+                        jsonify(
+                            {
+                                "error": "Too many authentication attempts, temporarily locked"
+                            }
+                        ),
+                        429,
+                        {"Retry-After": str(retry_after)},
+                    )
 
 
             if not auth:
             if not auth:
                 # For missing auth, still account for attempts keyed by ip and '<no_auth>'
                 # For missing auth, still account for attempts keyed by ip and '<no_auth>'
                 # Increment attempt count and possibly lock
                 # Increment attempt count and possibly lock
-                with state['lock']:
-                    attempts = state['attempts'].setdefault(key, [])
+                with state["lock"]:
+                    attempts = state["attempts"].setdefault(key, [])
                     # prune old timestamps
                     # prune old timestamps
                     attempts = [t for t in attempts if now_ts - t <= WINDOW]
                     attempts = [t for t in attempts if now_ts - t <= WINDOW]
                     attempts.append(now_ts)
                     attempts.append(now_ts)
-                    state['attempts'][key] = attempts
+                    state["attempts"][key] = attempts
                     if len(attempts) > MAX_ATTEMPTS:
                     if len(attempts) > MAX_ATTEMPTS:
                         # Lock out
                         # Lock out
-                        state['blocked'][key] = now_ts + LOCKOUT
-                        logger.error(f"Locking out {client_ip} for missing/invalid auth (no credentials) after repeated attempts")
+                        state["blocked"][key] = now_ts + LOCKOUT
+                        logger.error(
+                            f"Locking out {client_ip} for missing/invalid auth (no credentials) after repeated attempts"
+                        )
                         # Try to notify about brute force (best-effort)
                         # Try to notify about brute force (best-effort)
                         try:
                         try:
-                            if config and hasattr(config, 'ntfy_backends_health'):
+                            if config and hasattr(config, "ntfy_backends_health"):
                                 send_ntfy_notification(
                                 send_ntfy_notification(
                                     config.ntfy_backends_health,
                                     config.ntfy_backends_health,
                                     f"🚨 Brute-force lockout: {client_ip} (no credentials) on server",
                                     f"🚨 Brute-force lockout: {client_ip} (no credentials) on server",
-                                    "Emergency Access ALERT"
+                                    "Emergency Access ALERT",
                                 )
                                 )
                         except Exception:
                         except Exception:
                             pass
                             pass
-                        return jsonify({'error': 'Too many authentication attempts, temporarily locked'}), 429, {
-                            'Retry-After': str(LOCKOUT)
-                        }
-
-                return jsonify({'error': 'Authentication required'}), 401, {
-                    'WWW-Authenticate': 'Basic realm="Emergency Access"'
-                }
+                        return (
+                            jsonify(
+                                {
+                                    "error": "Too many authentication attempts, temporarily locked"
+                                }
+                            ),
+                            429,
+                            {"Retry-After": str(LOCKOUT)},
+                        )
+
+                return (
+                    jsonify({"error": "Authentication required"}),
+                    401,
+                    {"WWW-Authenticate": 'Basic realm="Emergency Access"'},
+                )
 
 
             # Determine expected credentials
             # Determine expected credentials
             if is_health:
             if is_health:
@@ -177,71 +199,90 @@ def require_auth(key_config=None, is_health=False):
             else:
             else:
                 if key_config is None:
                 if key_config is None:
                     logger.error("Key configuration not provided for authentication")
                     logger.error("Key configuration not provided for authentication")
-                    return jsonify({'error': 'Server configuration error'}), 500
+                    return jsonify({"error": "Server configuration error"}), 500
                 expected_username = key_config.username
                 expected_username = key_config.username
                 expected_password_hash = key_config.password_hash
                 expected_password_hash = key_config.password_hash
                 auth_type = f"key '{key_config.key_id}'"
                 auth_type = f"key '{key_config.key_id}'"
 
 
             # Verify credentials
             # Verify credentials
-            credential_ok = (auth.username == expected_username and
-                             Config.verify_password(auth.password, expected_password_hash))
+            credential_ok = (
+                auth.username == expected_username
+                and Config.verify_password(auth.password, expected_password_hash)
+            )
 
 
             if not credential_ok:
             if not credential_ok:
                 # record failed attempt and check for lockout
                 # record failed attempt and check for lockout
-                with state['lock']:
-                    attempts = state['attempts'].setdefault(key, [])
+                with state["lock"]:
+                    attempts = state["attempts"].setdefault(key, [])
                     attempts = [t for t in attempts if now_ts - t <= WINDOW]
                     attempts = [t for t in attempts if now_ts - t <= WINDOW]
                     attempts.append(now_ts)
                     attempts.append(now_ts)
-                    state['attempts'][key] = attempts
+                    state["attempts"][key] = attempts
 
 
                     if len(attempts) > MAX_ATTEMPTS:
                     if len(attempts) > MAX_ATTEMPTS:
-                        state['blocked'][key] = now_ts + LOCKOUT
-                        logger.error(f"Locking out {client_ip} for user '{username_for_key}' after repeated failed attempts")
+                        state["blocked"][key] = now_ts + LOCKOUT
+                        logger.error(
+                            f"Locking out {client_ip} for user '{username_for_key}' after repeated failed attempts"
+                        )
                         # Notify about brute-force lockout (best-effort)
                         # Notify about brute-force lockout (best-effort)
                         try:
                         try:
                             notify_backends = []
                             notify_backends = []
-                            if config and hasattr(config, 'ntfy_backends_health'):
+                            if config and hasattr(config, "ntfy_backends_health"):
                                 notify_backends.extend(config.ntfy_backends_health)
                                 notify_backends.extend(config.ntfy_backends_health)
                             # Include key-specific backends when available
                             # Include key-specific backends when available
-                            if key_config and getattr(key_config, 'backends', None):
+                            if key_config and getattr(key_config, "backends", None):
                                 notify_backends.extend(key_config.backends)
                                 notify_backends.extend(key_config.backends)
                             if notify_backends:
                             if notify_backends:
                                 send_ntfy_notification(
                                 send_ntfy_notification(
                                     list(dict.fromkeys(notify_backends)),  # deduplicate
                                     list(dict.fromkeys(notify_backends)),  # deduplicate
                                     f"🚨 Brute-force lockout: {client_ip} user='{username_for_key}' on {auth_type}",
                                     f"🚨 Brute-force lockout: {client_ip} user='{username_for_key}' on {auth_type}",
-                                    "Emergency Access ALERT"
+                                    "Emergency Access ALERT",
                                 )
                                 )
                         except Exception:
                         except Exception:
                             pass
                             pass
 
 
-                        return jsonify({'error': 'Too many authentication attempts, temporarily locked'}), 429, {
-                            'Retry-After': str(LOCKOUT)
-                        }
-
-                logger.warning(f"Authentication failed for {auth_type}: invalid credentials from {client_ip}")
-                return jsonify({'error': 'Invalid credentials'}), 401, {
-                    'WWW-Authenticate': 'Basic realm="Emergency Access"'
-                }
+                        return (
+                            jsonify(
+                                {
+                                    "error": "Too many authentication attempts, temporarily locked"
+                                }
+                            ),
+                            429,
+                            {"Retry-After": str(LOCKOUT)},
+                        )
+
+                logger.warning(
+                    f"Authentication failed for {auth_type}: invalid credentials from {client_ip}"
+                )
+                return (
+                    jsonify({"error": "Invalid credentials"}),
+                    401,
+                    {"WWW-Authenticate": 'Basic realm="Emergency Access"'},
+                )
 
 
             # On success, clear recorded failed attempts for this key
             # On success, clear recorded failed attempts for this key
-            with state['lock']:
-                if key in state['attempts']:
+            with state["lock"]:
+                if key in state["attempts"]:
                     try:
                     try:
-                        del state['attempts'][key]
+                        del state["attempts"][key]
                     except KeyError:
                     except KeyError:
                         pass
                         pass
-                if key in state['blocked']:
+                if key in state["blocked"]:
                     try:
                     try:
-                        del state['blocked'][key]
+                        del state["blocked"][key]
                     except KeyError:
                     except KeyError:
                         pass
                         pass
 
 
             logger.info(f"Authentication successful for {auth_type}")
             logger.info(f"Authentication successful for {auth_type}")
             return f(*args, **kwargs)
             return f(*args, **kwargs)
+
         return decorated_function
         return decorated_function
+
     return decorator
     return decorator
 
 
-def send_ntfy_notification(backends: List[str], message: str, title: str = None) -> Tuple[bool, List[str]]:
+
+def send_ntfy_notification(
+    backends: List[str], message: str, title: str = None
+) -> Tuple[bool, List[str]]:
     """
     """
     Send notification using dschep/ntfy with dedicated config file
     Send notification using dschep/ntfy with dedicated config file
     Returns: (success, successful_backends)
     Returns: (success, successful_backends)
@@ -261,7 +302,9 @@ def send_ntfy_notification(backends: List[str], message: str, title: str = None)
                     import ntfy
                     import ntfy
                     from ntfy.config import load_config
                     from ntfy.config import load_config
                 except ImportError:
                 except ImportError:
-                    raise Exception("ntfy package not available. Please install with: pip install ntfy")
+                    raise Exception(
+                        "ntfy package not available. Please install with: pip install ntfy"
+                    )
 
 
                 if config is None:
                 if config is None:
                     raise Exception("Configuration not loaded")
                     raise Exception("Configuration not loaded")
@@ -279,9 +322,13 @@ def send_ntfy_notification(backends: List[str], message: str, title: str = None)
                     try:
                     try:
                         # Send notification using the backend name from our config file
                         # Send notification using the backend name from our config file
                         if title:
                         if title:
-                            result[0] = ntfy.notify(message, title=title, config=ntfy_config)
+                            result[0] = ntfy.notify(
+                                message, title=title, config=ntfy_config
+                            )
                         else:
                         else:
-                            result[0] = ntfy.notify(message, config=ntfy_config, title="Note")
+                            result[0] = ntfy.notify(
+                                message, config=ntfy_config, title="Note"
+                            )
                     except Exception as e:
                     except Exception as e:
                         exception[0] = e
                         exception[0] = e
 
 
@@ -313,18 +360,25 @@ def send_ntfy_notification(backends: List[str], message: str, title: str = None)
             except Exception as e:
             except Exception as e:
                 last_error = e
                 last_error = e
                 if attempt < max_retries - 1:
                 if attempt < max_retries - 1:
-                    logger.warning(f"Notification attempt {attempt + 1} failed for {backend}: {str(e)}, retrying...")
+                    logger.warning(
+                        f"Notification attempt {attempt + 1} failed for {backend}: {str(e)}, retrying..."
+                    )
                     time.sleep(retry_delay * (attempt + 1))  # Exponential backoff
                     time.sleep(retry_delay * (attempt + 1))  # Exponential backoff
                 else:
                 else:
-                    logger.error(f"All notification attempts failed for {backend}: {str(e)}")
+                    logger.error(
+                        f"All notification attempts failed for {backend}: {str(e)}"
+                    )
 
 
         if not success and last_error:
         if not success and last_error:
             # Don't raise exception - just log failure and continue with other backends
             # Don't raise exception - just log failure and continue with other backends
-            logger.error(f"Failed to send notification to {backend} after {max_retries} attempts: {str(last_error)}")
+            logger.error(
+                f"Failed to send notification to {backend} after {max_retries} attempts: {str(last_error)}"
+            )
 
 
     success = len(successful_backends) > 0
     success = len(successful_backends) > 0
     return success, successful_backends
     return success, successful_backends
 
 
+
 def read_file_safely(file_path: str) -> Tuple[bool, str]:
 def read_file_safely(file_path: str) -> Tuple[bool, str]:
     """
     """
     Safely read file content
     Safely read file content
@@ -335,7 +389,7 @@ def read_file_safely(file_path: str) -> Tuple[bool, str]:
             logger.error(f"File not found: {file_path}")
             logger.error(f"File not found: {file_path}")
             return False, f"File not found: {file_path}"
             return False, f"File not found: {file_path}"
 
 
-        with open(file_path, 'r') as f:
+        with open(file_path, "r") as f:
             content = f.read().strip()
             content = f.read().strip()
 
 
         if not content:
         if not content:
@@ -351,69 +405,88 @@ def read_file_safely(file_path: str) -> Tuple[bool, str]:
         logger.error(f"Failed to read file {file_path}: {str(e)}")
         logger.error(f"Failed to read file {file_path}: {str(e)}")
         return False, f"Failed to read file: {str(e)}"
         return False, f"Failed to read file: {str(e)}"
 
 
+
 def create_key_handler(key_config):
 def create_key_handler(key_config):
     """Create a key access handler for a specific key configuration"""
     """Create a key access handler for a specific key configuration"""
+
     @require_auth(key_config=key_config)
     @require_auth(key_config=key_config)
     def get_key_part():
     def get_key_part():
         """Emergency key access endpoint"""
         """Emergency key access endpoint"""
         if key_config is None:
         if key_config is None:
             logger.error("Key configuration is None in get_key_part")
             logger.error("Key configuration is None in get_key_part")
-            return jsonify({'error': 'Server configuration error'}), 500
-
-        logger.warning(f"EMERGENCY: Key access attempt detected for key '{key_config.key_id}'")
-
+            return jsonify({"error": "Server configuration error"}), 500
 
 
+        logger.warning(
+            f"EMERGENCY: Key access attempt detected for key '{key_config.key_id}'"
+        )
 
 
         try:
         try:
             # Send notification first - fail-safe approach
             # Send notification first - fail-safe approach
             notification_success, successful_backends = send_ntfy_notification(
             notification_success, successful_backends = send_ntfy_notification(
-                key_config.backends,
-                key_config.message,
-                "EMERGENCY ACCESS ALERT"
+                key_config.backends, key_config.message, "EMERGENCY ACCESS ALERT"
             )
             )
 
 
             if not notification_success:
             if not notification_success:
-                logger.error(f"CRITICAL: Failed to send notifications to any backend for key '{key_config.key_id}'")
-                return jsonify({
-                    'error': 'Notification system failure',
-                    'message': 'Access denied for security reasons'
-                }), 500
+                logger.error(
+                    f"CRITICAL: Failed to send notifications to any backend for key '{key_config.key_id}'"
+                )
+                return jsonify(
+                    {
+                        "error": "Notification system failure",
+                        "message": "Access denied for security reasons",
+                    }
+                ), 500
 
 
-            logger.info(f"Notifications sent successfully to: {successful_backends} for key '{key_config.key_id}'")
+            logger.info(
+                f"Notifications sent successfully to: {successful_backends} for key '{key_config.key_id}'"
+            )
 
 
             # Read key file
             # Read key file
             file_success, content = read_file_safely(key_config.file_path)
             file_success, content = read_file_safely(key_config.file_path)
 
 
             if not file_success:
             if not file_success:
-                logger.error(f"CRITICAL: Failed to read key file for '{key_config.key_id}': {content}")
-                return jsonify({
-                    'error': 'File access failure',
-                    'message': 'Unable to retrieve key part'
-                }), 500
-
-            logger.warning(f"EMERGENCY: Key part successfully retrieved and sent for key '{key_config.key_id}'")
-            resp = jsonify({
-                'success': True,
-                'key_id': key_config.key_id,
-                'key_part': content,
-                'timestamp': time.time(),
-                'notified_backends': successful_backends
-            })
+                logger.error(
+                    f"CRITICAL: Failed to read key file for '{key_config.key_id}': {content}"
+                )
+                return jsonify(
+                    {
+                        "error": "File access failure",
+                        "message": "Unable to retrieve key part",
+                    }
+                ), 500
+
+            logger.warning(
+                f"EMERGENCY: Key part successfully retrieved and sent for key '{key_config.key_id}'"
+            )
+            resp = jsonify(
+                {
+                    "success": True,
+                    "key_id": key_config.key_id,
+                    "key_part": content,
+                    "timestamp": time.time(),
+                    "notified_backends": successful_backends,
+                }
+            )
             # Ensure responses with secret material are never cached by clients or intermediaries
             # Ensure responses with secret material are never cached by clients or intermediaries
-            resp.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, private'
-            resp.headers['Pragma'] = 'no-cache'
-            resp.headers['Expires'] = '0'
+            resp.headers["Cache-Control"] = (
+                "no-store, no-cache, must-revalidate, private"
+            )
+            resp.headers["Pragma"] = "no-cache"
+            resp.headers["Expires"] = "0"
             # Additional defensive headers
             # Additional defensive headers
-            resp.headers['X-Content-Type-Options'] = 'nosniff'
-            resp.headers['Content-Security-Policy'] = "default-src 'none'; frame-ancestors 'none'; sandbox"
+            resp.headers["X-Content-Type-Options"] = "nosniff"
+            resp.headers["Content-Security-Policy"] = (
+                "default-src 'none'; frame-ancestors 'none'; sandbox"
+            )
             return resp
             return resp
 
 
         except Exception as e:
         except Exception as e:
-            logger.error(f"CRITICAL: Unexpected error in key access for '{key_config.key_id}': {str(e)}")
-            return jsonify({
-                'error': 'System error',
-                'message': 'Internal server error'
-            }), 500
+            logger.error(
+                f"CRITICAL: Unexpected error in key access for '{key_config.key_id}': {str(e)}"
+            )
+            return jsonify(
+                {"error": "System error", "message": "Internal server error"}
+            ), 500
 
 
     return get_key_part
     return get_key_part
 
 
@@ -423,18 +496,14 @@ def health_check():
     """Health check endpoint that verifies both health monitoring and all key request functionality"""
     """Health check endpoint that verifies both health monitoring and all key request functionality"""
     logger.info("Health check requested")
     logger.info("Health check requested")
 
 
-
-
     if config is None:
     if config is None:
         logger.error("Configuration not loaded during health check")
         logger.error("Configuration not loaded during health check")
-        return jsonify({'status': 'error', 'message': 'Configuration not loaded'}), 500
+        return jsonify({"status": "error", "message": "Configuration not loaded"}), 500
 
 
     try:
     try:
         # Test health notification system
         # Test health notification system
         health_notification_success, health_backends = send_ntfy_notification(
         health_notification_success, health_backends = send_ntfy_notification(
-            config.ntfy_backends_health,
-            config.ntfy_health_message,
-            "Health Check"
+            config.ntfy_backends_health, config.ntfy_health_message, "Health Check"
         )
         )
 
 
         # Test dummy file access
         # Test dummy file access
@@ -457,24 +526,26 @@ def health_check():
                 # Test notification without actually sending
                 # Test notification without actually sending
                 backend_test_success = len(key_config.backends) > 0
                 backend_test_success = len(key_config.backends) > 0
                 key_backends_status[key_id] = {
                 key_backends_status[key_id] = {
-                    'backends': key_config.backends,
-                    'success': backend_test_success
+                    "backends": key_config.backends,
+                    "success": backend_test_success,
                 }
                 }
                 if not backend_test_success:
                 if not backend_test_success:
                     all_key_backends_ok = False
                     all_key_backends_ok = False
             except Exception as e:
             except Exception as e:
                 key_backends_status[key_id] = {
                 key_backends_status[key_id] = {
-                    'backends': key_config.backends,
-                    'success': False,
-                    'error': str(e)
+                    "backends": key_config.backends,
+                    "success": False,
+                    "error": str(e),
                 }
                 }
                 all_key_backends_ok = False
                 all_key_backends_ok = False
 
 
         # Determine overall health status
         # Determine overall health status
-        all_systems_ok = (health_notification_success and
-                         dummy_file_success and
-                         all_key_files_ok and
-                         all_key_backends_ok)
+        all_systems_ok = (
+            health_notification_success
+            and dummy_file_success
+            and all_key_files_ok
+            and all_key_backends_ok
+        )
 
 
         if not all_systems_ok:
         if not all_systems_ok:
             error_details = []
             error_details = []
@@ -489,57 +560,59 @@ def health_check():
                     error_details.append(f"key file access failed for '{key_id}'")
                     error_details.append(f"key file access failed for '{key_id}'")
 
 
             for key_id, status in key_backends_status.items():
             for key_id, status in key_backends_status.items():
-                if not status['success']:
+                if not status["success"]:
                     error_msg = f"key backends failed for '{key_id}'"
                     error_msg = f"key backends failed for '{key_id}'"
-                    if 'error' in status:
+                    if "error" in status:
                         error_msg += f": {status['error']}"
                         error_msg += f": {status['error']}"
                     error_details.append(error_msg)
                     error_details.append(error_msg)
 
 
             logger.error(f"Health check failed: {', '.join(error_details)}")
             logger.error(f"Health check failed: {', '.join(error_details)}")
-            return jsonify({
-                'status': 'error',
-                'message': 'System components failed',
-                'details': error_details,
-                'health_notifications': health_notification_success,
-                'dummy_file_access': dummy_file_success,
-                'key_files_status': key_files_status,
-                'key_backends_status': key_backends_status
-            }), 500
+            return jsonify(
+                {
+                    "status": "error",
+                    "message": "System components failed",
+                    "details": error_details,
+                    "health_notifications": health_notification_success,
+                    "dummy_file_access": dummy_file_success,
+                    "key_files_status": key_files_status,
+                    "key_backends_status": key_backends_status,
+                }
+            ), 500
 
 
         logger.info("Health check completed successfully - all systems operational")
         logger.info("Health check completed successfully - all systems operational")
-        return jsonify({
-            'status': 'ok',
-            'timestamp': time.time(),
-            'health_backends_notified': health_backends,
-            'dummy_content_length': len(dummy_content),
-            'keys_accessible': len(key_files_status),
-            'key_files_status': key_files_status,
-            'key_backends_status': key_backends_status,
-            'emergency_system_ready': True
-        })
+        return jsonify(
+            {
+                "status": "ok",
+                "timestamp": time.time(),
+                "health_backends_notified": health_backends,
+                "dummy_content_length": len(dummy_content),
+                "keys_accessible": len(key_files_status),
+                "key_files_status": key_files_status,
+                "key_backends_status": key_backends_status,
+                "emergency_system_ready": True,
+            }
+        )
 
 
     except Exception as e:
     except Exception as e:
         logger.error(f"Health check error: {str(e)}")
         logger.error(f"Health check error: {str(e)}")
-        return jsonify({
-            'status': 'error',
-            'message': 'System error',
-            'error': str(e)
-        }), 500
-
-
+        return jsonify(
+            {"status": "error", "message": "System error", "error": str(e)}
+        ), 500
 
 
 
 
 @app.errorhandler(404)
 @app.errorhandler(404)
 def not_found(error):
 def not_found(error):
     """Handle 404 errors silently for security"""
     """Handle 404 errors silently for security"""
-    logger.warning(f"404 attempt: {error}")
-    return jsonify({'error': 'Not found'}), 404
+    logger.info(f"404 attempt: {error}")
+    return jsonify({"error": "Not found"}), 404
+
 
 
 @app.errorhandler(500)
 @app.errorhandler(500)
 def internal_error(error):
 def internal_error(error):
     """Handle internal server errors"""
     """Handle internal server errors"""
     logger.error(f"Internal server error: {error}")
     logger.error(f"Internal server error: {error}")
-    return jsonify({'error': 'Internal server error'}), 500
+    return jsonify({"error": "Internal server error"}), 500
+
 
 
 def validate_setup():
 def validate_setup():
     """Validate system setup before starting"""
     """Validate system setup before starting"""
@@ -556,7 +629,7 @@ def validate_setup():
 
 
     # Test dummy file permissions
     # Test dummy file permissions
     try:
     try:
-        with open(config.dummy_file_path, 'r') as f:
+        with open(config.dummy_file_path, "r") as f:
             f.read(1)
             f.read(1)
     except Exception as e:
     except Exception as e:
         logger.error(f"Dummy file permission test failed: {str(e)}")
         logger.error(f"Dummy file permission test failed: {str(e)}")
@@ -573,7 +646,7 @@ def validate_setup():
 
 
         # Test key file permissions
         # Test key file permissions
         try:
         try:
-            with open(key_config.file_path, 'r') as f:
+            with open(key_config.file_path, "r") as f:
                 f.read(1)
                 f.read(1)
         except Exception as e:
         except Exception as e:
             logger.error(f"Key file permission test failed for '{key_id}': {str(e)}")
             logger.error(f"Key file permission test failed for '{key_id}': {str(e)}")
@@ -591,7 +664,7 @@ def validate_setup():
         health_success, _ = send_ntfy_notification(
         health_success, _ = send_ntfy_notification(
             config.ntfy_backends_health[:1],  # Test only first backend
             config.ntfy_backends_health[:1],  # Test only first backend
             "System startup test - health notifications",
             "System startup test - health notifications",
-            "Emergency Access Startup Test"
+            "Emergency Access Startup Test",
         )
         )
 
 
         if not health_success:
         if not health_success:
@@ -603,7 +676,7 @@ def validate_setup():
             key_success, _ = send_ntfy_notification(
             key_success, _ = send_ntfy_notification(
                 key_config.backends[:1],  # Test only first backend
                 key_config.backends[:1],  # Test only first backend
                 f"System startup test - key '{key_id}' notifications",
                 f"System startup test - key '{key_id}' notifications",
-                "Emergency Access Startup Test"
+                "Emergency Access Startup Test",
             )
             )
 
 
             if not key_success:
             if not key_success:
@@ -616,6 +689,7 @@ def validate_setup():
     logger.info("System validation completed successfully")
     logger.info("System validation completed successfully")
     return True
     return True
 
 
+
 class ProductionRequestHandler(WSGIRequestHandler):
 class ProductionRequestHandler(WSGIRequestHandler):
     """Custom request handler with improved error handling"""
     """Custom request handler with improved error handling"""
 
 
@@ -627,6 +701,7 @@ class ProductionRequestHandler(WSGIRequestHandler):
         """Override to use our logger"""
         """Override to use our logger"""
         logger.info(f"HTTP: {format % args}")
         logger.info(f"HTTP: {format % args}")
 
 
+
 def main():
 def main():
     global config
     global config
     try:
     try:
@@ -650,25 +725,27 @@ def main():
         # Add Flask routes dynamically for each key
         # Add Flask routes dynamically for each key
         for key_id, key_config in config.keys.items():
         for key_id, key_config in config.keys.items():
             handler = create_key_handler(key_config)
             handler = create_key_handler(key_config)
-            endpoint_name = f'get_key_part_{key_id}'
-            app.add_url_rule(key_config.route, endpoint_name, handler, methods=['GET'])
-            logger.info(f"Registered authenticated key route for '{key_id}': {key_config.route}")
+            endpoint_name = f"get_key_part_{key_id}"
+            app.add_url_rule(key_config.route, endpoint_name, handler, methods=["GET"])
+            logger.info(
+                f"Registered authenticated key route for '{key_id}': {key_config.route}"
+            )
 
 
         # Add health check route
         # Add health check route
-        app.add_url_rule(config.health_route, 'health_check', health_check, methods=['GET'])
-
-
+        app.add_url_rule(
+            config.health_route, "health_check", health_check, methods=["GET"]
+        )
 
 
-        logger.info(f"Starting emergency access server on {config.server_host}:{config.server_port}")
+        logger.info(
+            f"Starting emergency access server on {config.server_host}:{config.server_port}"
+        )
         logger.info(f"Health route: {config.health_route}")
         logger.info(f"Health route: {config.health_route}")
         logger.info(f"Configured {len(config.keys)} key(s)")
         logger.info(f"Configured {len(config.keys)} key(s)")
 
 
-
-
-
         # Use production-ready server with better error handling
         # Use production-ready server with better error handling
         try:
         try:
             from waitress import serve
             from waitress import serve
+
             logger.info("Using Waitress WSGI server for production")
             logger.info("Using Waitress WSGI server for production")
             serve(
             serve(
                 app,
                 app,
@@ -677,17 +754,19 @@ def main():
                 threads=6,
                 threads=6,
                 connection_limit=100,
                 connection_limit=100,
                 cleanup_interval=30,
                 cleanup_interval=30,
-                channel_timeout=120
+                channel_timeout=120,
             )
             )
         except ImportError:
         except ImportError:
-            logger.critical("Waitress WSGI server not installed. This application must run under a production WSGI server such as 'waitress' or 'gunicorn'. Aborting startup.")
+            logger.critical(
+                "Waitress WSGI server not installed. This application must run under a production WSGI server such as 'waitress' or 'gunicorn'. Aborting startup."
+            )
             # Attempt to notify configured health backends about startup failure (best-effort)
             # Attempt to notify configured health backends about startup failure (best-effort)
             try:
             try:
-                if config and hasattr(config, 'ntfy_backends_health'):
+                if config and hasattr(config, "ntfy_backends_health"):
                     send_ntfy_notification(
                     send_ntfy_notification(
                         config.ntfy_backends_health,
                         config.ntfy_backends_health,
                         "🚨 Emergency Access server failed to start: waitress not installed",
                         "🚨 Emergency Access server failed to start: waitress not installed",
-                        "Emergency Access CRITICAL"
+                        "Emergency Access CRITICAL",
                     )
                     )
             except Exception:
             except Exception:
                 # Do not raise further - we are already aborting startup
                 # Do not raise further - we are already aborting startup
@@ -698,12 +777,12 @@ def main():
         logger.info("Received keyboard interrupt, shutting down gracefully")
         logger.info("Received keyboard interrupt, shutting down gracefully")
     except Exception as e:
     except Exception as e:
         logger.error(f"Failed to start server: {str(e)}")
         logger.error(f"Failed to start server: {str(e)}")
-        if config and hasattr(config, 'ntfy_backends_health'):
+        if config and hasattr(config, "ntfy_backends_health"):
             try:
             try:
                 send_ntfy_notification(
                 send_ntfy_notification(
                     config.ntfy_backends_health,
                     config.ntfy_backends_health,
                     f"🚨 Emergency Access server failed to start: {str(e)}",
                     f"🚨 Emergency Access server failed to start: {str(e)}",
-                    "Emergency Access CRITICAL"
+                    "Emergency Access CRITICAL",
                 )
                 )
             except Exception:
             except Exception:
                 pass
                 pass
@@ -711,5 +790,6 @@ def main():
     finally:
     finally:
         logger.info("Emergency Access server shutdown complete")
         logger.info("Emergency Access server shutdown complete")
 
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     main()
     main()