-- --------------------------------------------------------------------------- -- HANDGESCHRIEBEN. Prisma erzeugt hier zusaetzlich Loeschbefehle fuer die -- zusammengesetzten Fremdschluessel (Mandantengrenze), die Trigramm-Indizes -- (Archivsuche), die partiellen eindeutigen Indizes und alle Trigger: es kennt -- sie nicht, weil sie sich im Schema nicht ausdruecken lassen. Diese -- Loeschbefehle sind bewusst gestrichen. -- -- tests/datenbankregeln.test.ts prueft, dass alle diese Objekte vorhanden sind – -- ein versehentlich stehengelassener Loeschbefehl faellt dort sofort auf. -- --------------------------------------------------------------------------- -- SCIM-Endpunkt als Alternative zum Abgleich (#029). ALTER TABLE "Verzeichnisquelle" ADD COLUMN "scimTokenHash" TEXT, ADD COLUMN "scimTokenGesetztAm" TIMESTAMP(3), ADD COLUMN "letzteScimZustellungAm" TIMESTAMP(3); /* * **Der CHECK je Art wird ersetzt, nicht ergaenzt.** * * Bis #028 liess er `SCIM` ohne jede Bedingung durch — die Art hatte noch keine * Felder. Jetzt hat sie welche, und dieselbe Regel gilt in beide Richtungen: was * eine Art braucht, und was sie **nicht** haben darf. Ohne den zweiten Teil * waere eine SCIM-Quelle mit `basisDn` moeglich, und bei der koennte niemand * mehr sagen, was gilt. * * **Das Token steht nicht in der Bedingung.** Eine SCIM-Quelle entsteht ohne * Token und bekommt es danach — der Administrator legt die Quelle an, erzeugt * das Token und traegt es beim Anbieter ein. Eine Quelle ohne Token nimmt * nichts an: der Handler findet keinen Hash zum Vergleichen und antwortet mit * 401. Das ist der richtige Zustand, nicht ein verbotener. */ ALTER TABLE "Verzeichnisquelle" DROP CONSTRAINT "Verzeichnisquelle_felder_je_art"; ALTER TABLE "Verzeichnisquelle" ADD CONSTRAINT "Verzeichnisquelle_felder_je_art" CHECK ( ("art" = 'LDAP' AND "url" IS NOT NULL AND "bindDn" IS NOT NULL AND "bindPasswortVerschluesselt" IS NOT NULL AND "basisDn" IS NOT NULL AND "filter" IS NOT NULL AND "tenantId" IS NULL AND "clientId" IS NULL AND "clientSecretVerschluesselt" IS NULL AND "scimTokenHash" IS NULL) OR ("art" = 'GRAPH' AND "tenantId" IS NOT NULL AND "clientId" IS NOT NULL AND "clientSecretVerschluesselt" IS NOT NULL AND "url" IS NULL AND "bindDn" IS NULL AND "bindPasswortVerschluesselt" IS NULL AND "basisDn" IS NULL AND "filter" IS NULL AND "scimTokenHash" IS NULL) OR ("art" = 'SCIM' AND "url" IS NULL AND "bindDn" IS NULL AND "bindPasswortVerschluesselt" IS NULL AND "basisDn" IS NULL AND "filter" IS NULL AND "tenantId" IS NULL AND "clientId" IS NULL AND "clientSecretVerschluesselt" IS NULL) ); -- Das Token als argon2-Hash, nicht im Klartext. `$argon2` ist das Praefix der -- Bibliothek; ein Token, das versehentlich roh gespeichert wird, faellt hier auf. ALTER TABLE "Verzeichnisquelle" ADD CONSTRAINT "Verzeichnisquelle_scimtoken_gehasht" CHECK ("scimTokenHash" IS NULL OR "scimTokenHash" LIKE '$argon2%'); -- Ein Token gehoert zu einem Zeitpunkt, in beide Richtungen: ohne ihn liesse -- sich nicht sagen, seit wann es gilt, und ein Zeitpunkt ohne Token behauptete -- ein Token, das es nicht gibt. ALTER TABLE "Verzeichnisquelle" ADD CONSTRAINT "Verzeichnisquelle_scimtoken_mit_zeitpunkt" CHECK (("scimTokenHash" IS NULL) = ("scimTokenGesetztAm" IS NULL)); /* * Der Index, auf dem der SCIM-Handler arbeitet. * * Jede Anfrage bringt ein Token mit und muss daraus die Quelle finden. Ein Hash * laesst sich nicht nachschlagen — argon2 ist je Aufruf anders —, also werden * die SCIM-Quellen gelesen und einzeln geprueft. Bei zwei Quellen ist das * gleichgueltig; der Index haelt es auch bei zwanzig schnell und sagt zugleich, * dass hier nach `art` gesucht wird. */ CREATE INDEX "Verzeichnisquelle_art_aktiv_idx" ON "Verzeichnisquelle"("art", "aktiv"); /* * Gegenprobe: der ersetzte CHECK muss die bestehenden Zeilen noch zulassen. * `ALTER TABLE ... ADD CONSTRAINT` prueft das von sich aus — aber eine * Migration, die ihre eigene Annahme nicht nachrechnet, ist genau die Art * Zusage, die dieses Projekt teuer bezahlt hat. */ DO $$ DECLARE anzahl INTEGER; BEGIN SELECT count(*) INTO anzahl FROM "Verzeichnisquelle" WHERE "art" NOT IN ('LDAP', 'GRAPH', 'SCIM'); IF anzahl > 0 THEN RAISE EXCEPTION 'Unerwartete Quellenart in % Zeilen.', anzahl; END IF; END $$;