Merge lp:~jelmer/brz/gpg-detached-sign into lp:brz
- gpg-detached-sign
- Merge into trunk
Proposed by
Jelmer Vernooij
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Jelmer Vernooij | ||||
Approved revision: | no longer in the source branch. | ||||
Merge reported by: | The Breezy Bot | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~jelmer/brz/gpg-detached-sign | ||||
Merge into: | lp:brz | ||||
Diff against target: |
448 lines (+73/-111) 8 files modified
breezy/bzr/remote.py (+5/-3) breezy/gpg.py (+39/-31) breezy/merge_directive.py (+1/-1) breezy/repository.py (+6/-5) breezy/tests/per_repository/test_signatures.py (+1/-1) breezy/tests/test_commit.py (+2/-1) breezy/tests/test_gpg.py (+13/-54) breezy/tests/test_log.py (+6/-15) |
||||
To merge this branch: | bzr merge lp:~jelmer/brz/gpg-detached-sign | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Packman | Approve | ||
Review via email: mp+341287@code.launchpad.net |
Commit message
Add support for passing mode argument to GPGSignature.sign.
Description of the change
Add support for passing mode argument to GPGSignature.sign.
This is necessary for brz-git, which needs to create detached signatures.
To post a comment you must log in.
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/bzr/remote.py' |
2 | --- breezy/bzr/remote.py 2017-11-23 20:02:55 +0000 |
3 | +++ breezy/bzr/remote.py 2018-03-24 01:56:28 +0000 |
4 | @@ -2692,7 +2692,7 @@ |
5 | |
6 | def store_revision_signature(self, gpg_strategy, plaintext, revision_id): |
7 | with self.lock_write(): |
8 | - signature = gpg_strategy.sign(plaintext) |
9 | + signature = gpg_strategy.sign(plaintext, gpg.MODE_CLEAR) |
10 | self.add_signature_text(revision_id, signature) |
11 | |
12 | def add_signature_text(self, revision_id, signature): |
13 | @@ -2737,9 +2737,11 @@ |
14 | signature = self.get_signature_text(revision_id) |
15 | |
16 | testament = _mod_testament.Testament.from_revision(self, revision_id) |
17 | - plaintext = testament.as_short_text() |
18 | |
19 | - return gpg_strategy.verify(signature, plaintext) |
20 | + (status, key, signed_plaintext) = gpg_strategy.verify(signature) |
21 | + if testament.as_short_text() != signed_plaintext: |
22 | + return gpg.SIGNATURE_NOT_VALID, None |
23 | + return (status, key) |
24 | |
25 | def item_keys_introduced_by(self, revision_ids, _files_pb=None): |
26 | self._ensure_real() |
27 | |
28 | === modified file 'breezy/gpg.py' |
29 | --- breezy/gpg.py 2018-02-24 15:50:23 +0000 |
30 | +++ breezy/gpg.py 2018-03-24 01:56:28 +0000 |
31 | @@ -52,6 +52,10 @@ |
32 | SIGNATURE_NOT_SIGNED = 3 |
33 | SIGNATURE_EXPIRED = 4 |
34 | |
35 | +MODE_NORMAL = 0 |
36 | +MODE_DETACH = 1 |
37 | +MODE_CLEAR = 2 |
38 | + |
39 | |
40 | class GpgNotInstalled(errors.DependencyNotPresent): |
41 | |
42 | @@ -123,10 +127,10 @@ |
43 | def __init__(self, ignored): |
44 | """Real strategies take a configuration.""" |
45 | |
46 | - def sign(self, content): |
47 | + def sign(self, content, mode): |
48 | raise SigningFailed('Signing is disabled.') |
49 | |
50 | - def verify(self, content, testament): |
51 | + def verify(self, signed_data, signature=None): |
52 | raise SignatureVerificationFailed('Signature verification is \ |
53 | disabled.') |
54 | |
55 | @@ -146,12 +150,14 @@ |
56 | def __init__(self, ignored): |
57 | """Real strategies take a configuration.""" |
58 | |
59 | - def sign(self, content): |
60 | + def sign(self, content, mode): |
61 | return ("-----BEGIN PSEUDO-SIGNED CONTENT-----\n" + content + |
62 | "-----END PSEUDO-SIGNED CONTENT-----\n") |
63 | |
64 | - def verify(self, content, testament): |
65 | - return SIGNATURE_VALID, None |
66 | + def verify(self, signed_data, signature=None): |
67 | + plain_text = signed_data.replace("-----BEGIN PSEUDO-SIGNED CONTENT-----\n", "") |
68 | + plain_text = plain_text.replace("-----END PSEUDO-SIGNED CONTENT-----\n", "") |
69 | + return SIGNATURE_VALID, None, plain_text |
70 | |
71 | def set_acceptable_keys(self, command_line_input): |
72 | if command_line_input is not None: |
73 | @@ -187,11 +193,11 @@ |
74 | try: |
75 | import gpg |
76 | self.context = gpg.Context() |
77 | + self.context.armor = True |
78 | + self.context.signers = self._get_signing_keys() |
79 | except ImportError as error: |
80 | pass # can't use verify() |
81 | |
82 | - self.context.signers = self._get_signing_keys() |
83 | - |
84 | def _get_signing_keys(self): |
85 | import gpg |
86 | keyname = self._config_stack.get('gpg_signing_key') |
87 | @@ -224,7 +230,7 @@ |
88 | except ImportError as error: |
89 | return False |
90 | |
91 | - def sign(self, content): |
92 | + def sign(self, content, mode): |
93 | import gpg |
94 | if isinstance(content, unicode): |
95 | raise errors.BzrBadParameterUnicode('content') |
96 | @@ -232,29 +238,34 @@ |
97 | plain_text = gpg.Data(content) |
98 | try: |
99 | output, result = self.context.sign( |
100 | - plain_text, mode=gpg.constants.sig.mode.CLEAR) |
101 | + plain_text, mode={ |
102 | + MODE_DETACH: gpg.constants.sig.mode.DETACH, |
103 | + MODE_CLEAR: gpg.constants.sig.mode.CLEAR, |
104 | + MODE_NORMAL: gpg.constants.sig.mode.NORMAL, |
105 | + }[mode]) |
106 | except gpg.errors.GPGMEError as error: |
107 | raise SigningFailed(str(error)) |
108 | |
109 | return output |
110 | |
111 | - def verify(self, content, testament): |
112 | + def verify(self, signed_data, signature=None): |
113 | """Check content has a valid signature. |
114 | |
115 | - :param content: the commit signature |
116 | - :param testament: the valid testament string for the commit |
117 | + :param signed_data; Signed data |
118 | + :param signature: optional signature (if detached) |
119 | |
120 | - :return: SIGNATURE_VALID or a failed SIGNATURE_ value, key uid if valid |
121 | + :return: SIGNATURE_VALID or a failed SIGNATURE_ value, key uid if valid, plain text |
122 | """ |
123 | try: |
124 | import gpg |
125 | except ImportError as error: |
126 | raise errors.GpgNotInstalled(error) |
127 | |
128 | - signature = gpg.Data(content) |
129 | - sink = gpg.Data() |
130 | + signed_data = gpg.Data(signed_data) |
131 | + if signature: |
132 | + signature = gpg.Data(signature) |
133 | try: |
134 | - plain_output, result = self.context.verify(signature) |
135 | + plain_output, result = self.context.verify(signed_data, signature) |
136 | except gpg.errors.BadSignatures as error: |
137 | fingerprint = error.result.signatures[0].fpr |
138 | if error.result.signatures[0].summary & gpg.constants.SIGSUM_KEY_EXPIRED: |
139 | @@ -262,35 +273,32 @@ |
140 | if expires > error.result.signatures[0].timestamp: |
141 | # The expired key was not expired at time of signing. |
142 | # test_verify_expired_but_valid() |
143 | - return SIGNATURE_EXPIRED, fingerprint[-8:] |
144 | + return SIGNATURE_EXPIRED, fingerprint[-8:], None |
145 | else: |
146 | # I can't work out how to create a test where the signature |
147 | # was expired at the time of signing. |
148 | - return SIGNATURE_NOT_VALID, None |
149 | + return SIGNATURE_NOT_VALID, None, None |
150 | |
151 | # GPG does not know this key. |
152 | # test_verify_unknown_key() |
153 | if error.result.signatures[0].summary & gpg.constants.SIGSUM_KEY_MISSING: |
154 | - return SIGNATURE_KEY_MISSING, fingerprint[-8:] |
155 | + return SIGNATURE_KEY_MISSING, fingerprint[-8:], None |
156 | |
157 | - return SIGNATURE_NOT_VALID, None |
158 | + return SIGNATURE_NOT_VALID, None, None |
159 | except gpg.errors.GPGMEError as error: |
160 | - raise SignatureVerificationFailed(error[2]) |
161 | + raise SignatureVerificationFailed(error) |
162 | |
163 | # No result if input is invalid. |
164 | # test_verify_invalid() |
165 | if len(result.signatures) == 0: |
166 | - return SIGNATURE_NOT_VALID, None |
167 | + return SIGNATURE_NOT_VALID, None, plain_output |
168 | + |
169 | # User has specified a list of acceptable keys, check our result is in |
170 | # it. test_verify_unacceptable_key() |
171 | fingerprint = result.signatures[0].fpr |
172 | if self.acceptable_keys is not None: |
173 | if not fingerprint in self.acceptable_keys: |
174 | - return SIGNATURE_KEY_MISSING, fingerprint[-8:] |
175 | - # Check the signature actually matches the testament. |
176 | - # test_verify_bad_testament() |
177 | - if testament != plain_output: |
178 | - return SIGNATURE_NOT_VALID, None |
179 | + return SIGNATURE_KEY_MISSING, fingerprint[-8:], plain_output |
180 | # Yay gpg set the valid bit. |
181 | # Can't write a test for this one as you can't set a key to be |
182 | # trusted using gpg. |
183 | @@ -298,20 +306,20 @@ |
184 | key = self.context.get_key(fingerprint) |
185 | name = key.uids[0].name |
186 | email = key.uids[0].email |
187 | - return SIGNATURE_VALID, name + " <" + email + ">" |
188 | + return SIGNATURE_VALID, name.decode('utf-8') + u" <" + email.decode('utf-8') + u">", plain_output |
189 | # Sigsum_red indicates a problem, unfortunatly I have not been able |
190 | # to write any tests which actually set this. |
191 | if result.signatures[0].summary & gpg.constants.SIGSUM_RED: |
192 | - return SIGNATURE_NOT_VALID, None |
193 | + return SIGNATURE_NOT_VALID, None, plain_output |
194 | # Summary isn't set if sig is valid but key is untrusted but if user |
195 | # has explicity set the key as acceptable we can validate it. |
196 | if result.signatures[0].summary == 0 and self.acceptable_keys is not None: |
197 | if fingerprint in self.acceptable_keys: |
198 | # test_verify_untrusted_but_accepted() |
199 | - return SIGNATURE_VALID, None |
200 | + return SIGNATURE_VALID, None, plain_output |
201 | # test_verify_valid_but_untrusted() |
202 | if result.signatures[0].summary == 0 and self.acceptable_keys is None: |
203 | - return SIGNATURE_NOT_VALID, None |
204 | + return SIGNATURE_NOT_VALID, None, plain_output |
205 | # Other error types such as revoked keys should (I think) be caught by |
206 | # SIGSUM_RED so anything else means something is buggy. |
207 | raise SignatureVerificationFailed( |
208 | |
209 | === modified file 'breezy/merge_directive.py' |
210 | --- breezy/merge_directive.py 2017-10-27 00:18:42 +0000 |
211 | +++ breezy/merge_directive.py 2018-03-24 01:56:28 +0000 |
212 | @@ -251,7 +251,7 @@ |
213 | :return: a string |
214 | """ |
215 | my_gpg = gpg.GPGStrategy(branch.get_config_stack()) |
216 | - return my_gpg.sign(''.join(self.to_lines())) |
217 | + return my_gpg.sign(''.join(self.to_lines()), gpg.MODE_CLEAR) |
218 | |
219 | def to_email(self, mail_to, branch, sign=False): |
220 | """Serialize as an email message. |
221 | |
222 | === modified file 'breezy/repository.py' |
223 | --- breezy/repository.py 2018-02-24 15:50:23 +0000 |
224 | +++ breezy/repository.py 2018-03-24 01:56:28 +0000 |
225 | @@ -887,7 +887,7 @@ |
226 | |
227 | def store_revision_signature(self, gpg_strategy, plaintext, revision_id): |
228 | with self.lock_write(): |
229 | - signature = gpg_strategy.sign(plaintext) |
230 | + signature = gpg_strategy.sign(plaintext, gpg.MODE_CLEAR) |
231 | self.add_signature_text(revision_id, signature) |
232 | |
233 | def add_signature_text(self, revision_id, signature): |
234 | @@ -1104,11 +1104,12 @@ |
235 | return gpg.SIGNATURE_NOT_SIGNED, None |
236 | signature = self.get_signature_text(revision_id) |
237 | |
238 | - testament = _mod_testament.Testament.from_revision( |
239 | - self, revision_id) |
240 | - plaintext = testament.as_short_text() |
241 | + testament = _mod_testament.Testament.from_revision(self, revision_id) |
242 | |
243 | - return gpg_strategy.verify(signature, plaintext) |
244 | + (status, key, signed_plaintext) = gpg_strategy.verify(signature) |
245 | + if testament.as_short_text() != signed_plaintext: |
246 | + return gpg.SIGNATURE_NOT_VALID, None |
247 | + return (status, key) |
248 | |
249 | def verify_revision_signatures(self, revision_ids, gpg_strategy): |
250 | """Verify revision signatures for a number of revisions. |
251 | |
252 | === modified file 'breezy/tests/per_repository/test_signatures.py' |
253 | --- breezy/tests/per_repository/test_signatures.py 2017-08-07 19:09:47 +0000 |
254 | +++ breezy/tests/per_repository/test_signatures.py 2018-03-24 01:56:28 +0000 |
255 | @@ -123,7 +123,7 @@ |
256 | '-----END PSEUDO-SIGNED CONTENT-----\n', |
257 | repo.get_signature_text(a)) |
258 | self.assertEqual( |
259 | - (gpg.SIGNATURE_VALID, None, ), |
260 | + (gpg.SIGNATURE_VALID, None), |
261 | repo.verify_revision_signature(a, strategy)) |
262 | |
263 | def test_verify_revision_signatures(self): |
264 | |
265 | === modified file 'breezy/tests/test_commit.py' |
266 | --- breezy/tests/test_commit.py 2018-02-15 19:38:33 +0000 |
267 | +++ breezy/tests/test_commit.py 2018-03-24 01:56:28 +0000 |
268 | @@ -435,7 +435,8 @@ |
269 | message="base", allow_pointless=True, rev_id='B', |
270 | working_tree=wt) |
271 | def sign(text): |
272 | - return breezy.gpg.LoopbackGPGStrategy(None).sign(text) |
273 | + return breezy.gpg.LoopbackGPGStrategy(None).sign( |
274 | + text, breezy.gpg.MODE_CLEAR) |
275 | self.assertEqual(sign(Testament.from_revision(branch.repository, |
276 | 'B').as_short_text()), |
277 | branch.repository.get_signature_text('B')) |
278 | |
279 | === modified file 'breezy/tests/test_gpg.py' |
280 | --- breezy/tests/test_gpg.py 2017-07-04 20:03:11 +0000 |
281 | +++ breezy/tests/test_gpg.py 2018-03-24 01:56:28 +0000 |
282 | @@ -224,8 +224,7 @@ |
283 | """ |
284 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
285 | my_gpg.set_acceptable_keys("bazaar@example.com") |
286 | - self.assertEqual((gpg.SIGNATURE_VALID, None), my_gpg.verify(content, |
287 | - plain)) |
288 | + self.assertEqual((gpg.SIGNATURE_VALID, None, plain), my_gpg.verify(content)) |
289 | |
290 | def test_verify_unacceptable_key(self): |
291 | self.requireFeature(features.gpg) |
292 | @@ -255,8 +254,8 @@ |
293 | """ |
294 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
295 | my_gpg.set_acceptable_keys("foo@example.com") |
296 | - self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45'), |
297 | - my_gpg.verify(content, plain)) |
298 | + self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'E3080E45', plain), |
299 | + my_gpg.verify(content)) |
300 | |
301 | def test_verify_valid_but_untrusted(self): |
302 | self.requireFeature(features.gpg) |
303 | @@ -285,40 +284,7 @@ |
304 | sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 |
305 | """ |
306 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
307 | - self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content, |
308 | - plain)) |
309 | - |
310 | - def test_verify_bad_testament(self): |
311 | - self.requireFeature(features.gpg) |
312 | - self.import_keys() |
313 | - |
314 | - content = """-----BEGIN PGP SIGNED MESSAGE----- |
315 | -Hash: SHA1 |
316 | - |
317 | -bazaar-ng testament short form 1 |
318 | -revision-id: amy@example.com-20110527185938-hluafawphszb8dl1 |
319 | -sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 |
320 | ------BEGIN PGP SIGNATURE----- |
321 | -Version: GnuPG v1.4.11 (GNU/Linux) |
322 | - |
323 | -iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk |
324 | -FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+ |
325 | -6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx |
326 | -7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG |
327 | -rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6 |
328 | -NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8= |
329 | -=iwsn |
330 | ------END PGP SIGNATURE----- |
331 | -""" |
332 | - plain = """bazaar-ng testament short form 1 |
333 | -revision-id: doctor@example.com-20110527185938-hluafawphszb8dl1 |
334 | -sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 |
335 | -""" |
336 | - my_gpg = gpg.GPGStrategy(FakeConfig()) |
337 | - my_gpg.set_acceptable_keys("bazaar@example.com") |
338 | - self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content, |
339 | - plain)) |
340 | - |
341 | + self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, plain), my_gpg.verify(content)) |
342 | |
343 | def test_verify_revoked_signature(self): |
344 | self.requireFeature(features.gpg) |
345 | @@ -341,8 +307,7 @@ |
346 | plain = """asdf\n""" |
347 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
348 | my_gpg.set_acceptable_keys("test@example.com") |
349 | - self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content, |
350 | - plain)) |
351 | + self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, None), my_gpg.verify(content)) |
352 | |
353 | def test_verify_invalid(self): |
354 | self.requireFeature(features.gpg) |
355 | @@ -366,8 +331,8 @@ |
356 | sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 |
357 | """ |
358 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
359 | - self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), |
360 | - my_gpg.verify(content, plain)) |
361 | + self.assertEqual((gpg.SIGNATURE_NOT_VALID, None, plain), |
362 | + my_gpg.verify(content)) |
363 | |
364 | def test_verify_expired_but_valid(self): |
365 | self.requireFeature(features.gpg) |
366 | @@ -388,13 +353,9 @@ |
367 | =uHen |
368 | -----END PGP SIGNATURE----- |
369 | """ |
370 | - plain = """bazaar-ng testament short form 1 |
371 | -revision-id: test@example.com-20110801100657-f1dr1nompeex723z |
372 | -sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb |
373 | -""" |
374 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
375 | - self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'), |
376 | - my_gpg.verify(content, plain)) |
377 | + self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513', None), |
378 | + my_gpg.verify(content)) |
379 | |
380 | def test_verify_unknown_key(self): |
381 | self.requireFeature(features.gpg) |
382 | @@ -415,10 +376,9 @@ |
383 | =RNR5 |
384 | -----END PGP SIGNATURE----- |
385 | """ |
386 | - plain = "asdf\n" |
387 | my_gpg = gpg.GPGStrategy(FakeConfig()) |
388 | - self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'), |
389 | - my_gpg.verify(content, plain)) |
390 | + self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F', None), |
391 | + my_gpg.verify(content)) |
392 | |
393 | def test_set_acceptable_keys(self): |
394 | self.requireFeature(features.gpg) |
395 | @@ -454,9 +414,8 @@ |
396 | |
397 | def test_sign(self): |
398 | self.assertRaises(gpg.SigningFailed, |
399 | - gpg.DisabledGPGStrategy(None).sign, 'content') |
400 | + gpg.DisabledGPGStrategy(None).sign, 'content', gpg.MODE_CLEAR) |
401 | |
402 | def test_verify(self): |
403 | self.assertRaises(gpg.SignatureVerificationFailed, |
404 | - gpg.DisabledGPGStrategy(None).verify, 'content', |
405 | - 'testament') |
406 | + gpg.DisabledGPGStrategy(None).verify, 'content') |
407 | |
408 | === modified file 'breezy/tests/test_log.py' |
409 | --- breezy/tests/test_log.py 2017-12-04 00:25:02 +0000 |
410 | +++ breezy/tests/test_log.py 2018-03-24 01:56:28 +0000 |
411 | @@ -317,31 +317,22 @@ |
412 | |
413 | |
414 | class TestFormatSignatureValidity(tests.TestCaseWithTransport): |
415 | - class UTFLoopbackGPGStrategy(gpg.LoopbackGPGStrategy): |
416 | - def verify(self, content, testament): |
417 | - return (gpg.SIGNATURE_VALID, |
418 | - u'UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>') |
419 | - |
420 | - def has_signature_for_revision_id(self, revision_id): |
421 | - return True |
422 | - |
423 | - def get_signature_text(self, revision_id): |
424 | - return '' |
425 | + |
426 | + def verify_revision_signature(self, revid, gpg_strategy): |
427 | + return (gpg.SIGNATURE_VALID, |
428 | + u'UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>') |
429 | |
430 | def test_format_signature_validity_utf(self): |
431 | """Check that GPG signatures containing UTF-8 names are formatted |
432 | correctly.""" |
433 | - # Monkey patch to use our UTF-8 generating GPGStrategy |
434 | - self.overrideAttr(gpg, 'GPGStrategy', self.UTFLoopbackGPGStrategy) |
435 | wt = self.make_branch_and_tree('.') |
436 | revid = wt.commit('empty commit') |
437 | repo = wt.branch.repository |
438 | # Monkey patch out checking if this rev is actually signed, since we |
439 | # can't sign it without a heavier TestCase and LoopbackGPGStrategy |
440 | # doesn't care anyways. |
441 | - self.overrideAttr(repo, 'has_signature_for_revision_id', |
442 | - self.has_signature_for_revision_id) |
443 | - self.overrideAttr(repo, 'get_signature_text', self.get_signature_text) |
444 | + self.overrideAttr(repo, 'verify_revision_signature', |
445 | + self.verify_revision_signature) |
446 | out = log.format_signature_validity(revid, wt.branch) |
447 | self.assertEqual( |
448 | u'valid signature from UTF8 Test \xa1\xb1\xc1\xd1\xe1\xf1 <jrandom@example.com>', |
Thanks, so questions answered, constants are the same as the mapping, but the breezy interface doesn't depend on gpg module being installed. Also, argument not defaulted as bzr wants clear but git needs detached, so better to just pass.