Commit Graph
2 Commits
Author SHA1 Message Date
RichardandClaude Opus 5 86b497bdbf Desktop: Passwortabfrage vor Konten, Geheimnissen und WebUI-Zugang
CI / Build & Tests (Linux) (push) Canceled after 0s
CI / Plattformneutralität & Hygiene (push) Canceled after 0s
Umsetzung von #567.

Entscheidung Richard, 13.09.2026: Geheimnisse verwalten wir ausschliesslich im
Desktop, und selbst dort erst nach zusaetzlicher Passwortabfrage.

Bisher sah und aenderte jeder, der die Desktop-Oberflaeche offen vor sich
hatte:
- Polymarket-Konten mit ApiKey, ApiSecret, ApiPassphrase und PrivateKey
- Master-Key, OpenRouter-Key, Watchdog-Token und Lizenzschluessel
- Mullvad-Account und Polygon-RPC-URL mit Alchemy-Key, offen im Editor
- das WebUI-Token, per "Anzeigen" lesbar

Jetzt gesperrt, bis entsperrt:
- Tab "Polymarket Accounts": Gesperrt stehen die Konten gar nicht im
  visuellen Baum. Das Raster bleibt leer, der Editor mit den Private Keys
  ebenfalls; nichts ist nur verdeckt.
- Master-Key erzeugen, OpenRouter-, Watchdog- und Lizenzschluessel setzen.
- Mullvad-Account und Polygon-RPC-URL: mit [SensitiveSetting] markiert und im
  Editor ausgeblendet.
- WebUI-Zugang: Gesperrt steht das Token nicht einmal maskiert im Feld.
  Speichern ist mitgesperrt, weil es den Feldinhalt als Token schreibt;
  gesperrt und leer haette es das Token geloescht.
- Frei bleiben Lizenzpruefung und Test-Heartbeat, weil sie keinen Schluessel
  zeigen.

Kern im Core (PolyTrader.Core.Security), weil nur dort testbar:
- SettingsPasswordStore: PBKDF2-HMAC-SHA256, 600 000 Iterationen, Salt, eigene
  Datei settings-password.json neben master.key, atomar geschrieben und nur fuer
  den Besitzer lesbar. Nicht in server_settings.xml, die seit #561 das WebUI
  mitschreibt. Ein vorhandenes Passwort wird nie ueberschrieben.
- SettingsLock:
  - erstes Festlegen mit Wiederholung und mindestens 10 Zeichen
  - zwei freie Fehlversuche, danach 5 s bis 5 min Wartezeit, in der auch das
    richtige Passwort nicht geprueft wird
  - Sperre nach 5 Minuten ohne geschuetzte Aktion und beim Verlassen der
    Einstellungen
  - eine unlesbare Passwortdatei entsperrt nie und gilt auch nicht still als
    "kein Passwort"
  - Protokoll ohne eingegebene Werte

Oberflaeche: PasswordDialog deklarativ in .axaml, Sperr-Leiste ueber den Tabs.
Die PBKDF2-Pruefung dauert etwa eine halbe Sekunde und laeuft nicht im
UI-Thread.

Grenzen:
- Die Sperre schuetzt gegen jemanden an einer entsperrten Desktop-Sitzung. Wer
  Dateizugriff hat, liest master.key selbst. Deshalb gibt es kein "Passwort
  vergessen": Wer settings-password.json loeschen kann, braucht keins.
- Die Wartezeit nach Fehlversuchen beginnt nach einem Neustart von vorn.
- "Datenbankeinstellungen": Eine Ansicht dafuer gibt es im Desktop nicht; die
  Verbindungszeichenfolge steht nur in appsettings.Local.json. Entsteht eine,
  gehoert sie hinter dieselbe Sperre.

Tests: 20 fuer Passwortdatei und Sperre (Festlegen, Fehlversuche, Wartezeit,
Leerlauf, unlesbare Datei, Aendern, Iterationszahl aus der Datei, Dateirechte)
und 5 fuer die Markierung der Geheimnisfelder. Die Oberflaeche selbst wird auf
der VM abgenommen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 14:34:32 +02:00
RichardandClaude Opus 5 4ba8149e64 Settings nach Avalonia - PropertyGrid durch kategorisierten Editor ersetzt
Der PropertyGrid-Ersatz ist EIN wiederverwendbares Steuerelement statt Handarbeit je Feld:
Controls/SettingsEditor zeigt ein beliebiges Einstellungsobjekt nach Richards Vorlage -
Kategorie-Ueberschrift, Beschriftung links, Feld rechts, Erklaerung klein darunter.

- SettingsModelBuilder liest die Attribute, die fuers PropertyGrid ohnehin gepflegt waren:
  [Category] gruppiert, [DisplayName] beschriftet, [Description] wird zum Hinweistext,
  [Browsable(false)] blendet aus (Watchdog-Token, Lizenzschluessel bleiben unsichtbar).
  Ergebnis fuer ServerSettings: 6 Abschnitte, 15 Felder - ohne eine Zeile Feld-Code.
- Layout-Regel gewahrt: WELCHE Felder es gibt, kommt als Daten; WIE ein Feld aussieht,
  steht deklarativ als DataTemplate je Feldtyp (Text/Zahl/Ja-Nein/Auswahl/Nur-Lese).
- Damit sind auch die drei restlichen PropertyGrid-Stellen (Account-Einstellungen,
  Master-Trader, ResolutionFarming) mit je einem Aufruf erledigt.

SettingsWindow: Server-Settings + Polymarket-Accounts, Master-Key erzeugen,
OpenRouter-Key/Watchdog-Token setzen, Test-Heartbeat. Rueckmeldungen laufen ueber die
Statuszeile statt ueber Dialoge - nur echte Entscheidungen bekommen einen Dialog
(neu: Views/DialogWindow fuer Hinweis/Rueckfrage/maskierte Eingabe, Avalonia hat keine MessageBox).

Nebenbei einen offenen Punkt der Linux-Analyse erledigt: Schluesseldateien (master.key,
openrouter.key) werden jetzt per File.SetUnixFileMode auf 600 gesetzt. Auf Linux legt
File.WriteAllText sonst mit ueblicher umask 644 an - weltweit lesbar.

Lizenzdialog bewusst NICHT portiert: haengt am alten LicenseLabrador-SDK, das mit der
Deploymentcenter-Anbindung (P3c) ohnehin ersetzt wird - waere Wegwerfarbeit.

Smoke-UI prueft jetzt zusaetzlich die Feldzahl des Editors: ein Fenster kann fehlerfrei
konstruieren und trotzdem leer sein, wenn die Attribute verlorengehen.

Verifiziert: Solution baut, 442 Tests gruen, --smoke-ui gruen (5 Fenster + Editor-Pruefung),
Linux-Publish laeuft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:55:47 +02:00