qt: Handle if gpg does not support tofu in test
[gpgme.git] / lang / python / tests / t-callbacks.py
1 #!/usr/bin/env python
2
3 # Copyright (C) 2016 g10 Code GmbH
4 #
5 # This file is part of GPGME.
6 #
7 # GPGME is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # GPGME is distributed in the hope that it will be useful, but WITHOUT
13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
15 # Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this program; if not, see <http://www.gnu.org/licenses/>.
19
20 from __future__ import absolute_import, print_function, unicode_literals
21 del absolute_import, print_function, unicode_literals
22
23 import os
24 import gpg
25 import support
26
27 support.assert_gpg_version()
28
29 c = gpg.Context()
30 c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
31
32 source = gpg.Data("Hallo Leute\n")
33 sink = gpg.Data()
34
35 # Valid passphrases, both as string and bytes.
36 for passphrase in ('foo', b'foo'):
37     def passphrase_cb(hint, desc, prev_bad, hook=None):
38         assert hook == passphrase
39         return hook
40
41     c.set_passphrase_cb(passphrase_cb, passphrase)
42     c.op_encrypt([], 0, source, sink)
43
44 # Returning an invalid type.
45 def passphrase_cb(hint, desc, prev_bad, hook=None):
46     return 0
47
48 c.set_passphrase_cb(passphrase_cb, None)
49 try:
50     c.op_encrypt([], 0, source, sink)
51 except Exception as e:
52     assert type(e) == TypeError
53     assert str(e) == "expected str or bytes from passphrase callback, got int"
54 else:
55     assert False, "Expected an error, got none"
56
57 # Raising an exception inside callback.
58 myException = Exception()
59 def passphrase_cb(hint, desc, prev_bad, hook=None):
60     raise myException
61
62 c.set_passphrase_cb(passphrase_cb, None)
63 try:
64     c.op_encrypt([], 0, source, sink)
65 except Exception as e:
66     assert e == myException
67 else:
68     assert False, "Expected an error, got none"
69
70 # Wrong kind of callback function.
71 def bad_passphrase_cb():
72     pass
73
74 c.set_passphrase_cb(bad_passphrase_cb, None)
75 try:
76     c.op_encrypt([], 0, source, sink)
77 except Exception as e:
78     assert type(e) == TypeError
79 else:
80     assert False, "Expected an error, got none"
81
82
83
84 # Test the progress callback.
85 parms = """<GnupgKeyParms format="internal">
86 Key-Type: RSA
87 Key-Length: 1024
88 Name-Real: Joe Tester
89 Name-Comment: with stupid passphrase
90 Name-Email: joe+gpg@example.org
91 Passphrase: Crypt0R0cks
92 Expire-Date: 2020-12-31
93 </GnupgKeyParms>
94 """
95
96 messages = []
97 def progress_cb(what, typ, current, total, hook=None):
98     assert hook == messages
99     messages.append(
100         "PROGRESS UPDATE: what = {}, type = {}, current = {}, total = {}"
101         .format(what, typ, current, total))
102
103 c = gpg.Context()
104 c.set_progress_cb(progress_cb, messages)
105 c.op_genkey(parms, None, None)
106 assert len(messages) > 0
107
108 # Test exception handling.
109 def progress_cb(what, typ, current, total, hook=None):
110     raise myException
111
112 c = gpg.Context()
113 c.set_progress_cb(progress_cb, None)
114 try:
115     c.op_genkey(parms, None, None)
116 except Exception as e:
117     assert e == myException
118 else:
119     assert False, "Expected an error, got none"
120
121
122 # Test the edit callback.
123 c = gpg.Context()
124 c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
125 c.set_passphrase_cb(lambda *args: "abc")
126 sink = gpg.Data()
127 alpha = c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False)
128
129 cookie = object()
130 edit_cb_called = False
131 def edit_cb(status, args, hook):
132     global edit_cb_called
133     edit_cb_called = True
134     assert hook == cookie
135     return "quit" if args == "keyedit.prompt" else None
136 c.op_edit(alpha, edit_cb, cookie, sink)
137 assert edit_cb_called
138
139 # Test exceptions.
140 c = gpg.Context()
141 c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
142 c.set_passphrase_cb(lambda *args: "abc")
143 sink = gpg.Data()
144
145 def edit_cb(status, args):
146     raise myException
147 try:
148     c.op_edit(alpha, edit_cb, None, sink)
149 except Exception as e:
150     assert e == myException
151 else:
152     assert False, "Expected an error, got none"
153
154
155
156 # Test the status callback.
157 source = gpg.Data("Hallo Leute\n")
158 sink = gpg.Data()
159
160 status_cb_called = False
161 def status_cb(keyword, args, hook=None):
162     global status_cb_called
163     status_cb_called = True
164     assert hook == cookie
165
166 c = gpg.Context()
167 c.set_status_cb(status_cb, cookie)
168 c.set_ctx_flag("full-status", "1")
169 c.op_encrypt([alpha], gpg.constants.ENCRYPT_ALWAYS_TRUST, source, sink)
170 assert status_cb_called
171
172 # Test exceptions.
173 source = gpg.Data("Hallo Leute\n")
174 sink = gpg.Data()
175
176 def status_cb(keyword, args):
177     raise myException
178
179 c = gpg.Context()
180 c.set_status_cb(status_cb, None)
181 c.set_ctx_flag("full-status", "1")
182 try:
183     c.op_encrypt([alpha], gpg.constants.ENCRYPT_ALWAYS_TRUST, source, sink)
184 except Exception as e:
185     assert e == myException
186 else:
187     assert False, "Expected an error, got none"
188
189
190
191 # Test the data callbacks.
192 def read_cb(amount, hook=None):
193     assert hook == cookie
194     return 0
195 def release_cb(hook=None):
196     assert hook == cookie
197 data = gpg.Data(cbs=(read_cb, None, None, release_cb, cookie))
198 try:
199     data.read()
200 except Exception as e:
201     assert type(e) == TypeError
202 else:
203     assert False, "Expected an error, got none"
204
205 def read_cb(amount):
206     raise myException
207 data = gpg.Data(cbs=(read_cb, None, None, lambda: None))
208 try:
209     data.read()
210 except Exception as e:
211     assert e == myException
212 else:
213     assert False, "Expected an error, got none"
214
215
216 def write_cb(what, hook=None):
217     assert hook == cookie
218     return "wrong type"
219 data = gpg.Data(cbs=(None, write_cb, None, release_cb, cookie))
220 try:
221     data.write(b'stuff')
222 except Exception as e:
223     assert type(e) == TypeError
224 else:
225     assert False, "Expected an error, got none"
226
227 def write_cb(what):
228     raise myException
229 data = gpg.Data(cbs=(None, write_cb, None, lambda: None))
230 try:
231     data.write(b'stuff')
232 except Exception as e:
233     assert e == myException
234 else:
235     assert False, "Expected an error, got none"
236
237
238 def seek_cb(offset, whence, hook=None):
239     assert hook == cookie
240     return "wrong type"
241 data = gpg.Data(cbs=(None, None, seek_cb, release_cb, cookie))
242 try:
243     data.seek(0, os.SEEK_SET)
244 except Exception as e:
245     assert type(e) == TypeError
246 else:
247     assert False, "Expected an error, got none"
248
249 def seek_cb(offset, whence):
250     raise myException
251 data = gpg.Data(cbs=(None, None, seek_cb, lambda: None))
252 try:
253     data.seek(0, os.SEEK_SET)
254 except Exception as e:
255     assert e == myException
256 else:
257     assert False, "Expected an error, got none"