internal/pwpolicy: Validate ist eine schmale Regelschicht VOR dem bcrypt-Hashing aus IAM-02, kein eigenes Policy-Framework. Prueft Mindestlaenge, Zeichenklassen (Gross-/Kleinbuchstaben, Ziffern, Sonderzeichen je nach Policy) und eine eingebettete Sperrliste haeufig verwendeter Passwoerter (case-insensitive) — Akzeptanzkriterium 1 + 2. Store haelt die Richtlinie als eine Zeile je Tenant-Datenbank (Singleton, Modell C), DefaultPolicy() greift, solange kein Tenant eine eigene gesetzt hat. LoginAndCheckPolicy komponiert IAM-02s LoginService, OHNE ihn zu veraendern: der Login selbst schlaegt bei einem alten, nicht mehr konformen Passwort NICHT fehl (Akzeptanzkriterium 3 — kein rueckwirkendes Aussperren), die Funktion liefert zusaetzlich mustChangePassword=true. Die Pruefung ist nur im Login-Moment moeglich, da dort kurzzeitig das Klartext-Passwort vorliegt — der gespeicherte bcrypt-Hash laesst sich nicht rueckwirkend gegen eine neue Richtlinie pruefen. Pruefungen (ausgefuehrt auf root@192.168.1.131, go build/vet/test PASS): 1. Zu kurzes/zu einfaches Passwort bei Registrierung/Aenderung abgelehnt — TestValidate_RejectsTooShortOrSimple. PASS. 2. Passwort aus Sperrliste abgelehnt — TestValidate_RejectsBlocklistedPassword (inkl. Gross-/Kleinschreibung). PASS. 3. Bestehender Nutzer mit altem, nicht-konformem Passwort kann sich noch einloggen, wird aber zur Aenderung aufgefordert — TestLoginAndCheckPolicy_FlagsNonConformantExistingPassword: Login mit schwachem Altpasswort gelingt, mustChangePassword=true; mit konformem Passwort mustChangePassword=false. PASS. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
12 lines
571 B
SQL
12 lines
571 B
SQL
-- Passwort-Richtlinien je Tenant (IAM-14, siehe core-kanban/tickets/IAM-14.md).
|
|
-- Genau eine Zeile pro Tenant-Datenbank (Singleton-Muster, id fest auf true).
|
|
CREATE TABLE password_policy (
|
|
id BOOLEAN PRIMARY KEY DEFAULT true CHECK (id),
|
|
min_length INT NOT NULL DEFAULT 12,
|
|
require_upper BOOLEAN NOT NULL DEFAULT true,
|
|
require_lower BOOLEAN NOT NULL DEFAULT true,
|
|
require_digit BOOLEAN NOT NULL DEFAULT true,
|
|
require_special BOOLEAN NOT NULL DEFAULT false,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|