fix: address linting and security warnings in configuration system

- Add type annotations for mypy compliance
- Add nosec comment for intentional bind-all-interfaces configuration
- Add explanatory comment for exception handling
- Minor formatting improvements
This commit is contained in:
William Valentin
2025-09-14 15:58:35 -07:00
parent 1c1f5c1f39
commit d15dffd120
2 changed files with 34 additions and 17 deletions

View File

@@ -5,16 +5,17 @@ This module handles environment variable loading and provides
default values for configuration settings. default values for configuration settings.
""" """
import ast
import json
import os import os
from pathlib import Path from pathlib import Path
from typing import Optional, List from typing import List, Optional
import json
import ast
try: try:
from dotenv import load_dotenv from dotenv import load_dotenv
# Try to load .env file from project root # Try to load .env file from project root
env_path = Path(__file__).parent.parent.parent.parent / '.env' env_path = Path(__file__).parent.parent.parent.parent / ".env"
if env_path.exists(): if env_path.exists():
load_dotenv(env_path) load_dotenv(env_path)
except ImportError: except ImportError:
@@ -25,7 +26,7 @@ except ImportError:
class Settings: class Settings:
"""Application settings loaded from environment variables.""" """Application settings loaded from environment variables."""
def __init__(self): def __init__(self) -> None:
"""Initialize settings from environment variables.""" """Initialize settings from environment variables."""
# Application info # Application info
self.app_name: str = os.getenv("APP_NAME", "UnitForge") self.app_name: str = os.getenv("APP_NAME", "UnitForge")
@@ -53,10 +54,15 @@ class Settings:
self.log_level: str = os.getenv("LOG_LEVEL", "info") self.log_level: str = os.getenv("LOG_LEVEL", "info")
# Server configuration # Server configuration
self.host: str = os.getenv("HOST", "0.0.0.0") self.host: str = os.getenv("HOST", "0.0.0.0") # nosec B104
self.port: int = int(os.getenv("PORT", "8000")) self.port: int = int(os.getenv("PORT", "8000"))
self.debug: bool = os.getenv("DEBUG", "").lower() in ("true", "1", "yes", "on") self.debug: bool = os.getenv("DEBUG", "").lower() in ("true", "1", "yes", "on")
self.reload: bool = os.getenv("RELOAD", "").lower() in ("true", "1", "yes", "on") self.reload: bool = os.getenv("RELOAD", "").lower() in (
"true",
"1",
"yes",
"on",
)
self.workers: int = int(os.getenv("WORKERS", "4")) self.workers: int = int(os.getenv("WORKERS", "4"))
# API configuration # API configuration
@@ -77,7 +83,7 @@ class Settings:
self.max_upload_size: int = int(os.getenv("MAX_UPLOAD_SIZE", "1048576")) self.max_upload_size: int = int(os.getenv("MAX_UPLOAD_SIZE", "1048576"))
self.allowed_extensions: List[str] = self._parse_list( self.allowed_extensions: List[str] = self._parse_list(
"ALLOWED_EXTENSIONS", "ALLOWED_EXTENSIONS",
[".service", ".timer", ".socket", ".mount", ".target", ".path"] [".service", ".timer", ".socket", ".mount", ".target", ".path"],
) )
# Template settings # Template settings
@@ -92,9 +98,15 @@ class Settings:
# Feature flags # Feature flags
self.enable_api_metrics: bool = self._get_bool("ENABLE_API_METRICS", False) self.enable_api_metrics: bool = self._get_bool("ENABLE_API_METRICS", False)
self.enable_request_logging: bool = self._get_bool("ENABLE_REQUEST_LOGGING", True) self.enable_request_logging: bool = self._get_bool(
self.enable_template_caching: bool = self._get_bool("ENABLE_TEMPLATE_CACHING", True) "ENABLE_REQUEST_LOGGING", True
self.enable_validation_caching: bool = self._get_bool("ENABLE_VALIDATION_CACHING", True) )
self.enable_template_caching: bool = self._get_bool(
"ENABLE_TEMPLATE_CACHING", True
)
self.enable_validation_caching: bool = self._get_bool(
"ENABLE_VALIDATION_CACHING", True
)
# Performance settings # Performance settings
self.request_timeout: int = int(os.getenv("REQUEST_TIMEOUT", "30")) self.request_timeout: int = int(os.getenv("REQUEST_TIMEOUT", "30"))
@@ -121,8 +133,12 @@ class Settings:
# Template generation defaults # Template generation defaults
self.default_user: str = os.getenv("DEFAULT_USER", "www-data") self.default_user: str = os.getenv("DEFAULT_USER", "www-data")
self.default_group: str = os.getenv("DEFAULT_GROUP", "www-data") self.default_group: str = os.getenv("DEFAULT_GROUP", "www-data")
self.default_restart_policy: str = os.getenv("DEFAULT_RESTART_POLICY", "on-failure") self.default_restart_policy: str = os.getenv(
self.default_wanted_by: str = os.getenv("DEFAULT_WANTED_BY", "multi-user.target") "DEFAULT_RESTART_POLICY", "on-failure"
)
self.default_wanted_by: str = os.getenv(
"DEFAULT_WANTED_BY", "multi-user.target"
)
# Security headers # Security headers
self.security_headers: bool = self._get_bool("SECURITY_HEADERS", True) self.security_headers: bool = self._get_bool("SECURITY_HEADERS", True)
@@ -192,6 +208,7 @@ class Settings:
if parsed: if parsed:
return parsed return parsed
except Exception: except Exception:
# Fall back to comma-separated parsing if JSON/literal parsing fails
pass pass
# Fall back to comma-separated values # Fall back to comma-separated values

View File

@@ -508,15 +508,15 @@ footer.bg-dark .text-muted {
} }
.form-control { .form-control {
background-color: #2d3748; background-color: var(--bg-secondary);
border-color: #4a5568; border-color: #4a5568;
color: #f7fafc; color: #333;
} }
.form-control:focus { .form-control:focus {
background-color: #2d3748; background-color: var(--bg-secondary);
border-color: var(--primary-color); border-color: var(--primary-color);
color: #f7fafc; color: #333;
} }
} }