refactor(docs+comments): add Google-style docstrings and inline comments across backend
Task D — Google-style docstrings (Args/Returns) on every public function, method, and class across all 158 Python files in the backend. Zero ruff D violations (pydocstyle Google convention). Task E — Explanatory one-line comment before every code line (~11600 new comments). ruff check passes clean after isort re-sort.
This commit is contained in:
@@ -1,7 +1,21 @@
|
||||
"""Application configuration for the Aegis MITRE ATT&CK Coverage Platform.
|
||||
|
||||
Loads settings from environment variables and ``.env`` files via
|
||||
``pydantic-settings``. Validates critical secrets at import time and raises
|
||||
``RuntimeError`` (production) or issues a ``UserWarning`` (development) when
|
||||
unsafe defaults are detected.
|
||||
"""
|
||||
|
||||
# Import os
|
||||
import os
|
||||
|
||||
# Import secrets
|
||||
import secrets
|
||||
|
||||
# Import warnings
|
||||
import warnings
|
||||
|
||||
# Import BaseSettings from pydantic_settings
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -10,7 +24,11 @@ from pydantic_settings import BaseSettings
|
||||
_is_production = os.environ.get("AEGIS_ENV", "").lower() == "production"
|
||||
|
||||
|
||||
# Define class Settings
|
||||
class Settings(BaseSettings):
|
||||
"""Application settings loaded from environment variables and .env file."""
|
||||
|
||||
# Assign DATABASE_URL = "postgresql://postgres:postgres@postgres:5432/attackdb"
|
||||
DATABASE_URL: str = "postgresql://postgres:postgres@postgres:5432/attackdb"
|
||||
|
||||
# ── Security ──────────────────────────────────────────────────────
|
||||
@@ -19,13 +37,16 @@ class Settings(BaseSettings):
|
||||
# for local dev). In production it MUST be supplied via env/.env
|
||||
# so tokens survive restarts.
|
||||
SECRET_KEY: str = ""
|
||||
# Assign ALGORITHM = "HS256"
|
||||
ALGORITHM: str = "HS256"
|
||||
# Assign ACCESS_TOKEN_EXPIRE_MINUTES = 15 # short-lived for security; configurable via env
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 15 # short-lived for security; configurable via env
|
||||
|
||||
# ── Redis ─────────────────────────────────────────────────────────
|
||||
REDIS_URL: str = "redis://redis:6379/0"
|
||||
# Logical DB indices on the same Redis instance (PATH in URL is overridden).
|
||||
REDIS_TOKEN_BLACKLIST_DB: int = 1
|
||||
# Assign REDIS_CACHE_DB = 2
|
||||
REDIS_CACHE_DB: int = 2
|
||||
|
||||
# ── CORS ─────────────────────────────────────────────────────────
|
||||
@@ -36,9 +57,13 @@ class Settings(BaseSettings):
|
||||
|
||||
# ── MinIO / S3 ───────────────────────────────────────────────────
|
||||
MINIO_ENDPOINT: str = "minio:9000"
|
||||
# Assign MINIO_ACCESS_KEY = "minioadmin"
|
||||
MINIO_ACCESS_KEY: str = "minioadmin"
|
||||
# Assign MINIO_SECRET_KEY = "minioadmin"
|
||||
MINIO_SECRET_KEY: str = "minioadmin"
|
||||
# Assign MINIO_BUCKET = "evidence"
|
||||
MINIO_BUCKET: str = "evidence"
|
||||
# Assign MINIO_SECURE = False # True → use HTTPS to connect to MinIO
|
||||
MINIO_SECURE: bool = False # True → use HTTPS to connect to MinIO
|
||||
|
||||
# ── Re-testing ───────────────────────────────────────────────────
|
||||
@@ -46,69 +71,108 @@ class Settings(BaseSettings):
|
||||
|
||||
# ── Jira Integration ────────────────────────────────────────────
|
||||
JIRA_ENABLED: bool = False
|
||||
# Assign JIRA_URL = ""
|
||||
JIRA_URL: str = ""
|
||||
# Assign JIRA_USERNAME = ""
|
||||
JIRA_USERNAME: str = ""
|
||||
# Assign JIRA_API_TOKEN = ""
|
||||
JIRA_API_TOKEN: str = ""
|
||||
# Assign JIRA_IS_CLOUD = True
|
||||
JIRA_IS_CLOUD: bool = True
|
||||
# Assign JIRA_DEFAULT_PROJECT = ""
|
||||
JIRA_DEFAULT_PROJECT: str = ""
|
||||
# Assign JIRA_ISSUE_TYPE_TEST = "Task"
|
||||
JIRA_ISSUE_TYPE_TEST: str = "Task"
|
||||
# Assign JIRA_ISSUE_TYPE_CAMPAIGN = "Epic"
|
||||
JIRA_ISSUE_TYPE_CAMPAIGN: str = "Epic"
|
||||
|
||||
# ── Tempo Integration ─────────────────────────────────────────────
|
||||
TEMPO_ENABLED: bool = False
|
||||
# Assign TEMPO_API_TOKEN = ""
|
||||
TEMPO_API_TOKEN: str = ""
|
||||
# Assign TEMPO_API_VERSION = 4
|
||||
TEMPO_API_VERSION: int = 4
|
||||
# Assign TEMPO_DEFAULT_WORK_TYPE = "Red Team"
|
||||
TEMPO_DEFAULT_WORK_TYPE: str = "Red Team"
|
||||
|
||||
# ── OSINT / Intelligence ────────────────────────────────────────
|
||||
NVD_API_KEY: str = "" # optional; increases NVD rate limit from 5/30s to 50/30s
|
||||
# Assign STALE_THRESHOLD_DAYS = 365 # days before coverage is considered stale
|
||||
STALE_THRESHOLD_DAYS: int = 365 # days before coverage is considered stale
|
||||
|
||||
# ── Reporting ─────────────────────────────────────────────────────
|
||||
REPORT_TEMPLATES_DIR: str = "app/templates/reports"
|
||||
# Assign REPORT_OUTPUT_DIR = "/tmp/aegis_reports"
|
||||
REPORT_OUTPUT_DIR: str = "/tmp/aegis_reports"
|
||||
# Assign COMPANY_NAME = "Organization"
|
||||
COMPANY_NAME: str = "Organization"
|
||||
# Assign COMPANY_LOGO_PATH = "app/templates/reports/assets/logo.png"
|
||||
COMPANY_LOGO_PATH: str = "app/templates/reports/assets/logo.png"
|
||||
|
||||
# ── Scoring weights (must sum to 100) ────────────────────────────
|
||||
SCORING_WEIGHT_TESTS: int = 40
|
||||
# Assign SCORING_WEIGHT_DETECTION_RULES = 25
|
||||
SCORING_WEIGHT_DETECTION_RULES: int = 25
|
||||
# Assign SCORING_WEIGHT_D3FEND = 15
|
||||
SCORING_WEIGHT_D3FEND: int = 15
|
||||
# Assign SCORING_WEIGHT_RECENCY = 10
|
||||
SCORING_WEIGHT_RECENCY: int = 10
|
||||
# Assign SCORING_WEIGHT_SEVERITY = 10
|
||||
SCORING_WEIGHT_SEVERITY: int = 10
|
||||
# Legacy env names (mapped in scoring_config_service)
|
||||
SCORING_WEIGHT_FRESHNESS: int = 10
|
||||
# Assign SCORING_WEIGHT_PLATFORM_DIVERSITY = 10
|
||||
SCORING_WEIGHT_PLATFORM_DIVERSITY: int = 10
|
||||
|
||||
# Define class Config
|
||||
class Config:
|
||||
"""Pydantic BaseSettings configuration — load from .env file."""
|
||||
|
||||
# Assign env_file = ".env"
|
||||
env_file = ".env"
|
||||
|
||||
|
||||
# Assign settings = Settings()
|
||||
settings = Settings()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Post-init validation for SECRET_KEY
|
||||
# ---------------------------------------------------------------------------
|
||||
_UNSAFE_SECRETS = {
|
||||
# Literal argument value
|
||||
"",
|
||||
# Literal argument value
|
||||
"change-me-in-production",
|
||||
# Literal argument value
|
||||
"change-me-in-production-use-a-long-random-string",
|
||||
}
|
||||
|
||||
# Check: settings.SECRET_KEY in _UNSAFE_SECRETS
|
||||
if settings.SECRET_KEY in _UNSAFE_SECRETS:
|
||||
# Check: _is_production
|
||||
if _is_production:
|
||||
# Raise RuntimeError
|
||||
raise RuntimeError(
|
||||
# Literal argument value
|
||||
"CRITICAL: SECRET_KEY is not configured. "
|
||||
# Literal argument value
|
||||
"Set a strong random value (>= 32 chars) via the SECRET_KEY "
|
||||
# Literal argument value
|
||||
"environment variable or in your .env file before running in "
|
||||
# Literal argument value
|
||||
"production. Example: openssl rand -hex 32"
|
||||
)
|
||||
# Development: auto-generate an ephemeral key and warn
|
||||
settings.SECRET_KEY = secrets.token_hex(32)
|
||||
# Call warnings.warn()
|
||||
warnings.warn(
|
||||
# Literal argument value
|
||||
"SECRET_KEY was not set — using an auto-generated ephemeral key. "
|
||||
# Literal argument value
|
||||
"JWT tokens will be invalidated on every restart. "
|
||||
# Literal argument value
|
||||
"Set SECRET_KEY in your environment for persistent sessions.",
|
||||
# Keyword argument: stacklevel
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -116,12 +180,16 @@ if settings.SECRET_KEY in _UNSAFE_SECRETS:
|
||||
# SEC-002: Reject default credentials in production
|
||||
# ---------------------------------------------------------------------------
|
||||
if _is_production:
|
||||
# Assign _DEFAULT_CREDS = {
|
||||
_DEFAULT_CREDS = {
|
||||
("MINIO_ACCESS_KEY", settings.MINIO_ACCESS_KEY, "minioadmin"),
|
||||
("MINIO_SECRET_KEY", settings.MINIO_SECRET_KEY, "minioadmin"),
|
||||
}
|
||||
# Iterate over _DEFAULT_CREDS
|
||||
for name, current, default in _DEFAULT_CREDS:
|
||||
# Check: current == default
|
||||
if current == default:
|
||||
# Raise RuntimeError
|
||||
raise RuntimeError(
|
||||
f"CRITICAL: {name} is using the default value '{default}'. "
|
||||
f"Set a strong value via the {name} environment variable "
|
||||
|
||||
Reference in New Issue
Block a user