Skip to content

Commit 7aeda44

Browse files
committed
Update DB schema with recent changes
Signed-off-by: nscuro <nscuro@protonmail.com>
1 parent 1c2bd72 commit 7aeda44

File tree

1 file changed

+214
-4
lines changed

1 file changed

+214
-4
lines changed

commons-persistence/src/main/resources/schema.sql

Lines changed: 214 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,87 @@ BEGIN
778778
end;
779779
$$;
780780

781+
CREATE FUNCTION public.effective_permissions_mx_on_delete() RETURNS trigger
782+
LANGUAGE plpgsql
783+
AS $$
784+
DECLARE
785+
project_ids BIGINT[];
786+
BEGIN
787+
IF TG_TABLE_NAME = 'PROJECT_ACCESS_TEAMS' THEN
788+
PERFORM recalc_user_project_effective_permissions(
789+
(SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") FROM old_table)
790+
);
791+
ELSIF TG_TABLE_NAME IN (
792+
'LDAPUSERS_TEAMS', 'MANAGEDUSERS_TEAMS', 'OIDCUSERS_TEAMS', 'TEAMS_PERMISSIONS'
793+
) THEN
794+
PERFORM recalc_user_project_effective_permissions((
795+
SELECT ARRAY_AGG(DISTINCT pat."PROJECT_ID")
796+
FROM "PROJECT_ACCESS_TEAMS" AS pat
797+
INNER JOIN old_table
798+
ON old_table."TEAM_ID" = pat."TEAM_ID"
799+
));
800+
END IF;
801+
RETURN NULL;
802+
END;
803+
$$;
804+
805+
CREATE FUNCTION public.effective_permissions_mx_on_insert() RETURNS trigger
806+
LANGUAGE plpgsql
807+
AS $$
808+
DECLARE
809+
project_ids BIGINT[];
810+
BEGIN
811+
IF TG_TABLE_NAME = 'PROJECT_ACCESS_TEAMS' THEN
812+
PERFORM recalc_user_project_effective_permissions(
813+
(SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") FROM new_table)
814+
);
815+
ELSIF TG_TABLE_NAME IN (
816+
'LDAPUSERS_TEAMS', 'MANAGEDUSERS_TEAMS', 'OIDCUSERS_TEAMS', 'TEAMS_PERMISSIONS'
817+
) THEN
818+
PERFORM recalc_user_project_effective_permissions((
819+
SELECT ARRAY_AGG(DISTINCT pat."PROJECT_ID")
820+
FROM "PROJECT_ACCESS_TEAMS" AS pat
821+
INNER JOIN new_table
822+
ON new_table."TEAM_ID" = pat."TEAM_ID"
823+
));
824+
END IF;
825+
RETURN NULL;
826+
END;
827+
$$;
828+
829+
CREATE FUNCTION public.effective_permissions_mx_on_update() RETURNS trigger
830+
LANGUAGE plpgsql
831+
AS $$
832+
DECLARE
833+
project_ids BIGINT[];
834+
BEGIN
835+
IF TG_TABLE_NAME = 'PROJECT_ACCESS_TEAMS' THEN
836+
PERFORM recalc_user_project_effective_permissions((
837+
SELECT ARRAY_AGG("PROJECT_ID")
838+
FROM (
839+
SELECT "PROJECT_ID" FROM old_table
840+
UNION
841+
SELECT "PROJECT_ID" FROM new_table
842+
) AS combined_projects
843+
));
844+
ELSIF TG_TABLE_NAME IN (
845+
'LDAPUSERS_TEAMS', 'MANAGEDUSERS_TEAMS', 'OIDCUSERS_TEAMS', 'TEAMS_PERMISSIONS'
846+
) THEN
847+
PERFORM recalc_user_project_effective_permissions((
848+
SELECT ARRAY_AGG(DISTINCT pat."PROJECT_ID")
849+
FROM "PROJECT_ACCESS_TEAMS" pat
850+
JOIN (
851+
SELECT "TEAM_ID" FROM old_table
852+
UNION
853+
SELECT "TEAM_ID" FROM new_table
854+
) AS teams
855+
ON pat."TEAM_ID" = teams."TEAM_ID"
856+
));
857+
END IF;
858+
RETURN NULL;
859+
END;
860+
$$;
861+
781862
CREATE FUNCTION public.has_project_access(project_id bigint, team_ids bigint[]) RETURNS boolean
782863
LANGUAGE sql STABLE PARALLEL SAFE
783864
AS $$
@@ -815,6 +896,20 @@ SELECT JSONB_AGG(DISTINCT JSONB_STRIP_NULLS(JSONB_BUILD_OBJECT(
815896
OR ("vuln_source" = 'VULNDB' AND "VA"."VULNDB_ID" = "vuln_id")
816897
$$;
817898

899+
CREATE FUNCTION public.prevent_direct_effective_permissions_writes() RETURNS trigger
900+
LANGUAGE plpgsql
901+
AS $$
902+
BEGIN
903+
-- Depth of 1 means this trigger was fired by an attempted direct
904+
-- insert, update, or delete on USER_PROJECT_EFFECTIVE_PERMISSIONS.
905+
-- Depth should be 2, meaning this trigger was fired from another trigger.
906+
IF pg_trigger_depth() < 2 THEN
907+
RAISE EXCEPTION 'Direct modifications to USER_PROJECT_EFFECTIVE_PERMISSIONS are not allowed.';
908+
END IF;
909+
RETURN NEW;
910+
END;
911+
$$;
912+
818913
CREATE FUNCTION public.project_hierarchy_maintenance_on_project_delete() RETURNS trigger
819914
LANGUAGE plpgsql
820915
AS $$
@@ -861,9 +956,58 @@ CREATE FUNCTION public.project_hierarchy_maintenance_on_project_update() RETURNS
861956
END;
862957
$$;
863958

959+
CREATE FUNCTION public.recalc_user_project_effective_permissions(project_ids bigint[]) RETURNS void
960+
LANGUAGE plpgsql
961+
AS $$
962+
BEGIN
963+
-- Remove any existing effective permissions for this project.
964+
DELETE FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS"
965+
WHERE "PROJECT_ID" = ANY(project_ids);
966+
967+
-- Rebuild effective permissions for LDAP users
968+
INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS"
969+
("LDAPUSER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME")
970+
SELECT DISTINCT lt."LDAPUSER_ID", pat."PROJECT_ID", tp."PERMISSION_ID", p."NAME"
971+
FROM "PROJECT_ACCESS_TEAMS" pat
972+
INNER JOIN "TEAMS_PERMISSIONS" tp
973+
ON tp."TEAM_ID" = pat."TEAM_ID"
974+
INNER JOIN "PERMISSION" p
975+
ON p."ID" = tp."PERMISSION_ID"
976+
INNER JOIN "LDAPUSERS_TEAMS" lt
977+
ON lt."TEAM_ID" = pat."TEAM_ID"
978+
WHERE pat."PROJECT_ID" = ANY(project_ids);
979+
980+
-- Rebuild effective permissions for managed users
981+
INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS"
982+
("MANAGEDUSER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME")
983+
SELECT DISTINCT mt."MANAGEDUSER_ID", pat."PROJECT_ID", tp."PERMISSION_ID", p."NAME"
984+
FROM "PROJECT_ACCESS_TEAMS" pat
985+
INNER JOIN "TEAMS_PERMISSIONS" tp
986+
ON tp."TEAM_ID" = pat."TEAM_ID"
987+
INNER JOIN "PERMISSION" p
988+
ON p."ID" = tp."PERMISSION_ID"
989+
INNER JOIN "MANAGEDUSERS_TEAMS" mt
990+
ON mt."TEAM_ID" = pat."TEAM_ID"
991+
WHERE pat."PROJECT_ID" = ANY(project_ids);
992+
993+
-- Rebuild effective permissions for OIDC users
994+
INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS"
995+
("OIDCUSER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME")
996+
SELECT DISTINCT ot."OIDCUSERS_ID", pat."PROJECT_ID", tp."PERMISSION_ID", p."NAME"
997+
FROM "PROJECT_ACCESS_TEAMS" pat
998+
INNER JOIN "TEAMS_PERMISSIONS" tp
999+
ON tp."TEAM_ID" = pat."TEAM_ID"
1000+
INNER JOIN "PERMISSION" p
1001+
ON p."ID" = tp."PERMISSION_ID"
1002+
INNER JOIN "OIDCUSERS_TEAMS" ot
1003+
ON ot."TEAM_ID" = pat."TEAM_ID"
1004+
WHERE pat."PROJECT_ID" = ANY(project_ids);
1005+
END;
1006+
$$;
1007+
8641008
SET default_tablespace = '';
8651009

866-
SET default_with_oids = false;
1010+
SET default_table_access_method = heap;
8671011

8681012
CREATE TABLE public."AFFECTEDVERSIONATTRIBUTION" (
8691013
"ID" bigint NOT NULL,
@@ -1852,6 +1996,16 @@ ALTER TABLE public."TEAM" ALTER COLUMN "ID" ADD GENERATED BY DEFAULT AS IDENTITY
18521996
CACHE 1
18531997
);
18541998

1999+
CREATE TABLE public."USER_PROJECT_EFFECTIVE_PERMISSIONS" (
2000+
"LDAPUSER_ID" bigint,
2001+
"MANAGEDUSER_ID" bigint,
2002+
"OIDCUSER_ID" bigint,
2003+
"PROJECT_ID" bigint NOT NULL,
2004+
"PERMISSION_ID" bigint NOT NULL,
2005+
"PERMISSION_NAME" character varying(255) NOT NULL,
2006+
CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_check" CHECK (((((("LDAPUSER_ID" IS NOT NULL))::integer + (("MANAGEDUSER_ID" IS NOT NULL))::integer) + (("OIDCUSER_ID" IS NOT NULL))::integer) = 1))
2007+
);
2008+
18552009
CREATE TABLE public."VEX" (
18562010
"ID" bigint NOT NULL,
18572011
"IMPORTED" timestamp with time zone NOT NULL,
@@ -2663,6 +2817,12 @@ CREATE INDEX "TEAMS_PERMISSIONS_PERMISSION_ID_IDX" ON public."TEAMS_PERMISSIONS"
26632817

26642818
CREATE INDEX "TEAMS_PERMISSIONS_TEAM_ID_IDX" ON public."TEAMS_PERMISSIONS" USING btree ("TEAM_ID");
26652819

2820+
CREATE UNIQUE INDEX "USER_PROJECT_EFFECTIVE_PERMISSIONS_LDAPUSERS_IDX" ON public."USER_PROJECT_EFFECTIVE_PERMISSIONS" USING btree ("LDAPUSER_ID", "PROJECT_ID", "PERMISSION_ID") WHERE ("LDAPUSER_ID" IS NOT NULL);
2821+
2822+
CREATE UNIQUE INDEX "USER_PROJECT_EFFECTIVE_PERMISSIONS_MANAGEDUSERS_IDX" ON public."USER_PROJECT_EFFECTIVE_PERMISSIONS" USING btree ("MANAGEDUSER_ID", "PROJECT_ID", "PERMISSION_ID") WHERE ("MANAGEDUSER_ID" IS NOT NULL);
2823+
2824+
CREATE UNIQUE INDEX "USER_PROJECT_EFFECTIVE_PERMISSIONS_OIDCUSERS_IDX" ON public."USER_PROJECT_EFFECTIVE_PERMISSIONS" USING btree ("OIDCUSER_ID", "PROJECT_ID", "PERMISSION_ID") WHERE ("OIDCUSER_ID" IS NOT NULL);
2825+
26662826
CREATE INDEX "VEX_PROJECT_ID_IDX" ON public."VEX" USING btree ("PROJECT_ID");
26672827

26682828
CREATE INDEX "VIOLATIONANALYSISCOMMENT_VIOLATIONANALYSIS_ID_IDX" ON public."VIOLATIONANALYSISCOMMENT" USING btree ("VIOLATIONANALYSIS_ID");
@@ -2713,11 +2873,43 @@ CREATE INDEX "VULNERABLESOFTWARE_VULNERABILITIES_VULNERABLESOFTWARE_ID_IDX" ON p
27132873

27142874
CREATE INDEX "WORKFLOW_STATE_PARENT_STEP_ID_IDX" ON public."WORKFLOW_STATE" USING btree ("PARENT_STEP_ID");
27152875

2716-
CREATE TRIGGER trigger_project_hierarchy_maintenance_on_project_delete AFTER DELETE ON public."PROJECT" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE PROCEDURE public.project_hierarchy_maintenance_on_project_delete();
2876+
CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_teams_delete AFTER DELETE ON public."LDAPUSERS_TEAMS" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_delete();
2877+
2878+
CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_teams_insert AFTER INSERT ON public."LDAPUSERS_TEAMS" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_insert();
2879+
2880+
CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_teams_update AFTER UPDATE ON public."LDAPUSERS_TEAMS" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_update();
2881+
2882+
CREATE TRIGGER trigger_effective_permissions_mx_on_managedusers_teams_delete AFTER DELETE ON public."MANAGEDUSERS_TEAMS" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_delete();
2883+
2884+
CREATE TRIGGER trigger_effective_permissions_mx_on_managedusers_teams_insert AFTER INSERT ON public."MANAGEDUSERS_TEAMS" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_insert();
2885+
2886+
CREATE TRIGGER trigger_effective_permissions_mx_on_managedusers_teams_update AFTER UPDATE ON public."MANAGEDUSERS_TEAMS" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_update();
2887+
2888+
CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_teams_delete AFTER DELETE ON public."OIDCUSERS_TEAMS" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_delete();
2889+
2890+
CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_teams_insert AFTER INSERT ON public."OIDCUSERS_TEAMS" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_insert();
27172891

2718-
CREATE TRIGGER trigger_project_hierarchy_maintenance_on_project_insert AFTER INSERT ON public."PROJECT" FOR EACH ROW EXECUTE PROCEDURE public.project_hierarchy_maintenance_on_project_insert();
2892+
CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_teams_update AFTER UPDATE ON public."OIDCUSERS_TEAMS" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_update();
27192893

2720-
CREATE TRIGGER trigger_project_hierarchy_maintenance_on_project_update AFTER UPDATE OF "PARENT_PROJECT_ID" ON public."PROJECT" FOR EACH ROW WHEN ((old."PARENT_PROJECT_ID" IS DISTINCT FROM new."PARENT_PROJECT_ID")) EXECUTE PROCEDURE public.project_hierarchy_maintenance_on_project_update();
2894+
CREATE TRIGGER trigger_effective_permissions_mx_on_project_access_teams_delete AFTER DELETE ON public."PROJECT_ACCESS_TEAMS" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_delete();
2895+
2896+
CREATE TRIGGER trigger_effective_permissions_mx_on_project_access_teams_insert AFTER INSERT ON public."PROJECT_ACCESS_TEAMS" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_insert();
2897+
2898+
CREATE TRIGGER trigger_effective_permissions_mx_on_project_access_teams_update AFTER UPDATE ON public."PROJECT_ACCESS_TEAMS" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_update();
2899+
2900+
CREATE TRIGGER trigger_effective_permissions_mx_on_teams_permissions_delete AFTER DELETE ON public."TEAMS_PERMISSIONS" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_delete();
2901+
2902+
CREATE TRIGGER trigger_effective_permissions_mx_on_teams_permissions_insert AFTER INSERT ON public."TEAMS_PERMISSIONS" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_insert();
2903+
2904+
CREATE TRIGGER trigger_effective_permissions_mx_on_teams_permissions_update AFTER UPDATE ON public."TEAMS_PERMISSIONS" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION public.effective_permissions_mx_on_update();
2905+
2906+
CREATE TRIGGER trigger_prevent_direct_effective_permissions_writes BEFORE INSERT OR DELETE OR UPDATE ON public."USER_PROJECT_EFFECTIVE_PERMISSIONS" FOR EACH STATEMENT EXECUTE FUNCTION public.prevent_direct_effective_permissions_writes();
2907+
2908+
CREATE TRIGGER trigger_project_hierarchy_maintenance_on_project_delete AFTER DELETE ON public."PROJECT" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION public.project_hierarchy_maintenance_on_project_delete();
2909+
2910+
CREATE TRIGGER trigger_project_hierarchy_maintenance_on_project_insert AFTER INSERT ON public."PROJECT" FOR EACH ROW EXECUTE FUNCTION public.project_hierarchy_maintenance_on_project_insert();
2911+
2912+
CREATE TRIGGER trigger_project_hierarchy_maintenance_on_project_update AFTER UPDATE OF "PARENT_PROJECT_ID" ON public."PROJECT" FOR EACH ROW WHEN ((old."PARENT_PROJECT_ID" IS DISTINCT FROM new."PARENT_PROJECT_ID")) EXECUTE FUNCTION public.project_hierarchy_maintenance_on_project_update();
27212913

27222914
ALTER TABLE ONLY public."AFFECTEDVERSIONATTRIBUTION"
27232915
ADD CONSTRAINT "AFFECTEDVERSIONATTRIBUTION_VULNERABILITY_FK" FOREIGN KEY ("VULNERABILITY") REFERENCES public."VULNERABILITY"("ID") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
@@ -2932,6 +3124,24 @@ ALTER TABLE ONLY public."TEAMS_PERMISSIONS"
29323124
ALTER TABLE ONLY public."TEAMS_PERMISSIONS"
29333125
ADD CONSTRAINT "TEAMS_PERMISSIONS_TEAM_FK" FOREIGN KEY ("TEAM_ID") REFERENCES public."TEAM"("ID") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
29343126

3127+
ALTER TABLE ONLY public."USER_PROJECT_EFFECTIVE_PERMISSIONS"
3128+
ADD CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_LDAPUSER_FK" FOREIGN KEY ("LDAPUSER_ID") REFERENCES public."LDAPUSER"("ID") DEFERRABLE INITIALLY DEFERRED;
3129+
3130+
ALTER TABLE ONLY public."USER_PROJECT_EFFECTIVE_PERMISSIONS"
3131+
ADD CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_MANAGEDUSER_FK" FOREIGN KEY ("MANAGEDUSER_ID") REFERENCES public."MANAGEDUSER"("ID") DEFERRABLE INITIALLY DEFERRED;
3132+
3133+
ALTER TABLE ONLY public."USER_PROJECT_EFFECTIVE_PERMISSIONS"
3134+
ADD CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_OIDCUSER_FK" FOREIGN KEY ("OIDCUSER_ID") REFERENCES public."OIDCUSER"("ID") DEFERRABLE INITIALLY DEFERRED;
3135+
3136+
ALTER TABLE ONLY public."USER_PROJECT_EFFECTIVE_PERMISSIONS"
3137+
ADD CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_PERMISSION_ID_FK" FOREIGN KEY ("PERMISSION_ID") REFERENCES public."PERMISSION"("ID") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
3138+
3139+
ALTER TABLE ONLY public."USER_PROJECT_EFFECTIVE_PERMISSIONS"
3140+
ADD CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_PERMISSION_NAME_FK" FOREIGN KEY ("PERMISSION_NAME") REFERENCES public."PERMISSION"("NAME") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
3141+
3142+
ALTER TABLE ONLY public."USER_PROJECT_EFFECTIVE_PERMISSIONS"
3143+
ADD CONSTRAINT "USER_PROJECT_EFFECTIVE_PERMISSIONS_PROJECT_FK" FOREIGN KEY ("PROJECT_ID") REFERENCES public."PROJECT"("ID") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
3144+
29353145
ALTER TABLE ONLY public."VEX"
29363146
ADD CONSTRAINT "VEX_PROJECT_FK" FOREIGN KEY ("PROJECT_ID") REFERENCES public."PROJECT"("ID") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
29373147

0 commit comments

Comments
 (0)