Merge ~pappacena/launchpad:merge-db-stable into launchpad:master

Proposed by Thiago F. Pappacena
Status: Merged
Approved by: Thiago F. Pappacena
Approved revision: 8143362d385401088014b1d66bf71e55549b6df5
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~pappacena/launchpad:merge-db-stable
Merge into: launchpad:master
Diff against target: 171 lines (+129/-0)
3 files modified
database/schema/patch-2210-26-3.sql (+122/-0)
database/schema/security.cfg (+3/-0)
lib/lp/registry/personmerge.py (+4/-0)
Reviewer Review Type Date Requested Status
Thiago F. Pappacena (community) Approve
Review via email: mp+400266@code.launchpad.net

Commit message

Merge db-stable 8143362d385401088014b1d66bf71e55549b6df5 (Database changes for private OCI recipes)

To post a comment you must log in.
Revision history for this message
Thiago F. Pappacena (pappacena) wrote :

Deployed to the production database today.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/database/schema/patch-2210-26-3.sql b/database/schema/patch-2210-26-3.sql
2new file mode 100644
3index 0000000..0788f93
4--- /dev/null
5+++ b/database/schema/patch-2210-26-3.sql
6@@ -0,0 +1,122 @@
7+-- Copyright 2021 Canonical Ltd. This software is licensed under the
8+-- GNU Affero General Public License version 3 (see the file LICENSE).
9+
10+SET client_min_messages=ERROR;
11+
12+-- OCIRecipe privacy model is based only on ownership, similarly to Archives.
13+ALTER TABLE OCIRecipe
14+ ADD COLUMN information_type integer,
15+ ADD COLUMN access_policy integer,
16+ ADD COLUMN access_grants integer[];
17+
18+COMMENT ON COLUMN OCIRecipe.information_type IS
19+ 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine to apply an access policy.';
20+
21+
22+CREATE TABLE OCIRecipeSubscription (
23+ id serial PRIMARY KEY,
24+ recipe integer NOT NULL REFERENCES OCIRecipe(id),
25+ person integer NOT NULL REFERENCES Person(id),
26+ date_created timestamp without time zone DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC') NOT NULL,
27+ subscribed_by integer NOT NULL REFERENCES Person(id)
28+);
29+
30+COMMENT ON TABLE OCIRecipeSubscription IS 'Person subscription for OCI recipe.';
31+COMMENT ON COLUMN OCIRecipeSubscription.person IS
32+ 'The person who subscribed to the OCI recipe.';
33+COMMENT ON COLUMN OCIRecipeSubscription.recipe IS
34+ 'The OCI recipe to which the person subscribed.';
35+COMMENT ON COLUMN OCIRecipeSubscription.date_created IS
36+ 'When the subscription was created.';
37+COMMENT ON COLUMN OCIRecipeSubscription.subscribed_by IS
38+ 'The person performing the action of subscribing someone to the OCI recipe.';
39+
40+CREATE UNIQUE INDEX ocirecipesubscription__recipe__person__key
41+ ON OCIRecipeSubscription(recipe, person);
42+
43+CREATE INDEX ocirecipesubscription__person__idx
44+ ON OCIRecipeSubscription(person);
45+
46+CREATE INDEX ocirecipesubscription__subscribed_by__idx
47+ ON OCIRecipeSubscription(subscribed_by);
48+
49+ALTER TABLE AccessArtifact
50+ ADD COLUMN ocirecipe integer REFERENCES OCIRecipe;
51+
52+
53+ALTER TABLE AccessArtifact DROP CONSTRAINT has_artifact;
54+ALTER TABLE AccessArtifact
55+ ADD CONSTRAINT has_artifact CHECK (
56+ (null_count(ARRAY[bug, branch, gitrepository, snap, specification, ocirecipe]) = 5)) NOT VALID;
57+
58+
59+CREATE OR REPLACE FUNCTION ocirecipe_denorm_access(ocirecipe_id integer)
60+ RETURNS void LANGUAGE plpgsql AS
61+$$
62+DECLARE
63+ info_type integer;
64+BEGIN
65+ SELECT
66+ -- information type: 1 = public
67+ COALESCE(ocirecipe.information_type, 1)
68+ INTO info_type
69+ FROM ocirecipe WHERE id = ocirecipe_id;
70+
71+ UPDATE OCIRecipe
72+ SET access_policy = policies[1], access_grants = grants
73+ FROM
74+ build_access_cache(
75+ (SELECT id FROM accessartifact WHERE ocirecipe = ocirecipe_id),
76+ info_type)
77+ AS (policies integer[], grants integer[])
78+ WHERE id = ocirecipe_id;
79+END;
80+$$;
81+
82+CREATE OR REPLACE FUNCTION accessartifact_denorm_to_artifacts(artifact_id integer)
83+ RETURNS void
84+ LANGUAGE plpgsql
85+ AS $$
86+DECLARE
87+ artifact_row accessartifact%ROWTYPE;
88+BEGIN
89+ SELECT * INTO artifact_row FROM accessartifact WHERE id = artifact_id;
90+ IF artifact_row.bug IS NOT NULL THEN
91+ PERFORM bug_flatten_access(artifact_row.bug);
92+ END IF;
93+ IF artifact_row.branch IS NOT NULL THEN
94+ PERFORM branch_denorm_access(artifact_row.branch);
95+ END IF;
96+ IF artifact_row.gitrepository IS NOT NULL THEN
97+ PERFORM gitrepository_denorm_access(artifact_row.gitrepository);
98+ END IF;
99+ IF artifact_row.snap IS NOT NULL THEN
100+ PERFORM snap_denorm_access(artifact_row.snap);
101+ END IF;
102+ IF artifact_row.specification IS NOT NULL THEN
103+ PERFORM specification_denorm_access(artifact_row.specification);
104+ END IF;
105+ IF artifact_row.ocirecipe IS NOT NULL THEN
106+ PERFORM ocirecipe_denorm_access(artifact_row.ocirecipe);
107+ END IF;
108+ RETURN;
109+END;
110+$$;
111+
112+COMMENT ON FUNCTION accessartifact_denorm_to_artifacts(artifact_id integer) IS
113+ 'Denormalize the policy access and artifact grants to bugs, branches, git repositories, snaps, specifications and ocirecipe.';
114+
115+-- A trigger to handle ocirecipe.information_type changes.
116+CREATE OR REPLACE FUNCTION ocirecipe_maintain_access_cache_trig() RETURNS trigger
117+ LANGUAGE plpgsql AS $$
118+BEGIN
119+ PERFORM ocirecipe_denorm_access(NEW.id);
120+ RETURN NULL;
121+END;
122+$$;
123+
124+CREATE TRIGGER ocirecipe_maintain_access_cache
125+ AFTER INSERT OR UPDATE OF information_type ON OCIRecipe
126+ FOR EACH ROW EXECUTE PROCEDURE ocirecipe_maintain_access_cache_trig();
127+
128+INSERT INTO LaunchpadDatabaseRevision VALUES (2210, 26, 3);
129diff --git a/database/schema/security.cfg b/database/schema/security.cfg
130index 2911da2..ea39046 100644
131--- a/database/schema/security.cfg
132+++ b/database/schema/security.cfg
133@@ -61,6 +61,7 @@ public.milestone_sort_key(timestamp without time zone, text) = EXECUTE
134 public.min(debversion) = EXECUTE
135 public.name_blacklist_match(text, integer) = EXECUTE
136 public.null_count(anyarray) = EXECUTE
137+public.ocirecipe_denorm_access(integer) = EXECUTE
138 public.person_sort_key(text, text) = EXECUTE
139 public.pgstatginindex(regclass) =
140 public.pgstathashindex(regclass) =
141@@ -252,6 +253,7 @@ public.ocirecipearch = SELECT, INSERT, DELETE
142 public.ocirecipebuild = SELECT, INSERT, UPDATE, DELETE
143 public.ocirecipebuildjob = SELECT, INSERT, UPDATE, DELETE
144 public.ocirecipejob = SELECT, INSERT, UPDATE, DELETE
145+public.ocirecipesubscription = SELECT, INSERT, UPDATE, DELETE
146 public.ociregistrycredentials = SELECT, INSERT, UPDATE, DELETE
147 public.officialbugtag = SELECT, INSERT, UPDATE, DELETE
148 public.openidconsumerassociation = SELECT, INSERT, UPDATE, DELETE
149@@ -2334,6 +2336,7 @@ public.ociproject = SELECT, UPDATE
150 public.ociprojectseries = SELECT, UPDATE
151 public.ocirecipe = SELECT, UPDATE
152 public.ocirecipebuild = SELECT, UPDATE
153+public.ocirecipesubscription = SELECT, UPDATE, DELETE
154 public.ociregistrycredentials = SELECT, UPDATE
155 public.officialbugtag = SELECT
156 public.openididentifier = SELECT, UPDATE
157diff --git a/lib/lp/registry/personmerge.py b/lib/lp/registry/personmerge.py
158index 3e51005..a4a79e9 100644
159--- a/lib/lp/registry/personmerge.py
160+++ b/lib/lp/registry/personmerge.py
161@@ -941,6 +941,10 @@ def merge_people(from_person, to_person, reviewer, delete=False):
162 _mergeOCIRecipe(cur, from_person, to_person)
163 skip.append(('ocirecipe', 'owner'))
164
165+ # XXX pappacena 2021-03-05: We need to implement the proper handling for
166+ # this once we have OCIRecipeSubscription implemented.
167+ skip.append(('ocirecipesubscription', 'person'))
168+
169 # Sanity check. If we have a reference that participates in a
170 # UNIQUE index, it must have already been handled by this point.
171 # We can tell this by looking at the skip list.