""" 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"""
Remediation Guidance
{remediation_text}
""" 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...

"""