]>
Commit | Line | Data |
---|---|---|
ad918272 BZ |
1 | import subprocess |
2 | import json | |
3 | import unittest | |
86b3e4e8 | 4 | import os |
ad918272 | 5 | |
541bb91b | 6 | from test_helper import ApiTestCase, is_auth, pdnsutil, unique_zone_name |
ad918272 BZ |
7 | |
8 | @unittest.skipIf(not is_auth(), "Not applicable") | |
9 | class 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) | |
26 | self.assertEquals(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 | |
33 | def add_zone_key(self, status='inactive'): | |
541bb91b | 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)) |
75191dc4 | 46 | self.assertEquals(r.status_code, 204) |
541bb91b | 47 | self.assertEquals(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)) | |
56 | self.assertEquals(r.status_code, 404) | |
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")) | |
61 | self.assertEquals(r.status_code, 404) | |
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)) |
77bfe8de | 67 | self.assertEquals(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)) |
71de13d7 | 74 | self.assertEquals(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) | |
100 | self.assertEquals(r.status_code, 201) | |
101 | response = r.json() | |
102 | # Only a ksk added, so expected type is csk | |
103 | self.assertEquals(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) | |
141 | self.assertEquals(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) | |
147 | self.assertEquals(r.status_code, 422) | |
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) | |
153 | self.assertEquals(r.status_code, 422) | |
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) | |
158 | self.assertEquals(r.status_code, 422) | |
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) | |
163 | self.assertEquals(r.status_code, 422) | |
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) | |
169 | self.assertEquals(r.status_code, 422) | |
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) | |
175 | self.assertEquals(r.status_code, 422) | |
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) | |
181 | self.assertEquals(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 BZ |
186 | self.assert_error_json(r) |
187 | self.assertEquals(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 BZ |
193 | payload = { |
194 | 'active': True | |
195 | } | |
86b3e4e8 BZ |
196 | r = self.session.put( |
197 | self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid), | |
ad918272 BZ |
198 | data=json.dumps(payload), |
199 | headers={'content-type': 'application/json'}) | |
86b3e4e8 | 200 | self.assertEquals(r.status_code, 204) |
541bb91b | 201 | self.assertEquals(r.content, b"") |
ad918272 BZ |
202 | |
203 | # check if key is activated | |
541bb91b CH |
204 | out = pdnsutil("show-zone", self.zone_nodot) |
205 | self.assertIn("Active", out) | |
ad918272 | 206 | |
86b3e4e8 | 207 | def test_put_deactivate_key(self): |
541bb91b | 208 | self.keyid = self.add_zone_key(status='active') |
ad918272 BZ |
209 | # deactivate key |
210 | payload2 = { | |
211 | 'active': False | |
212 | } | |
86b3e4e8 BZ |
213 | |
214 | r = self.session.put( | |
215 | self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid), | |
ad918272 BZ |
216 | data=json.dumps(payload2), |
217 | headers={'content-type': 'application/json'}) | |
86b3e4e8 | 218 | self.assertEquals(r.status_code, 204) |
541bb91b | 219 | self.assertEquals(r.content, b"") |
ad918272 BZ |
220 | |
221 | # check if key is deactivated | |
541bb91b CH |
222 | out = pdnsutil("show-zone", self.zone_nodot) |
223 | self.assertIn("Inactive", out) | |
ad918272 | 224 | |
86b3e4e8 BZ |
225 | def test_put_deactivate_inactive_key(self): |
226 | self.keyid = self.add_zone_key() | |
ad918272 BZ |
227 | |
228 | # deactivate key | |
229 | payload = { | |
230 | 'active': False | |
231 | } | |
86b3e4e8 BZ |
232 | |
233 | r = self.session.put( | |
234 | self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid), | |
ad918272 BZ |
235 | data=json.dumps(payload), |
236 | headers={'content-type': 'application/json'}) | |
86b3e4e8 | 237 | self.assertEquals(r.status_code, 204) |
541bb91b | 238 | self.assertEquals(r.content, b"") |
ad918272 BZ |
239 | |
240 | # check if key is still deactivated | |
541bb91b CH |
241 | out = pdnsutil("show-zone", self.zone_nodot) |
242 | self.assertIn("Inactive", out) | |
ad918272 | 243 | |
86b3e4e8 BZ |
244 | def test_put_activate_active_key(self): |
245 | self.keyid =self.add_zone_key(status='active') | |
246 | ||
ad918272 BZ |
247 | # activate key |
248 | payload2 = { | |
249 | 'active': True | |
250 | } | |
86b3e4e8 BZ |
251 | r = self.session.put( |
252 | self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid), | |
ad918272 BZ |
253 | data=json.dumps(payload2), |
254 | headers={'content-type': 'application/json'}) | |
86b3e4e8 | 255 | self.assertEquals(r.status_code, 204) |
541bb91b | 256 | self.assertEquals(r.content, b"") |
ad918272 BZ |
257 | |
258 | # check if key is activated | |
541bb91b CH |
259 | out = pdnsutil("show-zone", self.zone_nodot) |
260 | self.assertIn("Active", out) |