95 lines
3.2 KiB
TypeScript
95 lines
3.2 KiB
TypeScript
/**
|
|
* Die Sperren der Anwendungsrolle — nach einer Wiederherstellung.
|
|
*
|
|
* Hintergrund, und er ist unerwartet:
|
|
*
|
|
* Beim ersten Start richtet `docker/postgres/10-init-app-role.sh` eine
|
|
* Vorgabeprivilegierung ein — jede künftig angelegte Tabelle bekommt
|
|
* automatisch alle Rechte für `florian_app`. Das ist im Betrieb genau richtig:
|
|
* eine neue Migration soll nicht daran scheitern, dass jemand vergessen hat,
|
|
* Rechte zu vergeben.
|
|
*
|
|
* `pg_restore` legt die Tabellen aber ebenfalls neu an. Die Vorgabe greift
|
|
* also auch dort — und die `GRANT`-Anweisungen aus dem Dump können nur
|
|
* hinzufügen, nie wegnehmen. Nach einer Wiederherstellung stünde die
|
|
* Anwendungsrolle damit wieder mit allen Rechten da: sie dürfte das Audit-Log
|
|
* ändern, Wiki-Fassungen löschen, Kiosk-Vorgänge umschreiben.
|
|
*
|
|
* Nichts an der Anwendung würde darauf hinweisen. Die Unveränderlichkeit, auf
|
|
* der jeder Nachweis gegenüber der Unfallkasse beruht, wäre stillschweigend
|
|
* weg — bis jemand danach fragt.
|
|
*
|
|
* Gefunden haben das die Datenbanktests nach der ersten Rückspielprobe.
|
|
* Deshalb gibt es diese Datei: **eine** Liste, aus der sowohl das
|
|
* Wiederherstellen als auch das Prüfen der Sperren entsteht. Zwei Listen
|
|
* wären zwei Wahrheiten.
|
|
*/
|
|
|
|
/** Tabelle → Rechte, die `florian_app` NICHT haben darf, mit Begründung. */
|
|
export const SPERREN: Array<{ tabelle: string; rechte: string[]; grund: string }> = [
|
|
{
|
|
tabelle: "berechtigung",
|
|
rechte: ["INSERT", "UPDATE", "DELETE"],
|
|
grund: "systemweiter Rechtekatalog — nur lesbar",
|
|
},
|
|
{
|
|
tabelle: "audit_log",
|
|
rechte: ["UPDATE", "DELETE"],
|
|
grund: "append-only; das Löschen geht nur im Aufbewahrungslauf",
|
|
},
|
|
{
|
|
tabelle: "kiosk_vorgang",
|
|
rechte: ["UPDATE", "DELETE"],
|
|
grund: "übermittelte Terminalvorgänge sind unveränderlich",
|
|
},
|
|
{
|
|
tabelle: "druckmessung",
|
|
rechte: ["UPDATE", "DELETE"],
|
|
grund: "Atemschutzüberwachung — Druckwerte werden nie korrigiert",
|
|
},
|
|
{
|
|
tabelle: "atemschutz_ereignis",
|
|
rechte: ["UPDATE", "DELETE"],
|
|
grund: "wie oben: der Verlauf einer Überwachung bleibt, wie er war",
|
|
},
|
|
{
|
|
tabelle: "benachrichtigung",
|
|
rechte: ["DELETE"],
|
|
grund: "was zugestellt wurde, bleibt nachweisbar",
|
|
},
|
|
{
|
|
tabelle: "ki_vorgang",
|
|
rechte: ["DELETE"],
|
|
grund: "das KI-Protokoll belegt, was die Maschine getan hat",
|
|
},
|
|
{
|
|
tabelle: "wikiversion",
|
|
rechte: ["UPDATE", "DELETE"],
|
|
grund: "jede Fassung einer Wiki-Seite bleibt erhalten",
|
|
},
|
|
{
|
|
tabelle: "kassenabschluss",
|
|
rechte: ["DELETE"],
|
|
grund: "ein festgeschriebener Abschluss lässt sich nicht wegräumen",
|
|
},
|
|
{
|
|
tabelle: "benutzer",
|
|
rechte: ["INSERT", "DELETE"],
|
|
grund: "Konten entstehen und vergehen über den Systemzugang",
|
|
},
|
|
];
|
|
|
|
/** Die SQL-Anweisungen, die die Sperren wiederherstellen. */
|
|
export function sperrenSql(): string[] {
|
|
return SPERREN.map(
|
|
({ tabelle, rechte }) => `REVOKE ${rechte.join(", ")} ON "${tabelle}" FROM florian_app`,
|
|
);
|
|
}
|
|
|
|
/** Alle Kombinationen, die nach der Wiederherstellung fehlen müssen. */
|
|
export function verboteneRechte(): Array<{ tabelle: string; recht: string }> {
|
|
return SPERREN.flatMap(({ tabelle, rechte }) =>
|
|
rechte.map((recht) => ({ tabelle, recht })),
|
|
);
|
|
}
|