Die Selbstpruefung ruft die Funktion nicht mehr auf
Some checks failed
CI / Migrationen auf leerer Datenbank (push) Has been cancelled
CI / Lint, Typen, Tests, Build (push) Has been cancelled

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.
This commit is contained in:
2026-09-24 12:33:19 +02:00
parent 6d006e55fe
commit 520242e3c3

View File

@@ -141,6 +141,7 @@ grant execute on function public.om_reporting_lines(p_as_of date) to alpenwerk_a
do $$ do $$
declare declare
v_def text := pg_get_functiondef('public.om_reporting_lines(date)'::regprocedure); v_def text := pg_get_functiondef('public.om_reporting_lines(date)'::regprocedure);
v_teil text;
begin begin
-- Ohne die Prüfung in der ersten Zeile wäre aus der Funktion ein Loch im -- 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. -- 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.'; raise exception 'om_reporting_lines hat keinen festen search_path — bei security definer ist das Pflicht.';
end if; end if;
-- Und das Ergebnis bleibt, was es war: eine Zeile je laufender Besetzung. -- Der Körper wird **gelesen, nicht ausgeführt**. Ein Aufruf hier wäre der
if (select count(*) from om_reporting_lines(current_date)) -- erste Fehlversuch dieser Migration gewesen: sie läuft als Administrator
<> (select count(*) -- ohne `app.user_id`, und require_hr_admin() weist sie damit zu Recht ab.
from position_assignments pa -- Eine Selbstprüfung darf nichts aufrufen, was einen angemeldeten
join om_positions p on p.id = pa.position_id -- Anwendungsbenutzer voraussetzt.
where pa.valid_from <= current_date and (pa.valid_to is null or pa.valid_to > current_date) foreach v_teil in array array[
and p.valid_from <= current_date and (p.valid_to is null or p.valid_to > current_date)) then 'holder as', 'chief as', 'ancestry as', 'base as',
raise exception 'om_reporting_lines liefert nicht mehr eine Zeile je laufender Besetzung.'; 'formal_manager_id', 'acting_manager_id', 'order by a.depth'
end if; ] 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 end
$$; $$;