]> git.decadent.org.uk Git - dak.git/blob - dak/dakdb/update66.py
Set search_path to a secure value.
[dak.git] / dak / dakdb / update66.py
1 #!/usr/bin/env python
2 # coding=utf8
3
4 """
5 Add audit schema and initial package table and triggers
6
7 @contact: Debian FTP Master <ftpmaster@debian.org>
8 @copyright: 2011 Mark Hymers <mhy@debian.org>
9 @license: GNU General Public License version 2 or later
10 """
11
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
16
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
26 ################################################################################
27
28 import psycopg2
29 from daklib.dak_exceptions import DBUpdateError
30 from daklib.config import Config
31
32 ################################################################################
33 def do_update(self):
34     """
35     Add audit schema and initial package table and triggers
36     """
37     print __doc__
38     try:
39         c = self.db.cursor()
40
41         c.execute("CREATE SCHEMA audit");
42         c.execute("GRANT USAGE on SCHEMA audit TO public")
43         c.execute("GRANT USAGE on SCHEMA audit TO ftpteam")
44         c.execute("GRANT USAGE on SCHEMA audit TO ftpmaster")
45
46         c.execute("""CREATE TABLE audit.package_changes (
47    changedate TIMESTAMP NOT NULL DEFAULT now(),
48    package TEXT NOT NULL,
49    version DEBVERSION NOT NULL,
50    architecture TEXT NOT NULL,
51    suite TEXT NOT NULL,
52    event TEXT NOT NULL,
53    priority TEXT,
54    component TEXT,
55    section TEXT
56 )""")
57
58         c.execute("GRANT INSERT ON audit.package_changes TO dak")
59         c.execute("GRANT SELECT ON audit.package_changes TO PUBLIC")
60
61         c.execute("""CREATE OR REPLACE FUNCTION trigger_binsrc_assoc_update() RETURNS TRIGGER AS $$
62 DECLARE
63   v_data RECORD;
64
65   v_package audit.package_changes.package%TYPE;
66   v_version audit.package_changes.version%TYPE;
67   v_architecture audit.package_changes.architecture%TYPE;
68   v_suite audit.package_changes.suite%TYPE;
69   v_event audit.package_changes.event%TYPE;
70   v_priority audit.package_changes.priority%TYPE;
71   v_component audit.package_changes.component%TYPE;
72   v_section audit.package_changes.section%TYPE;
73 BEGIN
74   CASE TG_OP
75     WHEN 'INSERT' THEN v_event := 'I'; v_data := NEW;
76     WHEN 'DELETE' THEN v_event := 'D'; v_data := OLD;
77     ELSE RAISE EXCEPTION 'trigger called for invalid operation (%)', TG_OP;
78   END CASE;
79
80   SELECT suite_name INTO STRICT v_suite FROM suite WHERE id = v_data.suite;
81
82   CASE TG_TABLE_NAME
83     WHEN 'bin_associations' THEN
84       SELECT package, version, arch_string
85         INTO STRICT v_package, v_version, v_architecture
86         FROM binaries LEFT JOIN architecture ON (architecture.id = binaries.architecture)
87         WHERE binaries.id = v_data.bin;
88
89       SELECT component.name, priority.priority, section.section
90         INTO v_component, v_priority, v_section
91         FROM override
92              JOIN override_type ON (override.type = override_type.id)
93              JOIN priority ON (priority.id = override.priority)
94              JOIN section ON (section.id = override.section)
95              JOIN component ON (override.component = component.id)
96              JOIN suite ON (suite.id = override.suite)
97         WHERE override_type.type != 'dsc'
98               AND override.package = v_package AND suite.id = v_data.suite;
99
100     WHEN 'src_associations' THEN
101       SELECT source, version
102         INTO STRICT v_package, v_version
103         FROM source WHERE source.id = v_data.source;
104       v_architecture := 'source';
105
106       SELECT component.name, priority.priority, section.section
107         INTO v_component, v_priority, v_section
108         FROM override
109              JOIN override_type ON (override.type = override_type.id)
110              JOIN priority ON (priority.id = override.priority)
111              JOIN section ON (section.id = override.section)
112              JOIN component ON (override.component = component.id)
113              JOIN suite ON (suite.id = override.suite)
114         WHERE override_type.type = 'dsc'
115               AND override.package = v_package AND suite.id = v_data.suite;
116
117     ELSE RAISE EXCEPTION 'trigger called for invalid table (%)', TG_TABLE_NAME;
118   END CASE;
119
120   INSERT INTO audit.package_changes
121     (package, version, architecture, suite, event, priority, component, section)
122     VALUES (v_package, v_version, v_architecture, v_suite, v_event, v_priority, v_component, v_section);
123
124   RETURN NEW;
125 END;
126 $$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER
127 SET search_path = public, pg_temp""");
128
129         c.execute("""CREATE OR REPLACE FUNCTION trigger_override_update() RETURNS TRIGGER AS $$
130 DECLARE
131   v_src_override_id override_type.id%TYPE;
132
133   v_priority audit.package_changes.priority%TYPE := NULL;
134   v_component audit.package_changes.component%TYPE := NULL;
135   v_section audit.package_changes.section%TYPE := NULL;
136 BEGIN
137
138   IF TG_TABLE_NAME != 'override' THEN
139     RAISE EXCEPTION 'trigger called for invalid table (%)', TG_TABLE_NAME;
140   END IF;
141   IF TG_OP != 'UPDATE' THEN
142     RAISE EXCEPTION 'trigger called for invalid event (%)', TG_OP;
143   END IF;
144
145   IF OLD.package != NEW.package OR OLD.type != NEW.type OR OLD.suite != NEW.suite THEN
146     RETURN NEW;
147   END IF;
148
149   IF OLD.priority != NEW.priority THEN
150     SELECT priority INTO STRICT v_priority FROM priority WHERE id = NEW.priority;
151   END IF;
152
153   IF OLD.component != NEW.component THEN
154     SELECT name INTO STRICT v_component FROM component WHERE id = NEW.component;
155   END IF;
156
157   IF OLD.section != NEW.section THEN
158     SELECT section INTO STRICT v_section FROM section WHERE id = NEW.section;
159   END IF;
160
161   -- Find out if we're doing src or binary overrides
162   SELECT id INTO STRICT v_src_override_id FROM override_type WHERE type = 'dsc';
163   IF OLD.type = v_src_override_id THEN
164     -- Doing a src_association link
165     INSERT INTO audit.package_changes
166       (package, version, architecture, suite, event, priority, component, section)
167       SELECT NEW.package, source.version, 'source', suite.suite_name, 'U', v_priority, v_component, v_section
168         FROM source
169           JOIN src_associations ON (source.id = src_associations.source)
170           JOIN suite ON (suite.id = src_associations.suite)
171         WHERE source.source = NEW.package AND src_associations.suite = NEW.suite;
172   ELSE
173     -- Doing a bin_association link
174     INSERT INTO audit.package_changes
175       (package, version, architecture, suite, event, priority, component, section)
176       SELECT NEW.package, binaries.version, architecture.arch_string, suite.suite_name, 'U', v_priority, v_component, v_section
177         FROM binaries
178           JOIN bin_associations ON (binaries.id = bin_associations.bin)
179           JOIN architecture ON (architecture.id = binaries.architecture)
180           JOIN suite ON (suite.id = bin_associations.suite)
181         WHERE binaries.package = NEW.package AND bin_associations.suite = NEW.suite;
182   END IF;
183
184   RETURN NEW;
185 END;
186 $$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER
187 SET search_path = public, pg_temp""");
188
189         c.execute("CREATE TRIGGER trigger_bin_associations_audit AFTER INSERT OR DELETE ON bin_associations FOR EACH ROW EXECUTE PROCEDURE trigger_binsrc_assoc_update()")
190         c.execute("CREATE TRIGGER trigger_src_associations_audit AFTER INSERT OR DELETE ON src_associations FOR EACH ROW EXECUTE PROCEDURE trigger_binsrc_assoc_update()")
191         c.execute("CREATE TRIGGER trigger_override_audit AFTER UPDATE ON override FOR EACH ROW EXECUTE PROCEDURE trigger_override_update()")
192
193         c.execute("UPDATE config SET value = '66' WHERE name = 'db_revision'")
194         self.db.commit()
195
196     except psycopg2.ProgrammingError, msg:
197         self.db.rollback()
198         raise DBUpdateError, 'Unable to apply sick update 66, rollback issued. Error message : %s' % (str(msg))