]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.api/test_cryptokeys.py
Merge pull request #14021 from Habbie/auth-lua-join-whitespace
[thirdparty/pdns.git] / regression-tests.api / test_cryptokeys.py
CommitLineData
ad918272
BZ
1import subprocess
2import json
3import unittest
86b3e4e8 4import os
ad918272 5
541bb91b 6from test_helper import ApiTestCase, is_auth, pdnsutil, unique_zone_name
ad918272
BZ
7
8@unittest.skipIf(not is_auth(), "Not applicable")
9class Cryptokeys(ApiTestCase):
ad918272 10
541bb91b
CH
11 def setUp(self):
12 super(Cryptokeys, self).setUp()
86b3e4e8 13 self.keyid = 0
541bb91b
CH
14 self.zone = unique_zone_name()
15 self.zone_nodot = self.zone[:-1]
16 payload = {
17 'name': self.zone,
18 'kind': 'Native',
19 'nameservers': ['ns1.example.com.', 'ns2.example.com.']
20 }
21 r = self.session.post(
22 self.url("/api/v1/servers/localhost/zones"),
23 data=json.dumps(payload),
24 headers={'content-type': 'application/json'})
25 self.assert_success_json(r)
4bfebc93 26 self.assertEqual(r.status_code, 201)
ad918272
BZ
27
28 def tearDown(self):
541bb91b 29 super(Cryptokeys, self).tearDown()
86b3e4e8
BZ
30 self.remove_zone_key(self.keyid)
31
32 # Adding a key to self.zone using the pdnsutil command
33918299
RG
33 def add_zone_key(self, status=['inactive']):
34 return pdnsutil("add-zone-key", self.zone_nodot, "ksk", *status)
ad918272 35
86b3e4e8
BZ
36 # Removes a key from self.zone by id using the pdnsutil command
37 def remove_zone_key(self, key_id):
541bb91b 38 return pdnsutil("remove-zone-key", self.zone_nodot, str(key_id))
86b3e4e8
BZ
39
40 # This method tests the DELETE api call.
41 def test_delete(self):
42 self.keyid = self.add_zone_key()
ad918272
BZ
43
44 #checks the status code. I don't know how to test explicit that the backend fail removing a key.
86b3e4e8 45 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid))
4bfebc93
CH
46 self.assertEqual(r.status_code, 204)
47 self.assertEqual(r.content, b"")
ad918272
BZ
48
49 # Check that the key is actually deleted
541bb91b
CH
50 out = pdnsutil("list-keys", self.zone)
51 self.assertNotIn(self.zone, out)
ad918272 52
77bfe8de
PL
53 def test_get_wrong_zone(self):
54 self.keyid = self.add_zone_key()
55 r = self.session.get(self.url("/api/v1/servers/localhost/zones/"+self.zone+"fail/cryptokeys/"+self.keyid))
4bfebc93 56 self.assertEqual(r.status_code, 404)
77bfe8de 57
75191dc4
PL
58 def test_delete_wrong_id(self):
59 self.keyid = self.add_zone_key()
60 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/1234567"))
4bfebc93 61 self.assertEqual(r.status_code, 404)
75191dc4 62
86b3e4e8
BZ
63 def test_delete_wrong_zone(self):
64 self.keyid = self.add_zone_key()
ad918272 65 #checks for not covered zonename
86b3e4e8 66 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"fail/cryptokeys/"+self.keyid))
4bfebc93 67 self.assertEqual(r.status_code, 404)
ad918272 68
86b3e4e8
BZ
69 def test_delete_key_is_gone(self):
70 self.keyid = self.add_zone_key()
71 self.remove_zone_key(self.keyid)
ad918272 72 #checks for key is gone. Its ok even if no key had to be deleted. Or something went wrong with the backend.
86b3e4e8 73 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid))
4bfebc93 74 self.assertEqual(r.status_code, 404)
ad918272
BZ
75
76 # Prepares the json object for Post and sends it to the server
541bb91b
CH
77 def add_key(self, content='', type='ksk', active='true', algo='', bits=None):
78 payload = {
79 'keytype': type,
80 'active': active,
81 }
82 if algo:
83 payload['algorithm'] = algo
84 if bits is not None:
ad918272
BZ
85 payload['bits'] = bits
86 if content != '':
87 payload['content'] = content
541bb91b 88 print("create key with payload:", payload)
ad918272 89 r = self.session.post(
86b3e4e8 90 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys"),
ad918272
BZ
91 data=json.dumps(payload),
92 headers={'content-type': 'application/json'})
ad918272 93
86b3e4e8 94 return r
ad918272 95
86b3e4e8 96 # Test POST for a positive result and delete the added key
541bb91b 97 def post_helper(self, content='', algo='', bits=None):
ad918272
BZ
98 r = self.add_key(content=content, algo=algo, bits=bits)
99 self.assert_success_json(r)
4bfebc93 100 self.assertEqual(r.status_code, 201)
ad918272
BZ
101 response = r.json()
102 # Only a ksk added, so expected type is csk
4bfebc93 103 self.assertEqual(response['keytype'], 'csk')
86b3e4e8 104 self.keyid = response['id']
ad918272 105 # Check if the key is actually added
541bb91b
CH
106 out = pdnsutil("list-keys", self.zone_nodot)
107 self.assertIn(self.zone_nodot, out)
ad918272 108
86b3e4e8 109 # Test POST to add a key with default algorithm
ad918272 110 def test_post(self):
ad918272
BZ
111 self.post_helper()
112
86b3e4e8
BZ
113 # Test POST to add a key with specific algorithm number
114 def test_post_specific_number(self):
86783480 115 self.post_helper(algo=10, bits=1024)
ad918272 116
86b3e4e8
BZ
117 # Test POST to add a key with specific name and bits
118 def test_post_specific_name_bits(self):
86783480 119 self.post_helper(algo="rsasha256", bits=2048)
ad918272 120
86b3e4e8
BZ
121 # Test POST to add a key with specific name
122 def test_post_specific_name(self):
ad918272
BZ
123 self.post_helper(algo='ecdsa256')
124
86b3e4e8
BZ
125 # Test POST to add a private key from external resource
126 def test_post_content(self):
ad918272
BZ
127 self.post_helper(content="Private-key-format: v1.2\n"+
128 "Algorithm: 8 (RSASHA256)\n"+
129 "Modulus: 4GlYLGgDI7ohnP8SmEW8EBERbNRusDcg0VQda/EPVHU=\n"+
130 "PublicExponent: AQAB\n"+
131 "PrivateExponent: JBnuXF5zOtkjtSz3odV+Fk5UNUTTeCsiI16dkcM7TVU=\n"+
132 "Prime1: /w7TM4118RoSEvP8+dgnCw==\n"+
133 "Prime2: 4T2KhkYLa3w7rdK3Cb2ifw==\n"+
134 "Exponent1: 3aeKj9Ct4JuhfWsgPBhGxQ==\n"+
135 "Exponent2: tfh1OMPQKBdnU6iATjNR2w==\n"+
136 "Coefficient: eVrHe/kauqOewSKndIImrg==)\n")
137
86b3e4e8 138 def test_post_wrong_key_format(self):
ad918272
BZ
139 r = self.add_key(content="trollololoooolll")
140 self.assert_error_json(r)
4bfebc93 141 self.assertEqual(r.status_code, 422)
86b3e4e8 142 self.assertIn("Key could not be parsed. Make sure your key format is correct.",r.json()['error'])
ad918272 143
86b3e4e8 144 def test_post_wrong_keytype(self):
ad918272
BZ
145 r = self.add_key(type='sdfdhhgj')
146 self.assert_error_json(r)
4bfebc93 147 self.assertEqual(r.status_code, 422)
ad918272
BZ
148 self.assertIn("Invalid keytype",r.json()['error'])
149
86b3e4e8
BZ
150 def test_post_wrong_bits_format(self):
151 r = self.add_key(bits='sdfdhhgj')
152 self.assert_error_json(r)
4bfebc93 153 self.assertEqual(r.status_code, 422)
86b3e4e8
BZ
154 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
155
156 r = self.add_key(bits='5.5')
157 self.assert_error_json(r)
4bfebc93 158 self.assertEqual(r.status_code, 422)
86b3e4e8
BZ
159 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
160
161 r = self.add_key(bits='-6')
162 self.assert_error_json(r)
4bfebc93 163 self.assertEqual(r.status_code, 422)
86b3e4e8
BZ
164 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
165
166 def test_post_unsupported_algorithm(self):
ad918272
BZ
167 r = self.add_key(algo='lkjhgf')
168 self.assert_error_json(r)
4bfebc93 169 self.assertEqual(r.status_code, 422)
ad918272
BZ
170 self.assertIn("Unknown algorithm:",r.json()['error'])
171
86b3e4e8 172 def test_post_forgot_bits(self):
ad918272
BZ
173 r = self.add_key(algo="rsasha256")
174 self.assert_error_json(r)
4bfebc93 175 self.assertEqual(r.status_code, 422)
ad918272
BZ
176 self.assertIn("key requires the size (in bits) to be passed", r.json()['error'])
177
86b3e4e8 178 def test_post_wrong_bit_size(self):
ad918272
BZ
179 r = self.add_key(algo=10, bits=30)
180 self.assert_error_json(r)
4bfebc93 181 self.assertEqual(r.status_code,422)
86b3e4e8 182 self.assertIn("The algorithm does not support the given bit size.", r.json()['error'])
ad918272 183
86b3e4e8 184 def test_post_can_not_guess_key_size(self):
9d3727e0 185 r = self.add_key(algo=17)
ad918272 186 self.assert_error_json(r)
4bfebc93 187 self.assertEqual(r.status_code,422)
86b3e4e8 188 self.assertIn("Can not guess key size for algorithm", r.json()['error'])
ad918272 189
86b3e4e8
BZ
190 def test_put_activate_key(self):
191 self.keyid = self.add_zone_key()
ad918272 192
ad918272 193 payload = {
33918299
RG
194 'active': True,
195 'published': True,
ad918272 196 }
86b3e4e8
BZ
197 r = self.session.put(
198 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
ad918272
BZ
199 data=json.dumps(payload),
200 headers={'content-type': 'application/json'})
4bfebc93
CH
201 self.assertEqual(r.status_code, 204)
202 self.assertEqual(r.content, b"")
ad918272
BZ
203
204 # check if key is activated
541bb91b
CH
205 out = pdnsutil("show-zone", self.zone_nodot)
206 self.assertIn("Active", out)
ad918272 207
86b3e4e8 208 def test_put_deactivate_key(self):
33918299 209 self.keyid = self.add_zone_key(status=['active'])
ad918272
BZ
210 # deactivate key
211 payload2 = {
33918299
RG
212 'active': False,
213 'published': True,
ad918272 214 }
86b3e4e8
BZ
215
216 r = self.session.put(
217 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
ad918272
BZ
218 data=json.dumps(payload2),
219 headers={'content-type': 'application/json'})
4bfebc93
CH
220 self.assertEqual(r.status_code, 204)
221 self.assertEqual(r.content, b"")
ad918272
BZ
222
223 # check if key is deactivated
541bb91b
CH
224 out = pdnsutil("show-zone", self.zone_nodot)
225 self.assertIn("Inactive", out)
ad918272 226
86b3e4e8
BZ
227 def test_put_deactivate_inactive_key(self):
228 self.keyid = self.add_zone_key()
ad918272
BZ
229
230 # deactivate key
231 payload = {
33918299
RG
232 'active': False,
233 'published': True,
ad918272 234 }
86b3e4e8
BZ
235
236 r = self.session.put(
237 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
ad918272
BZ
238 data=json.dumps(payload),
239 headers={'content-type': 'application/json'})
4bfebc93
CH
240 self.assertEqual(r.status_code, 204)
241 self.assertEqual(r.content, b"")
ad918272
BZ
242
243 # check if key is still deactivated
541bb91b
CH
244 out = pdnsutil("show-zone", self.zone_nodot)
245 self.assertIn("Inactive", out)
ad918272 246
86b3e4e8 247 def test_put_activate_active_key(self):
33918299 248 self.keyid = self.add_zone_key(status=['active'])
86b3e4e8 249
ad918272
BZ
250 # activate key
251 payload2 = {
33918299
RG
252 'active': True,
253 'published': True,
ad918272 254 }
86b3e4e8
BZ
255 r = self.session.put(
256 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
ad918272
BZ
257 data=json.dumps(payload2),
258 headers={'content-type': 'application/json'})
4bfebc93
CH
259 self.assertEqual(r.status_code, 204)
260 self.assertEqual(r.content, b"")
ad918272
BZ
261
262 # check if key is activated
541bb91b
CH
263 out = pdnsutil("show-zone", self.zone_nodot)
264 self.assertIn("Active", out)
33918299
RG
265
266 def test_put_unpublish_key(self):
267 self.keyid = self.add_zone_key(status=['active'])
268
269 payload = {
270 'active': True,
271 'published': False,
272 }
273 r = self.session.put(
274 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
275 data=json.dumps(payload),
276 headers={'content-type': 'application/json'})
4bfebc93
CH
277 self.assertEqual(r.status_code, 204)
278 self.assertEqual(r.content, b"")
33918299
RG
279
280 # check if key is activated
281 out = pdnsutil("show-zone", self.zone_nodot)
282 self.assertIn("Unpublished", out)
283
284 def test_put_publish_key(self):
285 self.keyid = self.add_zone_key(status=['active', 'unpublished'])
286 # deactivate key
287 payload2 = {
288 'active': True,
289 'published': True,
290 }
291
292 r = self.session.put(
293 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
294 data=json.dumps(payload2),
295 headers={'content-type': 'application/json'})
4bfebc93
CH
296 self.assertEqual(r.status_code, 204)
297 self.assertEqual(r.content, b"")
33918299
RG
298
299 # check if key is deactivated
300 out = pdnsutil("show-zone", self.zone_nodot)
301 self.assertIn("Published", out)
302
303 def test_put_publish_published_key(self):
304 self.keyid = self.add_zone_key(status=['active'])
305
306 # deactivate key
307 payload = {
308 'active': True,
309 'published': True,
310 }
311
312 r = self.session.put(
313 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
314 data=json.dumps(payload),
315 headers={'content-type': 'application/json'})
4bfebc93
CH
316 self.assertEqual(r.status_code, 204)
317 self.assertEqual(r.content, b"")
33918299
RG
318
319 # check if key is still deactivated
320 out = pdnsutil("show-zone", self.zone_nodot)
321 self.assertIn("Published", out)
322
323 def test_put_unpublish_unpublished_key(self):
324 self.keyid = self.add_zone_key(status=['active', 'unpublished'])
325
326 # activate key
327 payload2 = {
328 'active': True,
329 'published': False,
330 }
331 r = self.session.put(
332 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
333 data=json.dumps(payload2),
334 headers={'content-type': 'application/json'})
4bfebc93
CH
335 self.assertEqual(r.status_code, 204)
336 self.assertEqual(r.content, b"")
33918299
RG
337
338 # check if key is activated
339 out = pdnsutil("show-zone", self.zone_nodot)
340 self.assertIn("Unpublished", out)