From 520242e3c37a0f05fffb76420a14cf443249e5e2 Mon Sep 17 00:00:00 2001 From: Andrei Laas Date: Thu, 24 Sep 2026 12:33:19 +0200 Subject: [PATCH] Die Selbstpruefung ruft die Funktion nicht mehr auf Die Migration ist an ihrer eigenen Pruefung gescheitert: FEHLGESCHLAGEN 20260924220000_reporting_lines_ohne_zeilenschutz.sql Nicht berechtigt: nur aktive HR-Benutzer:innen duerfen diese Aktion ausfuehren. Die Pruefung verglich die Zeilenzahl der neuen Funktion mit der Zahl der laufenden Besetzungen -- und rief sie dafuer auf. Die Funktion verlangt seit dieser Migration HR-Rechte, die Migration selbst laeuft aber als Administrator ohne app.user_id. require_hr_admin() hat sie also zu Recht abgewiesen. Nichts wurde eingespielt, die Transaktion ist vollstaendig zurueckgerollt. Jetzt wird der Koerper gelesen statt ausgefuehrt: geprueft wird, dass require_hr_admin, security definer und der search_path stehen und dass die Bestandteile der Abfrage vollzaehlig uebertragen sind. Eine Selbstpruefung darf nichts aufrufen, was einen angemeldeten Anwendungsbenutzer voraussetzt. --- ...0000_reporting_lines_ohne_zeilenschutz.sql | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/db/migrations/20260924220000_reporting_lines_ohne_zeilenschutz.sql b/db/migrations/20260924220000_reporting_lines_ohne_zeilenschutz.sql index 9b1046f..a76a6ee 100644 --- a/db/migrations/20260924220000_reporting_lines_ohne_zeilenschutz.sql +++ b/db/migrations/20260924220000_reporting_lines_ohne_zeilenschutz.sql @@ -141,6 +141,7 @@ grant execute on function public.om_reporting_lines(p_as_of date) to alpenwerk_a do $$ declare v_def text := pg_get_functiondef('public.om_reporting_lines(date)'::regprocedure); + v_teil text; begin -- Ohne die Prüfung in der ersten Zeile wäre aus der Funktion ein Loch im -- Zeilenschutz geworden: security definer liest an den Policies vorbei. @@ -154,14 +155,18 @@ begin raise exception 'om_reporting_lines hat keinen festen search_path — bei security definer ist das Pflicht.'; end if; - -- Und das Ergebnis bleibt, was es war: eine Zeile je laufender Besetzung. - if (select count(*) from om_reporting_lines(current_date)) - <> (select count(*) - from position_assignments pa - join om_positions p on p.id = pa.position_id - where pa.valid_from <= current_date and (pa.valid_to is null or pa.valid_to > current_date) - and p.valid_from <= current_date and (p.valid_to is null or p.valid_to > current_date)) then - raise exception 'om_reporting_lines liefert nicht mehr eine Zeile je laufender Besetzung.'; - end if; + -- Der Körper wird **gelesen, nicht ausgeführt**. Ein Aufruf hier wäre der + -- erste Fehlversuch dieser Migration gewesen: sie läuft als Administrator + -- ohne `app.user_id`, und require_hr_admin() weist sie damit zu Recht ab. + -- Eine Selbstprüfung darf nichts aufrufen, was einen angemeldeten + -- Anwendungsbenutzer voraussetzt. + foreach v_teil in array array[ + 'holder as', 'chief as', 'ancestry as', 'base as', + 'formal_manager_id', 'acting_manager_id', 'order by a.depth' + ] loop + if position(v_teil in v_def) = 0 then + raise exception 'Im Koerper fehlt „%" — beim Uebertragen ist etwas verlorengegangen.', v_teil; + end if; + end loop; end $$;