mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-08-25 06:55:17 +02:00
Add JSON integrity hash checks
This commit is contained in:
@@ -510,3 +510,46 @@ class AssetClaimDialog(tk.Toplevel):
|
||||
return
|
||||
self.destroy()
|
||||
self.on_created(str(result["claim"]["claim_id"]))
|
||||
|
||||
|
||||
class IntegrityWarningDialog(tk.Toplevel):
|
||||
def __init__(
|
||||
self,
|
||||
master: tk.Misc,
|
||||
*,
|
||||
title: str,
|
||||
warnings: list[str],
|
||||
on_confirm: Callable[[], None],
|
||||
):
|
||||
super().__init__(master)
|
||||
self.on_confirm = on_confirm
|
||||
self.title(title)
|
||||
self.transient(master.winfo_toplevel())
|
||||
self.resizable(False, False)
|
||||
self.warnings = warnings
|
||||
self._build_ui()
|
||||
self.bind("<Escape>", lambda _event: self.destroy())
|
||||
self.after_idle(self._activate_modal)
|
||||
|
||||
def _build_ui(self) -> None:
|
||||
frame = ttk.Frame(self, padding=18)
|
||||
frame.pack(fill="both", expand=True)
|
||||
message = (
|
||||
"ACHTUNG: Die zugehörigen JSON-Dateien wurden vermutlich extern geändert.\n\n"
|
||||
"Haben Sie alle Daten geprüft und soll der Hash jetzt aktualisiert werden?"
|
||||
)
|
||||
ttk.Label(frame, text=message, justify="left").grid(row=0, column=0, sticky="w")
|
||||
ttk.Label(frame, text="\n".join(f"• {item}" for item in self.warnings), style="Warning.TLabel", justify="left").grid(
|
||||
row=1, column=0, sticky="w", pady=(12, 0)
|
||||
)
|
||||
buttons = ttk.Frame(frame)
|
||||
buttons.grid(row=2, column=0, sticky="e", pady=(18, 0))
|
||||
ttk.Button(buttons, text="Nein", command=self.destroy).pack(side="left", padx=(0, 8))
|
||||
ttk.Button(buttons, text="Ja, bestätigen", style="Accent.TButton", command=self._confirm).pack(side="left")
|
||||
|
||||
def _activate_modal(self) -> None:
|
||||
_activate_modal_window(self)
|
||||
|
||||
def _confirm(self) -> None:
|
||||
self.destroy()
|
||||
self.on_confirm()
|
||||
|
||||
@@ -471,7 +471,7 @@ class MainWindow(ttk.Frame):
|
||||
tab = HousekeeperTab(
|
||||
self.notebook,
|
||||
self.findings,
|
||||
self.open_member,
|
||||
self._open_housekeeper_target,
|
||||
self.run_housekeeper,
|
||||
self.delete_housekeeper_task,
|
||||
lambda: self.tabs.close(key),
|
||||
@@ -545,12 +545,22 @@ class MainWindow(ttk.Frame):
|
||||
self.tabs.refresh_icons(self.icons)
|
||||
|
||||
def _show_validation_warning(self) -> None:
|
||||
display_errors = [item for item in self.validation_errors if "Hash fehlt oder stimmt nicht" not in item]
|
||||
if not display_errors:
|
||||
return
|
||||
messagebox.showwarning(
|
||||
"Datenprüfung",
|
||||
"Der Store enthält ungültige Akten:\n\n" + "\n".join(self.validation_errors[:12]),
|
||||
"Der Store enthält ungültige Akten:\n\n" + "\n".join(display_errors[:12]),
|
||||
parent=self,
|
||||
)
|
||||
|
||||
def _open_housekeeper_target(self, finding: HousekeeperFinding) -> None:
|
||||
if finding.target_type == "asset" and finding.asset_id:
|
||||
self.open_asset(finding.asset_id)
|
||||
return
|
||||
if finding.member_id:
|
||||
self.open_member(finding.member_id)
|
||||
|
||||
def _member_reference_label(self, member_id: str) -> str:
|
||||
if not member_id:
|
||||
return "—"
|
||||
|
||||
@@ -485,14 +485,14 @@ class HousekeeperTab(ttk.Frame):
|
||||
self,
|
||||
master: tk.Misc,
|
||||
findings: list[HousekeeperFinding],
|
||||
on_open_member: Callable[[str], None],
|
||||
on_open_target: Callable[[HousekeeperFinding], None],
|
||||
on_refresh: Callable[[], list[HousekeeperFinding]],
|
||||
on_delete: Callable[[str], list[HousekeeperFinding]],
|
||||
on_close: Callable[[], None],
|
||||
):
|
||||
super().__init__(master, padding=12)
|
||||
self.findings = findings
|
||||
self.on_open_member = on_open_member
|
||||
self.on_open_target = on_open_target
|
||||
self.on_refresh = on_refresh
|
||||
self.on_delete = on_delete
|
||||
self.on_close = on_close
|
||||
@@ -602,11 +602,15 @@ class HousekeeperTab(ttk.Frame):
|
||||
def _open_selected(self) -> None:
|
||||
selected = self.tree.selection()
|
||||
if selected:
|
||||
self.on_open_member(self.findings[int(selected[0])].member_id)
|
||||
self.on_open_target(self.findings[int(selected[0])])
|
||||
|
||||
|
||||
def _finding_details(finding: HousekeeperFinding) -> str:
|
||||
lines = [f"{finding.severity.upper()} · {finding.code}", finding.title]
|
||||
if finding.target_type == "asset" and finding.asset_id:
|
||||
lines.append(f"Asset: {finding.asset_id}")
|
||||
elif finding.member_id:
|
||||
lines.append(f"Mitglied: {finding.member_id}")
|
||||
if finding.key:
|
||||
lines.append(f"Key: {finding.key}")
|
||||
if finding.due_date:
|
||||
|
||||
Reference in New Issue
Block a user