Dateien nach "/" hochladen

This commit is contained in:
Oliver Braasch committed 2026-09-23 22:17:07 +02:00
1 parent c8e055b7d9
commit 387779a4ef
1 file changed
+42 -7
+42 -7
View File
@@ -25,6 +25,7 @@ import tempfile
import threading import threading
import time import time
import urllib.request import urllib.request
from datetime import datetime
from functools import wraps from functools import wraps
from pathlib import Path from pathlib import Path
from urllib.parse import urlparse from urllib.parse import urlparse
@@ -216,11 +217,19 @@ def generate_report_summary(result: dict) -> str | None:
risk = result.get("risk_assessment") or {} risk = result.get("risk_assessment") or {}
issues = result.get("issues") or result.get("findings") or [] issues = result.get("issues") or result.get("findings") or []
components = result.get("components") or []
other_fields = {
k: v
for k, v in result.items()
if k not in ("issues", "findings", "components", "risk_assessment")
}
compact = { compact = {
"score": risk.get("score"), "score": risk.get("score"),
"severity": risk.get("severity"), "severity": risk.get("severity"),
"recommendation": risk.get("recommendation"), "recommendation": risk.get("recommendation"),
"total_issues": len(issues), "total_issues": len(issues),
"scanned_files": [c.get("path") or c.get("file") for c in components][:15],
"other_metadata": other_fields,
"top_issues": [ "top_issues": [
{ {
"severity": i.get("severity"), "severity": i.get("severity"),
@@ -234,12 +243,15 @@ def generate_report_summary(result: dict) -> str | None:
prompt = ( prompt = (
"Du bekommst das JSON-Ergebnis eines automatisierten Sicherheits-Scans für einen " "Du bekommst das JSON-Ergebnis eines automatisierten Sicherheits-Scans für einen "
"AI-Agent-Skill. Schreibe eine kurze, laienverständliche Zusammenfassung auf Deutsch " "AI-Agent-Skill. Schreibe auf Deutsch einen kurzen, laienverständlichen Bericht für "
"für jemanden ohne Security-Hintergrund, als Fließtext in 2-3 kurzen Absätzen " "jemanden ohne Security-Hintergrund, als Fließtext in 4 kurzen Absätzen, getrennt "
"(keine Überschriften, keine Code-Blöcke, keine Aufzählungszeichen):\n" "durch eine Leerzeile (keine Überschriften, keine Code-Blöcke, keine Aufzählungszeichen):\n"
"Absatz 1: Gesamteinschätzung in 1-2 Sätzen – wie riskant ist es grob?\n" "Absatz 1: Wofür dieser Skill laut den vorliegenden Daten (Dateinamen, Metadaten, "
"Absatz 2: Die wichtigsten Funde in einfachen Worten, ohne unerklärte Fachbegriffe.\n" "Fundtexte) gedacht ist – 1-2 Sätze. Falls der Zweck nicht erkennbar ist, schreibe "
"Absatz 3: Konkrete Handlungsempfehlung (bedenkenlos nutzbar / mit Vorsicht " "das ehrlich so.\n"
"Absatz 2: Gesamteinschätzung des Risikos in 1-2 Sätzen.\n"
"Absatz 3: Die wichtigsten Funde in einfachen Worten, ohne unerklärte Fachbegriffe.\n"
"Absatz 4: Konkrete Handlungsempfehlung (bedenkenlos nutzbar / mit Vorsicht "
"nutzbar / besser nicht installieren) und eine kurze Begründung warum.\n\n" "nutzbar / besser nicht installieren) und eine kurze Begründung warum.\n\n"
f"Scan-Ergebnis:\n{json.dumps(compact, ensure_ascii=False)}" f"Scan-Ergebnis:\n{json.dumps(compact, ensure_ascii=False)}"
) )
@@ -358,6 +370,21 @@ footer{
max-width:760px;margin:0 auto;padding:0 24px 40px;color:#9aa2ab;font-size:.85em; max-width:760px;margin:0 auto;padding:0 24px 40px;color:#9aa2ab;font-size:.85em;
} }
a{color:var(--orange)} a{color:var(--orange)}
.meta-line{color:var(--ink-soft);font-size:.85em;margin:-4px 0 20px}
.print-btn{
background:transparent;color:var(--ink);border:1px solid var(--border);
margin-top:0;padding:9px 16px;font-weight:600;
}
.print-btn:hover{background:#f3f4f6}
@media print{
body{background:#fff}
header{background:#0d0e10 !important;-webkit-print-color-adjust:exact;print-color-adjust:exact}
.no-print{display:none !important}
.card{box-shadow:none;border:1px solid #ccc;page-break-inside:avoid}
details{display:block !important}
details summary{display:none}
a{color:inherit;text-decoration:none}
}
</style> </style>
</head> </head>
<body> <body>
@@ -368,7 +395,7 @@ a{color:var(--orange)}
</div> </div>
</header> </header>
<main> <main>
<div class="card"> <div class="card no-print">
<form method="post" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
<label>Git-Repository-URL</label> <label>Git-Repository-URL</label>
<input type="text" name="git_url" placeholder="https://git.obraasch.de/olli1986/mein-skill"> <input type="text" name="git_url" placeholder="https://git.obraasch.de/olli1986/mein-skill">
@@ -385,6 +412,10 @@ a{color:var(--orange)}
</div> </div>
{% if result %} {% if result %}
<p class="meta-line">
Gescannt am {{ scanned_at }} &middot; Ziel: <code>{{ target_label }}</code>
&middot; <button type="button" class="print-btn no-print" onclick="window.print()">Als PDF speichern / drucken</button>
</p>
{% if summary_paragraphs %} {% if summary_paragraphs %}
<div class="card"> <div class="card">
<h3 class="sev-heading">Verständliche Zusammenfassung</h3> <h3 class="sev-heading">Verständliche Zusammenfassung</h3>
@@ -533,6 +564,8 @@ def index():
summary_text = generate_report_summary(result) summary_text = generate_report_summary(result)
summary_failed = summary_text is None summary_failed = summary_text is None
target_label = git_url if git_url else (zip_file.filename if zip_file else "-")
return render_template_string( return render_template_string(
PAGE, PAGE,
allow_llm=ALLOW_LLM, allow_llm=ALLOW_LLM,
@@ -543,6 +576,8 @@ def index():
summary_paragraphs=[p for p in (summary_text or "").split("\n\n") if p.strip()], summary_paragraphs=[p for p in (summary_text or "").split("\n\n") if p.strip()],
summary_failed=summary_failed, summary_failed=summary_failed,
result_json=json.dumps(result, indent=2, ensure_ascii=False), result_json=json.dumps(result, indent=2, ensure_ascii=False),
scanned_at=datetime.now().strftime("%d.%m.%Y %H:%M"),
target_label=target_label,
error=None, error=None,
) )
return render_template_string( return render_template_string(