"""
UI Components for Security Auditor Gradio Interface
Generates HTML for badges, cards, and sections matching design mockups
"""
from typing import Dict, List
def create_severity_badge(severity: str, count: int = 0) -> str:
"""
Create severity badge as a visual indicator.
Args:
severity: CRITICAL, HIGH, MEDIUM, LOW, INFO
count: Number of findings
Returns:
HTML string for severity badge
"""
colors = {
"CRITICAL": {"bg": "#fef2f2", "text": "#dc2626", "border": "#fca5a5"},
"HIGH": {"bg": "#fff7ed", "text": "#ea580c", "border": "#fdba74"},
"MEDIUM": {"bg": "#fffbeb", "text": "#d97706", "border": "#fcd34d"},
"LOW": {"bg": "#f0fdfa", "text": "#0d9488", "border": "#5eead4"},
"INFO": {"bg": "#f9fafb", "text": "#6b7280", "border": "#d1d5db"}
}
color = colors.get(severity, colors["INFO"])
return f"""
{severity.capitalize()}
{count}
"""
def create_finding_card(vulnerability: Dict) -> str:
"""
Create HTML for vulnerability finding card.
Args:
vulnerability: Dict with name, severity, file_path, line_number,
description, cwe_id, cve_ids, remediation
Returns:
HTML string for finding card
"""
severity_colors = {
"CRITICAL": "#dc2626",
"HIGH": "#ea580c",
"MEDIUM": "#d97706",
"LOW": "#0d9488",
"INFO": "#6b7280"
}
severity_bg = {
"CRITICAL": "#fef2f2",
"HIGH": "#fff7ed",
"MEDIUM": "#fffbeb",
"LOW": "#f0fdfa",
"INFO": "#f9fafb"
}
severity = vulnerability.get('risk_level', 'INFO')
color = severity_colors.get(severity, severity_colors['INFO'])
bg = severity_bg.get(severity, severity_bg['INFO'])
# Build CWE/CVE tags
tags_html = ""
if vulnerability.get('cwe_id'):
tags_html += f"""
{vulnerability['cwe_id']}
"""
for cve in vulnerability.get('cve_ids', [])[:3]: # Show max 3 CVEs
tags_html += f"""
{cve}
"""
# Build remediation section
remediation_html = ""
if vulnerability.get('remediation'):
# Truncate very long remediation text
remediation_text = vulnerability['remediation']
if len(remediation_text) > 500:
remediation_text = remediation_text[:500] + "..."
remediation_html = f"""
"""
return f"""
{vulnerability.get('name', 'Unknown Vulnerability')}
{severity}
{tags_html}
{vulnerability.get('file_path', 'N/A')}:{vulnerability.get('line_number', 'N/A')}
{vulnerability.get('description', '')}
{remediation_html}
"""
def create_summary_section(scan_result: Dict) -> str:
"""
Create Analysis Summary section with proper alignment and sentence capitalization.
Args:
scan_result: Dict with target, files_scanned, scan_type, summary data
Returns:
HTML string for summary section
"""
summary = scan_result.get('summary', {})
# Metadata row - Fixed alignment with grid layout
metadata_html = f"""
Target
{scan_result.get('target', 'N/A')}
Files analyzed
{scan_result.get('files_scanned', 0)}
Total findings
{summary.get('total_vulnerabilities', 0)}
Analysis type
{scan_result.get('scan_type', 'local')}
"""
# Severity badges row
by_severity = summary.get('by_severity', {})
badges_html = f"""
{create_severity_badge('CRITICAL', by_severity.get('CRITICAL', 0))}
{create_severity_badge('HIGH', by_severity.get('HIGH', 0))}
{create_severity_badge('MEDIUM', by_severity.get('MEDIUM', 0))}
{create_severity_badge('LOW', by_severity.get('LOW', 0))}
{create_severity_badge('INFO', by_severity.get('INFO', 0))}
"""
return f"""
Analysis Summary
{metadata_html}
{badges_html}
"""
def create_empty_state() -> str:
"""
Create HTML for empty state (no results yet).
Returns:
HTML string for empty state
"""
return """
Ready to Scan
Upload files or enter a URL to begin security analysis
"""
def create_loading_state(message: str = "Scanning...") -> str:
"""
Create HTML for loading state.
Args:
message: Loading message to display
Returns:
HTML string for loading state
"""
return f"""
{message}
This may take a few moments...
"""