Merge lp:~wgrant/launchpad/gpgkey-fks-read into lp:launchpad

Proposed by William Grant
Status: Merged
Merged at revision: 17941
Proposed branch: lp:~wgrant/launchpad/gpgkey-fks-read
Merge into: lp:launchpad
Prerequisite: lp:~wgrant/launchpad/gpgkey-fks-no-garbo
Diff against target: 794 lines (+176/-73)
28 files modified
lib/lp/archivepublisher/archivesigningkey.py (+7/-4)
lib/lp/archivepublisher/tests/archive-signing.txt (+18/-7)
lib/lp/archivepublisher/tests/test_publishdistro.py (+3/-1)
lib/lp/archiveuploader/tests/upload-karma.txt (+4/-1)
lib/lp/registry/browser/tests/test_codeofconduct.py (+2/-1)
lib/lp/registry/browser/tests/test_distroseries.py (+17/-6)
lib/lp/registry/interfaces/gpg.py (+3/-0)
lib/lp/registry/model/codeofconduct.py (+9/-2)
lib/lp/registry/model/distroseries.py (+2/-2)
lib/lp/registry/model/distroseriesdifference.py (+2/-6)
lib/lp/registry/model/gpgkey.py (+6/-0)
lib/lp/soyuz/configure.zcml (+3/-3)
lib/lp/soyuz/doc/distroseriesqueue-notify.txt (+3/-1)
lib/lp/soyuz/doc/publishing.txt (+7/-2)
lib/lp/soyuz/interfaces/sourcepackagerelease.py (+0/-1)
lib/lp/soyuz/model/archive.py (+22/-18)
lib/lp/soyuz/model/queue.py (+8/-1)
lib/lp/soyuz/model/sourcepackagerelease.py (+14/-3)
lib/lp/soyuz/scripts/gina/handlers.py (+1/-1)
lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py (+6/-2)
lib/lp/soyuz/stories/ppa/xx-private-ppa-subscriptions.txt (+3/-1)
lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt (+3/-1)
lib/lp/soyuz/stories/webservice/xx-archive.txt (+4/-1)
lib/lp/soyuz/stories/webservice/xx-builds.txt (+4/-1)
lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt (+5/-2)
lib/lp/soyuz/tests/test_archive.py (+9/-2)
lib/lp/soyuz/tests/test_build_notify.py (+9/-2)
utilities/soyuz-sampledata-setup.py (+2/-1)
To merge this branch: bzr merge lp:~wgrant/launchpad/gpgkey-fks-read
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+287804@code.launchpad.net

Commit message

Read GPGKey fingerprint columns rather than the integer FK.

Description of the change

Read GPGKey fingerprint columns rather than the integer FK.

Still setting the old columns until everything reads from the new.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/archivepublisher/archivesigningkey.py'
2--- lib/lp/archivepublisher/archivesigningkey.py 2016-02-22 23:52:21 +0000
3+++ lib/lp/archivepublisher/archivesigningkey.py 2016-03-10 01:29:20 +0000
4@@ -27,6 +27,7 @@
5 GPGKeyAlgorithm,
6 IGPGHandler,
7 )
8+from lp.services.propertycache import get_property_cache
9
10
11 @implementer(IArchiveSigningKey)
12@@ -71,9 +72,10 @@
13 if default_ppa.signing_key is None:
14 IArchiveSigningKey(default_ppa).generateSigningKey()
15 key = default_ppa.signing_key
16- self.archive.signing_key = key
17+ self.archive._signing_key = key
18 self.archive.signing_key_owner = key.owner
19- self.archive._signing_key_fingerprint = key.fingerprint
20+ self.archive.signing_key_fingerprint = key.fingerprint
21+ del get_property_cache(self.archive).signing_key
22 return
23
24 key_displayname = (
25@@ -111,9 +113,10 @@
26 key = getUtility(IGPGKeySet).new(
27 key_owner, pub_key.keyid, pub_key.fingerprint, pub_key.keysize,
28 algorithm, active=True, can_encrypt=pub_key.can_encrypt)
29- self.archive.signing_key = key
30+ self.archive._signing_key = key
31 self.archive.signing_key_owner = key.owner
32- self.archive._signing_key_fingerprint = key.fingerprint
33+ self.archive.signing_key_fingerprint = key.fingerprint
34+ del get_property_cache(self.archive).signing_key
35
36 def signRepository(self, suite):
37 """See `IArchiveSigningKey`."""
38
39=== modified file 'lib/lp/archivepublisher/tests/archive-signing.txt'
40--- lib/lp/archivepublisher/tests/archive-signing.txt 2015-10-01 10:25:19 +0000
41+++ lib/lp/archivepublisher/tests/archive-signing.txt 2016-03-10 01:29:20 +0000
42@@ -104,8 +104,8 @@
43
44 And use it as the Mark's PPA signing key.
45
46- >>> mark.archive.signing_key = a_key
47-
48+ >>> mark.archive.signing_key_owner = a_key.owner
49+ >>> mark.archive.signing_key_fingerprint = a_key.fingerprint
50 >>> print mark.archive.signing_key_fingerprint
51 ABCDEF0123456789ABCDDCBA0000111112345678
52
53@@ -286,8 +286,11 @@
54 simulating the situation when a the default PPA and a named-ppas get
55 created within the same cycle of the key-generator process.
56
57+ >>> from lp.services.propertycache import get_property_cache
58 >>> login('foo.bar@canonical.com')
59- >>> named_ppa.signing_key = None
60+ >>> named_ppa.signing_key_owner = None
61+ >>> named_ppa.signing_key_fingerprint = None
62+ >>> del get_property_cache(named_ppa).signing_key
63 >>> login(ANONYMOUS)
64
65 >>> print named_ppa.signing_key
66@@ -312,8 +315,12 @@
67 We will reset the signing-keys for both PPA of Celso.
68
69 >>> login('foo.bar@canonical.com')
70- >>> cprov.archive.signing_key = None
71- >>> named_ppa.signing_key = None
72+ >>> cprov.archive.signing_key_owner = None
73+ >>> cprov.archive.signing_key_fingerprint = None
74+ >>> del get_property_cache(cprov.archive).signing_key
75+ >>> named_ppa.signing_key_owner = None
76+ >>> named_ppa.signing_key_fingerprint = None
77+ >>> del get_property_cache(named_ppa).signing_key
78 >>> login(ANONYMOUS)
79
80 >>> print cprov.archive.signing_key
81@@ -365,7 +372,9 @@
82 Celso's default PPA will uses the testing signing key.
83
84 >>> login('foo.bar@canonical.com')
85- >>> cprov.archive.signing_key = signing_key
86+ >>> cprov.archive.signing_key_owner = signing_key.owner
87+ >>> cprov.archive.signing_key_fingerprint = signing_key.fingerprint
88+ >>> del get_property_cache(cprov.archive).signing_key
89 >>> login(ANONYMOUS)
90
91 When signing repositores we assert they contain the right format and
92@@ -437,7 +446,9 @@
93 Finally, if we try to sign a repository for which the archive doesn't
94 have a 'signing_key' set, it raises an error.
95
96- >>> cprov.archive.signing_key = None
97+ >>> cprov.archive.signing_key_owner = None
98+ >>> cprov.archive.signing_key_fingerprint = None
99+ >>> del get_property_cache(cprov.archive).signing_key
100
101 >>> archive_signing_key.signRepository(test_suite)
102 Traceback (most recent call last):
103
104=== modified file 'lib/lp/archivepublisher/tests/test_publishdistro.py'
105--- lib/lp/archivepublisher/tests/test_publishdistro.py 2016-02-04 19:46:52 +0000
106+++ lib/lp/archivepublisher/tests/test_publishdistro.py 2016-03-10 01:29:20 +0000
107@@ -246,7 +246,9 @@
108 self.addCleanup(tac.tearDown)
109 key_path = os.path.join(gpgkeysdir, 'ppa-sample@canonical.com.sec')
110 IArchiveSigningKey(cprov.archive).setSigningKey(key_path)
111- name16.archive.signing_key = cprov.archive.signing_key
112+ name16.archive.signing_key_owner = cprov.archive.signing_key_owner
113+ name16.archive.signing_key_fingerprint = (
114+ cprov.archive.signing_key_fingerprint)
115
116 self.layer.txn.commit()
117
118
119=== modified file 'lib/lp/archiveuploader/tests/upload-karma.txt'
120--- lib/lp/archiveuploader/tests/upload-karma.txt 2016-03-01 12:40:37 +0000
121+++ lib/lp/archiveuploader/tests/upload-karma.txt 2016-03-10 01:29:20 +0000
122@@ -52,7 +52,10 @@
123 >>> from lp.registry.interfaces.person import IPersonSet
124 >>> name16 = getUtility(IPersonSet).getByName('name16')
125 >>> key = getUtility(IGPGKeySet).getGPGKeysForPerson(name16)[0]
126- >>> removeSecurityProxy(foo_src.queue_root).signing_key = key
127+ >>> removeSecurityProxy(foo_src.queue_root).signing_key_owner = (
128+ ... key.owner)
129+ >>> removeSecurityProxy(foo_src.queue_root).signing_key_fingerprint = (
130+ ... key.fingerprint)
131 >>> transaction.commit()
132 >>> foo_src.queue_root.acceptFromQueue()
133 Karma added: action=distributionuploadaccepted, distribution=ubuntu
134
135=== modified file 'lib/lp/registry/browser/tests/test_codeofconduct.py'
136--- lib/lp/registry/browser/tests/test_codeofconduct.py 2012-11-08 10:48:29 +0000
137+++ lib/lp/registry/browser/tests/test_codeofconduct.py 2016-03-10 01:29:20 +0000
138@@ -70,7 +70,8 @@
139 def sign_coc(self, user, gpg_key):
140 """Return a SignedCodeOfConduct using dummy text."""
141 signed_coc = SignedCodeOfConduct(
142- owner=user, signingkey=gpg_key,
143+ owner=user, signing_key_fingerprint=gpg_key.fingerprint,
144+ signing_key_owner=gpg_key.owner,
145 signedcode="Dummy CoC signed text.", active=True)
146 return signed_coc
147
148
149=== modified file 'lib/lp/registry/browser/tests/test_distroseries.py'
150--- lib/lp/registry/browser/tests/test_distroseries.py 2016-01-26 15:47:37 +0000
151+++ lib/lp/registry/browser/tests/test_distroseries.py 2016-03-10 01:29:20 +0000
152@@ -941,8 +941,11 @@
153 sourcename=spr.sourcepackagename.name,
154 distroseries=derived_series))
155 else:
156- removeSecurityProxy(spr).dscsigningkey = (
157- self.factory.makeGPGKey(owner=spr.creator))
158+ key = self.factory.makeGPGKey(owner=spr.creator)
159+ removeSecurityProxy(spr).signing_key_owner = key.owner
160+ removeSecurityProxy(spr).signing_key_fingerprint = (
161+ key.fingerprint)
162+ del get_property_cache(spr).dscsigningkey
163
164 def flush_and_render():
165 flush_database_caches()
166@@ -1357,8 +1360,12 @@
167 # each difference row.
168 dsd = self.makePackageUpgrade()
169 uploader = self.factory.makePerson()
170- removeSecurityProxy(dsd.source_package_release).dscsigningkey = (
171- self.factory.makeGPGKey(uploader))
172+ key = self.factory.makeGPGKey(uploader)
173+ naked_spr = removeSecurityProxy(
174+ dsd.source_package_release.sourcepackagerelease)
175+ naked_spr.signing_key_fingerprint = key.fingerprint
176+ naked_spr.signing_key_owner = key.owner
177+ del get_property_cache(naked_spr).dscsigningkey
178 view = self.makeView(dsd.derived_series)
179 root = html.fromstring(view())
180 [creator_cell] = root.cssselect(
181@@ -2433,8 +2440,12 @@
182 dsd = self.factory.makeDistroSeriesDifference(
183 difference_type=missing_type)
184 uploader = self.factory.makePerson()
185- naked_spr = removeSecurityProxy(dsd.parent_source_package_release)
186- naked_spr.dscsigningkey = self.factory.makeGPGKey(uploader)
187+ key = self.factory.makeGPGKey(uploader)
188+ naked_spr = removeSecurityProxy(
189+ dsd.parent_source_package_release.sourcepackagerelease)
190+ naked_spr.signing_key_fingerprint = key.fingerprint
191+ naked_spr.signing_key_owner = key.owner
192+ del get_property_cache(naked_spr).dscsigningkey
193 with person_logged_in(self.simple_user):
194 view = create_initialized_view(
195 dsd.derived_series, '+missingpackages',
196
197=== modified file 'lib/lp/registry/interfaces/gpg.py'
198--- lib/lp/registry/interfaces/gpg.py 2016-03-01 14:15:26 +0000
199+++ lib/lp/registry/interfaces/gpg.py 2016-03-10 01:29:20 +0000
200@@ -78,6 +78,9 @@
201 inactive ones.
202 """
203
204+ def getByFingerprints(fingerprints):
205+ """Get multiple OpenPGP keys by their fingerprints."""
206+
207 def getGPGKeysForPerson(person, active=True):
208 """Return OpenGPG keys for a person.
209
210
211=== modified file 'lib/lp/registry/model/codeofconduct.py'
212--- lib/lp/registry/model/codeofconduct.py 2016-02-23 02:40:39 +0000
213+++ lib/lp/registry/model/codeofconduct.py 2016-03-10 01:29:20 +0000
214@@ -49,6 +49,7 @@
215 format_address,
216 simple_sendmail,
217 )
218+from lp.services.propertycache import cachedproperty
219 from lp.services.webapp import canonical_url
220
221
222@@ -180,7 +181,7 @@
223
224 signedcode = StringCol(dbName='signedcode', notNull=False, default=None)
225
226- signingkey = ForeignKey(foreignKey="GPGKey", dbName="signingkey",
227+ _signingkey = ForeignKey(foreignKey="GPGKey", dbName="signingkey",
228 notNull=False, default=None)
229 signing_key_fingerprint = Unicode()
230
231@@ -195,6 +196,12 @@
232
233 active = BoolCol(dbName='active', notNull=True, default=False)
234
235+ @cachedproperty
236+ def signingkey(self):
237+ if self.signing_key_fingerprint is not None:
238+ return getUtility(IGPGKeySet).getByFingerprint(
239+ self.signing_key_fingerprint)
240+
241 @property
242 def displayname(self):
243 """Build a Fancy Title for CoC."""
244@@ -308,7 +315,7 @@
245
246 # Store the signature
247 signed = SignedCodeOfConduct(
248- owner=user, signingkey=gpg,
249+ owner=user, _signingkey=gpg,
250 signing_key_fingerprint=gpg.fingerprint if gpg else None,
251 signedcode=signedcode, active=True)
252
253
254=== modified file 'lib/lp/registry/model/distroseries.py'
255--- lib/lp/registry/model/distroseries.py 2016-02-23 02:27:23 +0000
256+++ lib/lp/registry/model/distroseries.py 2016-03-10 01:29:20 +0000
257@@ -1164,7 +1164,7 @@
258 architecturehintlist=architecturehintlist, component=component,
259 creator=creator, urgency=urgency, changelog=changelog,
260 changelog_entry=changelog_entry, dsc=dsc,
261- dscsigningkey=dscsigningkey,
262+ _dscsigningkey=dscsigningkey,
263 signing_key_owner=dscsigningkey.owner if dscsigningkey else None,
264 signing_key_fingerprint=(
265 dscsigningkey.fingerprint if dscsigningkey else None),
266@@ -1353,7 +1353,7 @@
267 return PackageUpload(
268 distroseries=self, status=PackageUploadStatus.NEW,
269 pocket=pocket, archive=archive, changesfile=changes_file_alias,
270- signing_key=signing_key,
271+ _signing_key=signing_key,
272 signing_key_owner=signing_key.owner if signing_key else None,
273 signing_key_fingerprint=(
274 signing_key.fingerprint if signing_key else None),
275
276=== modified file 'lib/lp/registry/model/distroseriesdifference.py'
277--- lib/lp/registry/model/distroseriesdifference.py 2015-07-08 16:05:11 +0000
278+++ lib/lp/registry/model/distroseriesdifference.py 2016-03-10 01:29:20 +0000
279@@ -330,17 +330,13 @@
280 SourcePackageRecipeBuild, sprs,
281 ("source_package_recipe_build_id",))
282
283- # SourcePackageRelease.uploader can end up getting the owner of
284- # the DSC signing key.
285- gpgkeys = bulk.load_related(GPGKey, sprs, ("dscsigningkeyID",))
286-
287 # Load DistroSeriesDifferenceComment owners, SourcePackageRecipeBuild
288 # requesters, GPGKey owners, and SourcePackageRelease creators.
289 person_ids = set().union(
290 (dsdc.message.ownerID for dsdc in latest_comments),
291 (sprb.requester_id for sprb in sprbs),
292- (gpgkey.ownerID for gpgkey in gpgkeys),
293- (spr.creatorID for spr in sprs))
294+ (spr.creatorID for spr in sprs),
295+ (spr.signing_key_owner_id for spr in sprs))
296 uploaders = getUtility(IPersonSet).getPrecachedPersonsFromIDs(
297 person_ids, need_validity=True)
298 list(uploaders)
299
300=== modified file 'lib/lp/registry/model/gpgkey.py'
301--- lib/lp/registry/model/gpgkey.py 2016-03-01 14:15:26 +0000
302+++ lib/lp/registry/model/gpgkey.py 2016-03-10 01:29:20 +0000
303@@ -19,6 +19,7 @@
304 IGPGKeySet,
305 )
306 from lp.services.database.enumcol import EnumCol
307+from lp.services.database.interfaces import IStore
308 from lp.services.database.sqlbase import (
309 SQLBase,
310 sqlvalues,
311@@ -95,6 +96,11 @@
312 return default
313 return result
314
315+ def getByFingerprints(self, fingerprints):
316+ """See `IGPGKeySet`"""
317+ return IStore(GPGKey).find(
318+ GPGKey, GPGKey.fingerprint.is_in(fingerprints))
319+
320 def getGPGKeysForPerson(self, owner, active=True):
321 if active is False:
322 query = """
323
324=== modified file 'lib/lp/soyuz/configure.zcml'
325--- lib/lp/soyuz/configure.zcml 2016-02-24 01:30:06 +0000
326+++ lib/lp/soyuz/configure.zcml 2016-03-10 01:29:20 +0000
327@@ -389,9 +389,9 @@
328 set_schema="lp.soyuz.interfaces.archive.IArchiveRestricted"/>
329 <require
330 permission="launchpad.InternalScriptsOnly"
331- attributes="signing_key_owner _signing_key_fingerprint"
332- set_attributes="distribution signing_key signing_key_owner
333- _signing_key_fingerprint"/>
334+ attributes="signing_key_owner"
335+ set_attributes="distribution _signing_key signing_key_owner
336+ signing_key_fingerprint"/>
337 </class>
338 <adapter
339 for="lp.soyuz.interfaces.archive.IArchive"
340
341=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-notify.txt'
342--- lib/lp/soyuz/doc/distroseriesqueue-notify.txt 2016-02-29 18:48:23 +0000
343+++ lib/lp/soyuz/doc/distroseriesqueue-notify.txt 2016-03-10 01:29:20 +0000
344@@ -110,7 +110,9 @@
345 >>> from zope.security.proxy import removeSecurityProxy
346 >>> from lp.registry.interfaces.gpg import IGPGKeySet
347 >>> gpgkey = getUtility(IGPGKeySet).getByFingerprint('ABCDEF0123456789ABCDDCBA0000111112345678')
348- >>> removeSecurityProxy(netapplet_upload).signing_key = gpgkey
349+ >>> removeSecurityProxy(netapplet_upload).signing_key_owner = gpgkey.owner
350+ >>> removeSecurityProxy(netapplet_upload).signing_key_fingerprint = (
351+ ... gpgkey.fingerprint)
352
353 Now request the email:
354
355
356=== modified file 'lib/lp/soyuz/doc/publishing.txt'
357--- lib/lp/soyuz/doc/publishing.txt 2015-02-19 01:35:33 +0000
358+++ lib/lp/soyuz/doc/publishing.txt 2016-03-10 01:29:20 +0000
359@@ -23,7 +23,9 @@
360 >>> from lp.registry.model.gpgkey import GPGKey
361 >>> name16 = getUtility(IPersonSet).getByName('name16')
362 >>> fake_signer = GPGKey.selectOneBy(owner=name16)
363- >>> spph.sourcepackagerelease.dscsigningkey = fake_signer
364+ >>> spph.sourcepackagerelease.signing_key_owner = fake_signer.owner
365+ >>> spph.sourcepackagerelease.signing_key_fingerprint = (
366+ ... fake_signer.fingerprint)
367
368 Verify if the object follows its interface contracts:
369
370@@ -86,7 +88,10 @@
371
372 The signer can also be None for packages that were synced (e.g. from Debian):
373
374- >>> spph.sourcepackagerelease.dscsigningkey = None
375+ >>> from lp.services.propertycache import get_property_cache
376+ >>> spph.sourcepackagerelease.signing_key_owner = None
377+ >>> spph.sourcepackagerelease.signing_key_fingerprint = None
378+ >>> del get_property_cache(spph.sourcepackagerelease).dscsigningkey
379 >>> print spph.package_signer
380 None
381
382
383=== modified file 'lib/lp/soyuz/interfaces/sourcepackagerelease.py'
384--- lib/lp/soyuz/interfaces/sourcepackagerelease.py 2016-02-05 15:16:29 +0000
385+++ lib/lp/soyuz/interfaces/sourcepackagerelease.py 2016-03-10 01:29:20 +0000
386@@ -35,7 +35,6 @@
387 version = Attribute("A version string")
388 dateuploaded = Attribute("Date of Upload")
389 urgency = Attribute("Source Package Urgency")
390- dscsigningkeyID = Attribute("DB ID of the DSC Signing Key")
391 dscsigningkey = Attribute("DSC Signing Key")
392 component = Attribute("Source Package Component")
393 format = Attribute("The Source Package Format")
394
395=== modified file 'lib/lp/soyuz/model/archive.py'
396--- lib/lp/soyuz/model/archive.py 2016-02-23 01:59:48 +0000
397+++ lib/lp/soyuz/model/archive.py 2016-03-10 01:29:20 +0000
398@@ -77,6 +77,7 @@
399 from lp.registry.errors import NoSuchDistroSeries
400 from lp.registry.interfaces.distroseries import IDistroSeriesSet
401 from lp.registry.interfaces.distroseriesparent import IDistroSeriesParentSet
402+from lp.registry.interfaces.gpg import IGPGKeySet
403 from lp.registry.interfaces.person import (
404 IPersonSet,
405 validate_person,
406@@ -338,11 +339,11 @@
407
408 date_created = UtcDateTimeCol(dbName='date_created')
409
410- signing_key = ForeignKey(
411+ _signing_key = ForeignKey(
412 foreignKey='GPGKey', dbName='signing_key', notNull=False)
413 signing_key_owner_id = Int(name="signing_key_owner")
414 signing_key_owner = Reference(signing_key_owner_id, 'Person.id')
415- _signing_key_fingerprint = Unicode(name="signing_key_fingerprint")
416+ signing_key_fingerprint = Unicode()
417
418 relative_build_score = IntCol(
419 dbName='relative_build_score', notNull=True, default=0)
420@@ -391,6 +392,13 @@
421 """See `IArchive`."""
422 return self.displayname
423
424+ @cachedproperty
425+ def signing_key(self):
426+ """See `IArchive`."""
427+ if self.signing_key_fingerprint is not None:
428+ return getUtility(IGPGKeySet).getByFingerprint(
429+ self.signing_key_fingerprint)
430+
431 @property
432 def is_ppa(self):
433 """See `IArchive`."""
434@@ -518,13 +526,6 @@
435 return urlappend(
436 db_pubconf.base_url, self.distribution.name + postfix)
437
438- @property
439- def signing_key_fingerprint(self):
440- if self.signing_key is not None:
441- return self.signing_key.fingerprint
442-
443- return None
444-
445 def getBuildRecords(self, build_state=None, name=None, pocket=None,
446 arch_tag=None, user=None, binary_only=True):
447 """See IHasBuildRecords"""
448@@ -679,7 +680,6 @@
449 def eager_load(rows):
450 # \o/ circular imports.
451 from lp.registry.model.distroseries import DistroSeries
452- from lp.registry.model.gpgkey import GPGKey
453 ids = set(map(attrgetter('distroseriesID'), rows))
454 ids.discard(None)
455 if ids:
456@@ -698,10 +698,14 @@
457 ids.discard(None)
458 if ids:
459 list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(ids))
460- ids = set(map(attrgetter('dscsigningkeyID'), releases))
461- ids.discard(None)
462- if ids:
463- list(store.find(GPGKey, GPGKey.id.is_in(ids)))
464+ keys = {
465+ key.fingerprint: key for key in
466+ getUtility(IGPGKeySet).getByFingerprints(
467+ set(map(attrgetter('signing_key_fingerprint'), releases))
468+ - set([None]))}
469+ for spr in releases:
470+ get_property_cache(spr).dscsigningkey = keys.get(
471+ spr.signing_key_fingerprint)
472 return DecoratedResultSet(resultset, pre_iter_hook=eager_load)
473
474 def getSourcesForDeletion(self, name=None, status=None, distroseries=None):
475@@ -2537,9 +2541,9 @@
476 new_archive = Archive(
477 owner=owner, distribution=distribution, name=name,
478 displayname=displayname, description=description,
479- purpose=purpose, publish=publish, signing_key=signing_key,
480+ purpose=purpose, publish=publish, _signing_key=signing_key,
481 signing_key_owner=signing_key.owner if signing_key else None,
482- _signing_key_fingerprint=(
483+ signing_key_fingerprint=(
484 signing_key.fingerprint if signing_key else None),
485 require_virtualized=require_virtualized)
486
487@@ -2631,8 +2635,8 @@
488 SourcePackagePublishingHistory.archive == Archive.id))
489 results = IStore(Archive).using(*origin).find(
490 Archive,
491- Archive.signing_key == None, Archive.purpose == ArchivePurpose.PPA,
492- Archive._enabled == True)
493+ Archive.signing_key_fingerprint == None,
494+ Archive.purpose == ArchivePurpose.PPA, Archive._enabled == True)
495 results.order_by(Archive.date_created)
496 return results.config(distinct=True)
497
498
499=== modified file 'lib/lp/soyuz/model/queue.py'
500--- lib/lp/soyuz/model/queue.py 2016-02-23 02:00:00 +0000
501+++ lib/lp/soyuz/model/queue.py 2016-03-10 01:29:20 +0000
502@@ -46,6 +46,7 @@
503 from lp.archivepublisher.config import getPubConfig
504 from lp.archivepublisher.customupload import CustomUploadError
505 from lp.archiveuploader.tagfiles import parse_tagfile_content
506+from lp.registry.interfaces.gpg import IGPGKeySet
507 from lp.registry.interfaces.pocket import PackagePublishingPocket
508 from lp.registry.model.sourcepackagename import SourcePackageName
509 from lp.services.auditor.client import AuditorClient
510@@ -184,7 +185,7 @@
511
512 archive = ForeignKey(dbName="archive", foreignKey="Archive", notNull=True)
513
514- signing_key = ForeignKey(
515+ _signing_key = ForeignKey(
516 foreignKey='GPGKey', dbName='signing_key', notNull=False)
517 signing_key_owner_id = Int(name="signing_key_owner")
518 signing_key_owner = Reference(signing_key_owner_id, 'Person.id')
519@@ -291,6 +292,12 @@
520 })
521 return properties
522
523+ @cachedproperty
524+ def signing_key(self):
525+ if self.signing_key_fingerprint is not None:
526+ return getUtility(IGPGKeySet).getByFingerprint(
527+ self.signing_key_fingerprint)
528+
529 @property
530 def copy_source_archive(self):
531 """See `IPackageUpload`."""
532
533=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
534--- lib/lp/soyuz/model/sourcepackagerelease.py 2016-02-23 02:27:23 +0000
535+++ lib/lp/soyuz/model/sourcepackagerelease.py 2016-03-10 01:29:20 +0000
536@@ -35,10 +35,12 @@
537 from storm.store import Store
538 from zope.component import getUtility
539 from zope.interface import implementer
540+from zope.security.proxy import removeSecurityProxy
541
542 from lp.app.errors import NotFoundError
543 from lp.archiveuploader.utils import determine_source_file_type
544 from lp.buildmaster.enums import BuildStatus
545+from lp.registry.interfaces.gpg import IGPGKeySet
546 from lp.registry.interfaces.person import validate_public_person
547 from lp.registry.interfaces.sourcepackage import (
548 SourcePackageType,
549@@ -89,7 +91,7 @@
550 maintainer = ForeignKey(
551 dbName='maintainer', foreignKey='Person',
552 storm_validator=validate_public_person, notNull=True)
553- dscsigningkey = ForeignKey(foreignKey='GPGKey', dbName='dscsigningkey')
554+ _dscsigningkey = ForeignKey(foreignKey='GPGKey', dbName='dscsigningkey')
555 signing_key_owner_id = Int(name="signing_key_owner")
556 signing_key_owner = Reference(signing_key_owner_id, 'Person.id')
557 signing_key_fingerprint = Unicode()
558@@ -172,6 +174,15 @@
559 "UPDATE sourcepackagerelease SET copyright=%s WHERE id=%s",
560 (content, self.id))
561
562+ @cachedproperty
563+ def dscsigningkey(self):
564+ if self.signing_key_fingerprint is not None:
565+ # Stripping proxy as some tests expect this former FK to
566+ # hold an unsecured object. self is always proxied by things
567+ # that hold it, so no issue here.
568+ return removeSecurityProxy(getUtility(IGPGKeySet).getByFingerprint(
569+ self.signing_key_fingerprint))
570+
571 @property
572 def user_defined_fields(self):
573 """See `IBinaryPackageRelease`."""
574@@ -364,8 +375,8 @@
575 """See `ISourcePackageRelease`"""
576 if self.source_package_recipe_build is not None:
577 return self.source_package_recipe_build.requester
578- if self.dscsigningkey is not None:
579- return self.dscsigningkey.owner
580+ if self.signing_key_owner is not None:
581+ return self.signing_key_owner
582 return None
583
584 @property
585
586=== modified file 'lib/lp/soyuz/scripts/gina/handlers.py'
587--- lib/lp/soyuz/scripts/gina/handlers.py 2016-02-23 02:27:23 +0000
588+++ lib/lp/soyuz/scripts/gina/handlers.py 2016-03-10 01:29:20 +0000
589@@ -615,7 +615,7 @@
590 component=componentID,
591 sourcepackagename=name.id,
592 maintainer=maintainer.id,
593- dscsigningkey=key,
594+ _dscsigningkey=key,
595 signing_key_owner=key.owner if key else None,
596 signing_key_fingerprint=key.fingerprint if key else None,
597 urgency=ChangesFile.urgency_map[src.urgency],
598
599=== modified file 'lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py'
600--- lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py 2016-02-29 18:48:23 +0000
601+++ lib/lp/soyuz/scripts/tests/test_ppakeygenerator.py 2016-03-10 01:29:20 +0000
602@@ -10,6 +10,7 @@
603 from lp.registry.interfaces.distribution import IDistributionSet
604 from lp.registry.interfaces.gpg import IGPGKeySet
605 from lp.registry.interfaces.person import IPersonSet
606+from lp.services.propertycache import get_property_cache
607 from lp.services.scripts.base import LaunchpadScriptFailure
608 from lp.soyuz.interfaces.archive import IArchiveSet
609 from lp.soyuz.scripts.ppakeygenerator import PPAKeyGenerator
610@@ -52,7 +53,9 @@
611 def fake_key_generation(archive):
612 a_key = getUtility(IGPGKeySet).getByFingerprint(
613 'ABCDEF0123456789ABCDDCBA0000111112345678')
614- archive.signing_key = a_key
615+ archive.signing_key_fingerprint = a_key.fingerprint
616+ archive.signing_key_owner = a_key.owner
617+ del get_property_cache(archive).signing_key
618
619 key_generator.generateKey = fake_key_generation
620
621@@ -71,7 +74,8 @@
622 cprov = getUtility(IPersonSet).getByName('cprov')
623 a_key = getUtility(IGPGKeySet).getByFingerprint(
624 'ABCDEF0123456789ABCDDCBA0000111112345678')
625- cprov.archive.signing_key = a_key
626+ cprov.archive.signing_key_fingerprint = a_key.fingerprint
627+ cprov.archive.signing_key_owner = a_key.owner
628
629 key_generator = self._getKeyGenerator(
630 archive_reference='~cprov/ubuntu/ppa')
631
632=== modified file 'lib/lp/soyuz/stories/ppa/xx-private-ppa-subscriptions.txt'
633--- lib/lp/soyuz/stories/ppa/xx-private-ppa-subscriptions.txt 2016-02-29 18:48:23 +0000
634+++ lib/lp/soyuz/stories/ppa/xx-private-ppa-subscriptions.txt 2016-03-10 01:29:20 +0000
635@@ -174,7 +174,9 @@
636 >>> login('foo.bar@canonical.com')
637 >>> mark = getUtility(IPersonSet).getByName('mark')
638 >>> a_key = getUtility(IGPGKeySet).getByFingerprint('ABCDEF0123456789ABCDDCBA0000111112345678')
639- >>> removeSecurityProxy(mark_private_ppa).signing_key = a_key
640+ >>> removeSecurityProxy(mark_private_ppa).signing_key_fingerprint = (
641+ ... a_key.fingerprint)
642+ >>> removeSecurityProxy(mark_private_ppa).signing_key_owner = a_key.owner
643 >>> logout()
644
645 >>> joe_browser.reload()
646
647=== modified file 'lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt'
648--- lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt 2016-02-29 18:48:23 +0000
649+++ lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt 2016-03-10 01:29:20 +0000
650@@ -557,7 +557,9 @@
651 >>> login('foo.bar@canonical.com')
652 >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
653 >>> a_key = getUtility(IGPGKeySet).getByFingerprint('ABCDEF0123456789ABCDDCBA0000111112345678')
654- >>> removeSecurityProxy(no_priv.archive).signing_key = a_key
655+ >>> removeSecurityProxy(no_priv.archive).signing_key_fingerprint = (
656+ ... a_key.fingerprint)
657+ >>> removeSecurityProxy(no_priv.archive).signing_key_owner = a_key.owner
658 >>> logout()
659
660 Now that 'No privileges' PPA has a signing key, a text with the key
661
662=== modified file 'lib/lp/soyuz/stories/webservice/xx-archive.txt'
663--- lib/lp/soyuz/stories/webservice/xx-archive.txt 2016-01-05 15:06:24 +0000
664+++ lib/lp/soyuz/stories/webservice/xx-archive.txt 2016-03-10 01:29:20 +0000
665@@ -80,7 +80,10 @@
666 ABCDEF0123456789ABCDDCBA0000111112345678
667
668 >>> cprov = getUtility(IPersonSet).getByName('cprov')
669- >>> removeSecurityProxy(cprov.archive).signing_key = a_key
670+ >>> removeSecurityProxy(cprov.archive).signing_key_fingerprint = (
671+ ... a_key.fingerprint)
672+ >>> removeSecurityProxy(cprov.archive).signing_key_owner = (
673+ ... a_key.owner)
674 >>> print cprov.archive.signing_key_fingerprint
675 ABCDEF0123456789ABCDDCBA0000111112345678
676
677
678=== modified file 'lib/lp/soyuz/stories/webservice/xx-builds.txt'
679--- lib/lp/soyuz/stories/webservice/xx-builds.txt 2016-01-06 12:24:47 +0000
680+++ lib/lp/soyuz/stories/webservice/xx-builds.txt 2016-03-10 01:29:20 +0000
681@@ -22,7 +22,10 @@
682 >>> ppa = getUtility(IPersonSet).getByName('cprov').archive
683 >>> for pub in ppa.getPublishedSources():
684 ... pub = removeSecurityProxy(pub)
685- ... pub.sourcepackagerelease.dscsigningkey = fake_signer
686+ ... pub.sourcepackagerelease.signing_key_owner = (
687+ ... fake_signer.owner)
688+ ... pub.sourcepackagerelease.signing_key_fingerprint = (
689+ ... fake_signer.fingerprint)
690 >>> transaction.commit()
691 >>> logout()
692
693
694=== modified file 'lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt'
695--- lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2015-04-09 05:16:37 +0000
696+++ lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2016-03-10 01:29:20 +0000
697@@ -23,7 +23,9 @@
698 >>> cprov_ppa = cprov_db.archive
699 >>> for pub in cprov_ppa.getPublishedSources():
700 ... pub = removeSecurityProxy(pub)
701- ... pub.sourcepackagerelease.dscsigningkey = fake_signer
702+ ... pub.sourcepackagerelease.signing_key_owner = fake_signer.owner
703+ ... pub.sourcepackagerelease.signing_key_fingerprint = (
704+ ... fake_signer.fingerprint)
705 >>> logout()
706 >>> cprov_webservice = webservice_for_person(
707 ... cprov_db, permission=OAuthPermission.WRITE_PUBLIC)
708@@ -159,7 +161,8 @@
709 >>> login("foo.bar@canonical.com")
710 >>> for pub in cprov_ppa.getPublishedSources():
711 ... pub = removeSecurityProxy(pub)
712- ... pub.sourcepackagerelease.dscsigningkey = None
713+ ... pub.sourcepackagerelease.signing_key_owner = None
714+ ... pub.sourcepackagerelease.signing_key_fingerprint = None
715 >>> logout()
716
717 Query the source again:
718
719=== modified file 'lib/lp/soyuz/tests/test_archive.py'
720--- lib/lp/soyuz/tests/test_archive.py 2016-01-05 15:06:24 +0000
721+++ lib/lp/soyuz/tests/test_archive.py 2016-03-10 01:29:20 +0000
722@@ -42,7 +42,10 @@
723 from lp.services.database.interfaces import IStore
724 from lp.services.database.sqlbase import sqlvalues
725 from lp.services.job.interfaces.job import JobStatus
726-from lp.services.propertycache import clear_property_cache
727+from lp.services.propertycache import (
728+ clear_property_cache,
729+ get_property_cache,
730+ )
731 from lp.services.webapp.interfaces import OAuthPermission
732 from lp.services.worlddata.interfaces.country import ICountrySet
733 from lp.soyuz.adapters.archivedependencies import (
734@@ -3456,7 +3459,11 @@
735 owner=person, purpose=ArchivePurpose.PPA, name="ppa")
736 self.assertEqual(ppa, person.archive)
737 self.factory.makeGPGKey(person)
738- removeSecurityProxy(person.archive).signing_key = person.gpg_keys[0]
739+ key = person.gpg_keys[0]
740+ removeSecurityProxy(person.archive).signing_key_owner = key.owner
741+ removeSecurityProxy(person.archive).signing_key_fingerprint = (
742+ key.fingerprint)
743+ del get_property_cache(person.archive).signing_key
744 ppa_with_key = self.factory.makeArchive(
745 owner=person, purpose=ArchivePurpose.PPA)
746 self.assertEqual(person.gpg_keys[0], ppa_with_key.signing_key)
747
748=== modified file 'lib/lp/soyuz/tests/test_build_notify.py'
749--- lib/lp/soyuz/tests/test_build_notify.py 2015-09-11 12:20:23 +0000
750+++ lib/lp/soyuz/tests/test_build_notify.py 2016-03-10 01:29:20 +0000
751@@ -15,6 +15,7 @@
752 from lp.registry.interfaces.person import IPersonSet
753 from lp.services.config import config
754 from lp.services.mail.sendmail import format_address_for_person
755+from lp.services.propertycache import get_property_cache
756 from lp.services.webapp import canonical_url
757 from lp.soyuz.enums import ArchivePurpose
758 from lp.soyuz.interfaces.publishing import PackagePublishingPocket
759@@ -83,7 +84,11 @@
760 self.factory.getUniqueInteger(), status.value),
761 distroseries=self.distroseries, architecturehintlist='any',
762 creator=self.creator, archive=archive)
763- spph.sourcepackagerelease.dscsigningkey = self.gpgkey
764+ spph.sourcepackagerelease._dscsigningkey = self.gpgkey
765+ spph.sourcepackagerelease.signing_key_fingerprint = (
766+ self.gpgkey.fingerprint)
767+ spph.sourcepackagerelease.signing_key_owner = (
768+ self.gpgkey.owner)
769 [build] = spph.createMissingBuilds()
770 with person_logged_in(self.admin):
771 build.updateStatus(BuildStatus.BUILDING, builder=self.builder)
772@@ -432,7 +437,9 @@
773 build = self.builds[BuildStatus.FAILEDTOBUILD.value]
774 spr = build.current_source_publication.sourcepackagerelease
775 # Push past the security proxy
776- removeSecurityProxy(spr).dscsigningkey = key
777+ removeSecurityProxy(spr).signing_key_owner = key.owner
778+ removeSecurityProxy(spr).signing_key_fingerprint = key.fingerprint
779+ del get_property_cache(spr).dscsigningkey
780 with dbuser(config.builddmaster.dbuser):
781 build.notify()
782 expected_reasons = [
783
784=== modified file 'utilities/soyuz-sampledata-setup.py'
785--- utilities/soyuz-sampledata-setup.py 2015-10-13 13:22:08 +0000
786+++ utilities/soyuz-sampledata-setup.py 2016-03-10 01:29:20 +0000
787@@ -316,7 +316,8 @@
788 if signedcocset.searchByUser(person_id).count() == 0:
789 fake_gpg_key = LaunchpadObjectFactory().makeGPGKey(person)
790 Store.of(person).add(SignedCodeOfConduct(
791- owner=person, signingkey=fake_gpg_key,
792+ owner=person, signing_key_fingerprint=fake_gpg_key.fingerprint,
793+ signing_key_owner=fake_gpg_key.owner,
794 signedcode="Normally a signed CoC would go here.", active=True))
795
796