]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_API.py
Merge pull request #8795 from omoerbeek/rec-lua-docs-policytag
[thirdparty/pdns.git] / regression-tests.dnsdist / test_API.py
CommitLineData
02bbf9eb 1#!/usr/bin/env python
56d68fad 2import os.path
02bbf9eb 3
80dbd7d2 4import base64
56d68fad 5import json
02bbf9eb
RG
6import requests
7from dnsdisttests import DNSDistTest
8
56d68fad 9class TestAPIBasics(DNSDistTest):
02bbf9eb
RG
10
11 _webTimeout = 2.0
12 _webServerPort = 8083
13 _webServerBasicAuthPassword = 'secret'
14 _webServerAPIKey = 'apisecret'
55afa518
RG
15 # paths accessible using the API key only
16 _apiOnlyPaths = ['/api/v1/servers/localhost/config', '/api/v1/servers/localhost/config/allow-from', '/api/v1/servers/localhost/statistics']
17 # paths accessible using an API key or basic auth
18 _statsPaths = [ '/jsonstat?command=stats', '/jsonstat?command=dynblocklist', '/api/v1/servers/localhost']
02bbf9eb
RG
19 # paths accessible using basic auth only (list not exhaustive)
20 _basicOnlyPaths = ['/', '/index.html']
21 _config_params = ['_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey']
22 _config_template = """
56d68fad 23 setACL({"127.0.0.1/32", "::1/128"})
02bbf9eb
RG
24 newServer{address="127.0.0.1:%s"}
25 webserver("127.0.0.1:%s", "%s", "%s")
26 """
27
28 def testBasicAuth(self):
29 """
30 API: Basic Authentication
31 """
55afa518 32 for path in self._basicOnlyPaths + self._statsPaths:
02bbf9eb 33 url = 'http://127.0.0.1:' + str(self._webServerPort) + path
80dbd7d2
CHB
34 r = requests.get(url, auth=('whatever', "evilsecret"), timeout=self._webTimeout)
35 self.assertEquals(r.status_code, 401)
02bbf9eb
RG
36 r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout)
37 self.assertTrue(r)
38 self.assertEquals(r.status_code, 200)
39
40 def testXAPIKey(self):
41 """
42 API: X-Api-Key
43 """
44 headers = {'x-api-key': self._webServerAPIKey}
55afa518 45 for path in self._apiOnlyPaths + self._statsPaths:
02bbf9eb
RG
46 url = 'http://127.0.0.1:' + str(self._webServerPort) + path
47 r = requests.get(url, headers=headers, timeout=self._webTimeout)
48 self.assertTrue(r)
49 self.assertEquals(r.status_code, 200)
50
80dbd7d2
CHB
51 def testWrongXAPIKey(self):
52 """
53 API: Wrong X-Api-Key
54 """
55 headers = {'x-api-key': "evilapikey"}
56 for path in self._apiOnlyPaths + self._statsPaths:
57 url = 'http://127.0.0.1:' + str(self._webServerPort) + path
58 r = requests.get(url, headers=headers, timeout=self._webTimeout)
59 self.assertEquals(r.status_code, 401)
c563cbe5 60
02bbf9eb
RG
61 def testBasicAuthOnly(self):
62 """
63 API: Basic Authentication Only
64 """
65 headers = {'x-api-key': self._webServerAPIKey}
66 for path in self._basicOnlyPaths:
67 url = 'http://127.0.0.1:' + str(self._webServerPort) + path
68 r = requests.get(url, headers=headers, timeout=self._webTimeout)
69 self.assertEquals(r.status_code, 401)
70
55afa518
RG
71 def testAPIKeyOnly(self):
72 """
73 API: API Key Only
74 """
75 for path in self._apiOnlyPaths:
76 url = 'http://127.0.0.1:' + str(self._webServerPort) + path
77 r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout)
78 self.assertEquals(r.status_code, 401)
79
02bbf9eb
RG
80 def testServersLocalhost(self):
81 """
82 API: /api/v1/servers/localhost
83 """
84 headers = {'x-api-key': self._webServerAPIKey}
85 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost'
86 r = requests.get(url, headers=headers, timeout=self._webTimeout)
87 self.assertTrue(r)
88 self.assertEquals(r.status_code, 200)
89 self.assertTrue(r.json())
90 content = r.json()
91
92 self.assertEquals(content['daemon_type'], 'dnsdist')
93
f8a222ac
RG
94 rule_groups = ['response-rules', 'cache-hit-response-rules', 'self-answered-response-rules', 'rules']
95 for key in ['version', 'acl', 'local', 'servers', 'frontends', 'pools'] + rule_groups:
02bbf9eb
RG
96 self.assertIn(key, content)
97
d18eab67
CH
98 for rule_group in rule_groups:
99 for rule in content[rule_group]:
f8a222ac 100 for key in ['id', 'creationOrder', 'matches', 'rule', 'action', 'uuid']:
d18eab67 101 self.assertIn(key, rule)
f8a222ac 102 for key in ['id', 'creationOrder', 'matches']:
d18eab67 103 self.assertTrue(rule[key] >= 0)
4ace9fe8 104
02bbf9eb
RG
105 for server in content['servers']:
106 for key in ['id', 'latency', 'name', 'weight', 'outstanding', 'qpsLimit',
6a78f305
PL
107 'reuseds', 'state', 'address', 'pools', 'qps', 'queries', 'order', 'sendErrors',
108 'dropRate']:
02bbf9eb
RG
109 self.assertIn(key, server)
110
111 for key in ['id', 'latency', 'weight', 'outstanding', 'qpsLimit', 'reuseds',
112 'qps', 'queries', 'order']:
113 self.assertTrue(server[key] >= 0)
114
115 self.assertTrue(server['state'] in ['up', 'down', 'UP', 'DOWN'])
116
117 for frontend in content['frontends']:
ba7ec340 118 for key in ['id', 'address', 'udp', 'tcp', 'type', 'queries']:
02bbf9eb
RG
119 self.assertIn(key, frontend)
120
121 for key in ['id', 'queries']:
122 self.assertTrue(frontend[key] >= 0)
123
4ace9fe8
RG
124 for pool in content['pools']:
125 for key in ['id', 'name', 'cacheSize', 'cacheEntries', 'cacheHits', 'cacheMisses', 'cacheDeferredInserts', 'cacheDeferredLookups', 'cacheLookupCollisions', 'cacheInsertCollisions', 'cacheTTLTooShorts']:
126 self.assertIn(key, pool)
127
128 for key in ['id', 'cacheSize', 'cacheEntries', 'cacheHits', 'cacheMisses', 'cacheDeferredInserts', 'cacheDeferredLookups', 'cacheLookupCollisions', 'cacheInsertCollisions', 'cacheTTLTooShorts']:
129 self.assertTrue(pool[key] >= 0)
130
00566cbf
PL
131 def testServersIDontExist(self):
132 """
133 API: /api/v1/servers/idontexist (should be 404)
134 """
135 headers = {'x-api-key': self._webServerAPIKey}
136 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/idontexist'
137 r = requests.get(url, headers=headers, timeout=self._webTimeout)
138 self.assertEquals(r.status_code, 404)
139
02bbf9eb
RG
140 def testServersLocalhostConfig(self):
141 """
142 API: /api/v1/servers/localhost/config
143 """
144 headers = {'x-api-key': self._webServerAPIKey}
145 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/config'
146 r = requests.get(url, headers=headers, timeout=self._webTimeout)
147 self.assertTrue(r)
148 self.assertEquals(r.status_code, 200)
149 self.assertTrue(r.json())
150 content = r.json()
151 values = {}
152 for entry in content:
153 for key in ['type', 'name', 'value']:
154 self.assertIn(key, entry)
155
156 self.assertEquals(entry['type'], 'ConfigSetting')
157 values[entry['name']] = entry['value']
158
159 for key in ['acl', 'control-socket', 'ecs-override', 'ecs-source-prefix-v4',
160 'ecs-source-prefix-v6', 'fixup-case', 'max-outstanding', 'server-policy',
161 'stale-cache-entries-ttl', 'tcp-recv-timeout', 'tcp-send-timeout',
162 'truncate-tc', 'verbose', 'verbose-health-checks']:
163 self.assertIn(key, values)
164
165 for key in ['max-outstanding', 'stale-cache-entries-ttl', 'tcp-recv-timeout',
166 'tcp-send-timeout']:
167 self.assertTrue(values[key] >= 0)
168
169 self.assertTrue(values['ecs-source-prefix-v4'] >= 0 and values['ecs-source-prefix-v4'] <= 32)
170 self.assertTrue(values['ecs-source-prefix-v6'] >= 0 and values['ecs-source-prefix-v6'] <= 128)
171
56d68fad
RG
172 def testServersLocalhostConfigAllowFrom(self):
173 """
174 API: /api/v1/servers/localhost/config/allow-from
175 """
176 headers = {'x-api-key': self._webServerAPIKey}
177 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/config/allow-from'
178 r = requests.get(url, headers=headers, timeout=self._webTimeout)
179 self.assertTrue(r)
180 self.assertEquals(r.status_code, 200)
181 self.assertTrue(r.json())
182 content = r.json()
183 for key in ['type', 'name', 'value']:
184 self.assertIn(key, content)
185
186 self.assertEquals(content['name'], 'allow-from')
187 self.assertEquals(content['type'], 'ConfigSetting')
078efd26
RG
188 acl = content['value']
189 expectedACL = ["127.0.0.1/32", "::1/128"]
190 acl.sort()
191 expectedACL.sort()
192 self.assertEquals(acl, expectedACL)
56d68fad
RG
193
194 def testServersLocalhostConfigAllowFromPut(self):
195 """
196 API: PUT /api/v1/servers/localhost/config/allow-from (should be refused)
197
198 The API is read-only by default, so this should be refused
199 """
200 newACL = ["192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24"]
201 payload = json.dumps({"name": "allow-from",
202 "type": "ConfigSetting",
203 "value": newACL})
204 headers = {'x-api-key': self._webServerAPIKey}
205 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/config/allow-from'
206 r = requests.put(url, headers=headers, timeout=self._webTimeout, data=payload)
207 self.assertFalse(r)
208 self.assertEquals(r.status_code, 405)
209
02bbf9eb
RG
210 def testServersLocalhostStatistics(self):
211 """
212 API: /api/v1/servers/localhost/statistics
213 """
214 headers = {'x-api-key': self._webServerAPIKey}
215 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/statistics'
216 r = requests.get(url, headers=headers, timeout=self._webTimeout)
217 self.assertTrue(r)
218 self.assertEquals(r.status_code, 200)
219 self.assertTrue(r.json())
220 content = r.json()
221 values = {}
222 for entry in content:
223 self.assertIn('type', entry)
224 self.assertIn('name', entry)
225 self.assertIn('value', entry)
226 self.assertEquals(entry['type'], 'StatisticItem')
227 values[entry['name']] = entry['value']
228
0c369ddc 229 expected = ['responses', 'servfail-responses', 'queries', 'acl-drops',
61d10a4d 230 'frontend-noerror', 'frontend-nxdomain', 'frontend-servfail',
dd46e5e3 231 'rule-drop', 'rule-nxdomain', 'rule-refused', 'self-answered', 'downstream-timeouts',
02bbf9eb
RG
232 'downstream-send-errors', 'trunc-failures', 'no-policy', 'latency0-1',
233 'latency1-10', 'latency10-50', 'latency50-100', 'latency100-1000',
eb0335ff
MC
234 'latency-slow', 'latency-sum', 'latency-count', 'latency-avg100', 'latency-avg1000',
235 'latency-avg10000', 'latency-avg1000000', 'uptime', 'real-memory-usage', 'noncompliant-queries',
02bbf9eb
RG
236 'noncompliant-responses', 'rdqueries', 'empty-queries', 'cache-hits',
237 'cache-misses', 'cpu-user-msec', 'cpu-sys-msec', 'fd-usage', 'dyn-blocked',
f29758cc 238 'dyn-block-nmg-size', 'rule-servfail', 'security-status']
02bbf9eb
RG
239
240 for key in expected:
241 self.assertIn(key, values)
242 self.assertTrue(values[key] >= 0)
243
dd46e5e3
RG
244 for key in values:
245 self.assertIn(key, expected)
246
02bbf9eb
RG
247 def testJsonstatStats(self):
248 """
249 API: /jsonstat?command=stats
250 """
251 headers = {'x-api-key': self._webServerAPIKey}
252 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/jsonstat?command=stats'
253 r = requests.get(url, headers=headers, timeout=self._webTimeout)
254 self.assertTrue(r)
255 self.assertEquals(r.status_code, 200)
256 self.assertTrue(r.json())
257 content = r.json()
258
0c369ddc 259 expected = ['responses', 'servfail-responses', 'queries', 'acl-drops',
61d10a4d 260 'frontend-noerror', 'frontend-nxdomain', 'frontend-servfail',
dd46e5e3 261 'rule-drop', 'rule-nxdomain', 'rule-refused', 'self-answered', 'downstream-timeouts',
02bbf9eb
RG
262 'downstream-send-errors', 'trunc-failures', 'no-policy', 'latency0-1',
263 'latency1-10', 'latency10-50', 'latency50-100', 'latency100-1000',
264 'latency-slow', 'latency-avg100', 'latency-avg1000', 'latency-avg10000',
265 'latency-avg1000000', 'uptime', 'real-memory-usage', 'noncompliant-queries',
266 'noncompliant-responses', 'rdqueries', 'empty-queries', 'cache-hits',
267 'cache-misses', 'cpu-user-msec', 'cpu-sys-msec', 'fd-usage', 'dyn-blocked',
dd46e5e3
RG
268 'dyn-block-nmg-size', 'packetcache-hits', 'packetcache-misses', 'over-capacity-drops',
269 'too-old-drops']
02bbf9eb
RG
270
271 for key in expected:
272 self.assertIn(key, content)
273 self.assertTrue(content[key] >= 0)
274
275 def testJsonstatDynblocklist(self):
276 """
277 API: /jsonstat?command=dynblocklist
278 """
279 headers = {'x-api-key': self._webServerAPIKey}
280 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/jsonstat?command=dynblocklist'
281 r = requests.get(url, headers=headers, timeout=self._webTimeout)
282 self.assertTrue(r)
283 self.assertEquals(r.status_code, 200)
284
285 content = r.json()
286
287 if content:
477c86a0 288 for key in ['reason', 'seconds', 'blocks', 'action']:
02bbf9eb
RG
289 self.assertIn(key, content)
290
291 for key in ['blocks']:
292 self.assertTrue(content[key] >= 0)
56d68fad 293
36927800
RG
294class TestAPIServerDown(DNSDistTest):
295
296 _webTimeout = 2.0
297 _webServerPort = 8083
298 _webServerBasicAuthPassword = 'secret'
299 _webServerAPIKey = 'apisecret'
300 # paths accessible using the API key
301 _config_params = ['_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey']
302 _config_template = """
303 setACL({"127.0.0.1/32", "::1/128"})
304 newServer{address="127.0.0.1:%s"}
305 getServer(0):setDown()
306 webserver("127.0.0.1:%s", "%s", "%s")
307 """
308
309 def testServerDownNoLatencyLocalhost(self):
310 """
311 API: /api/v1/servers/localhost, no latency for a down server
312 """
313 headers = {'x-api-key': self._webServerAPIKey}
314 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost'
315 r = requests.get(url, headers=headers, timeout=self._webTimeout)
316 self.assertTrue(r)
317 self.assertEquals(r.status_code, 200)
318 self.assertTrue(r.json())
319 content = r.json()
320
321 self.assertEquals(content['servers'][0]['latency'], None)
322
56d68fad
RG
323class TestAPIWritable(DNSDistTest):
324
325 _webTimeout = 2.0
326 _webServerPort = 8083
327 _webServerBasicAuthPassword = 'secret'
328 _webServerAPIKey = 'apisecret'
329 _APIWriteDir = '/tmp'
330 _config_params = ['_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey', '_APIWriteDir']
331 _config_template = """
332 setACL({"127.0.0.1/32", "::1/128"})
333 newServer{address="127.0.0.1:%s"}
334 webserver("127.0.0.1:%s", "%s", "%s")
335 setAPIWritable(true, "%s")
336 """
337
338 def testSetACL(self):
339 """
340 API: Set ACL
341 """
342 headers = {'x-api-key': self._webServerAPIKey}
343 url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/config/allow-from'
344 r = requests.get(url, headers=headers, timeout=self._webTimeout)
345 self.assertTrue(r)
346 self.assertEquals(r.status_code, 200)
347 self.assertTrue(r.json())
348 content = r.json()
078efd26
RG
349 acl = content['value']
350 expectedACL = ["127.0.0.1/32", "::1/128"]
351 acl.sort()
352 expectedACL.sort()
353 self.assertEquals(acl, expectedACL)
56d68fad
RG
354
355 newACL = ["192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24"]
356 payload = json.dumps({"name": "allow-from",
357 "type": "ConfigSetting",
358 "value": newACL})
359 r = requests.put(url, headers=headers, timeout=self._webTimeout, data=payload)
360 self.assertTrue(r)
361 self.assertEquals(r.status_code, 200)
362 self.assertTrue(r.json())
363 content = r.json()
b4be3cc0
OM
364 acl = content['value']
365 acl.sort()
366 self.assertEquals(acl, newACL)
56d68fad
RG
367
368 r = requests.get(url, headers=headers, timeout=self._webTimeout)
369 self.assertTrue(r)
370 self.assertEquals(r.status_code, 200)
371 self.assertTrue(r.json())
372 content = r.json()
b4be3cc0
OM
373 acl = content['value']
374 acl.sort()
375 self.assertEquals(acl, newACL)
56d68fad
RG
376
377 configFile = self._APIWriteDir + '/' + 'acl.conf'
378 self.assertTrue(os.path.isfile(configFile))
379 fileContent = None
b4f23783 380 with open(configFile, 'rt') as f:
b4be3cc0
OM
381 header = f.readline()
382 body = f.readline()
383
384 self.assertEquals(header, """-- Generated by the REST API, DO NOT EDIT\n""")
385
386 self.assertIn(body, {
387 """setACL({"192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24"})\n""",
388 """setACL({"192.0.2.0/24", "203.0.113.0/24", "198.51.100.0/24"})\n""",
389 """setACL({"198.51.100.0/24", "192.0.2.0/24", "203.0.113.0/24"})\n""",
390 """setACL({"198.51.100.0/24", "203.0.113.0/24", "192.0.2.0/24"})\n""",
391 """setACL({"203.0.113.0/24", "192.0.2.0/24", "198.51.100.0/24"})\n""",
392 """setACL({"203.0.113.0/24", "198.51.100.0/24", "192.0.2.0/24"})\n"""
393 })
80dbd7d2 394
32c97b56
CHB
395class TestAPICustomHeaders(DNSDistTest):
396
397 _webTimeout = 2.0
398 _webServerPort = 8083
399 _webServerBasicAuthPassword = 'secret'
400 _webServerAPIKey = 'apisecret'
401 # paths accessible using the API key only
402 _apiOnlyPath = '/api/v1/servers/localhost/config'
403 # paths accessible using basic auth only (list not exhaustive)
404 _basicOnlyPath = '/'
405 _consoleKey = DNSDistTest.generateConsoleKey()
406 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
407 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey']
408 _config_template = """
409 setKey("%s")
410 controlSocket("127.0.0.1:%s")
411 setACL({"127.0.0.1/32", "::1/128"})
412 newServer({address="127.0.0.1:%s"})
413 webserver("127.0.0.1:%s", "%s", "%s", {["X-Frame-Options"]="", ["X-Custom"]="custom"})
414 """
415
416 def testBasicHeaders(self):
417 """
418 API: Basic custom headers
419 """
420
421 url = 'http://127.0.0.1:' + str(self._webServerPort) + self._basicOnlyPath
422
423 r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout)
424 self.assertTrue(r)
425 self.assertEquals(r.status_code, 200)
426 self.assertEquals(r.headers.get('x-custom'), "custom")
427 self.assertFalse("x-frame-options" in r.headers)
428
429 def testBasicHeadersUpdate(self):
430 """
431 API: Basic update of custom headers
432 """
433
434 url = 'http://127.0.0.1:' + str(self._webServerPort) + self._basicOnlyPath
435 self.sendConsoleCommand('setWebserverConfig({customHeaders={["x-powered-by"]="dnsdist"}})')
436 r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout)
437 self.assertTrue(r)
438 self.assertEquals(r.status_code, 200)
439 self.assertEquals(r.headers.get('x-powered-by'), "dnsdist")
440 self.assertTrue("x-frame-options" in r.headers)
441
442
80dbd7d2
CHB
443class TestAPIAuth(DNSDistTest):
444
445 _webTimeout = 2.0
446 _webServerPort = 8083
447 _webServerBasicAuthPassword = 'secret'
448 _webServerBasicAuthPasswordNew = 'password'
449 _webServerAPIKey = 'apisecret'
450 _webServerAPIKeyNew = 'apipassword'
451 # paths accessible using the API key only
452 _apiOnlyPath = '/api/v1/servers/localhost/config'
453 # paths accessible using basic auth only (list not exhaustive)
454 _basicOnlyPath = '/'
455 _consoleKey = DNSDistTest.generateConsoleKey()
456 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
457 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_webServerPort', '_webServerBasicAuthPassword', '_webServerAPIKey']
458 _config_template = """
459 setKey("%s")
460 controlSocket("127.0.0.1:%s")
461 setACL({"127.0.0.1/32", "::1/128"})
462 newServer{address="127.0.0.1:%s"}
463 webserver("127.0.0.1:%s", "%s", "%s")
464 """
465
466 def testBasicAuthChange(self):
467 """
468 API: Basic Authentication updating credentials
469 """
470
80dbd7d2 471 url = 'http://127.0.0.1:' + str(self._webServerPort) + self._basicOnlyPath
32c97b56
CHB
472 self.sendConsoleCommand('setWebserverConfig({{password="{}"}})'.format(self._webServerBasicAuthPasswordNew))
473
80dbd7d2
CHB
474 r = requests.get(url, auth=('whatever', self._webServerBasicAuthPasswordNew), timeout=self._webTimeout)
475 self.assertTrue(r)
476 self.assertEquals(r.status_code, 200)
477
478 # Make sure the old password is not usable any more
80dbd7d2
CHB
479 r = requests.get(url, auth=('whatever', self._webServerBasicAuthPassword), timeout=self._webTimeout)
480 self.assertEquals(r.status_code, 401)
481
482 def testXAPIKeyChange(self):
483 """
484 API: X-Api-Key updating credentials
485 """
486
32c97b56
CHB
487 url = 'http://127.0.0.1:' + str(self._webServerPort) + self._apiOnlyPath
488 self.sendConsoleCommand('setWebserverConfig({{apiKey="{}"}})'.format(self._webServerAPIKeyNew))
80dbd7d2
CHB
489
490 headers = {'x-api-key': self._webServerAPIKeyNew}
80dbd7d2
CHB
491 r = requests.get(url, headers=headers, timeout=self._webTimeout)
492 self.assertTrue(r)
493 self.assertEquals(r.status_code, 200)
494
495 # Make sure the old password is not usable any more
496 headers = {'x-api-key': self._webServerAPIKey}
80dbd7d2
CHB
497 r = requests.get(url, headers=headers, timeout=self._webTimeout)
498 self.assertEquals(r.status_code, 401)
499
500 def testBasicAuthOnlyChange(self):
501 """
502 API: X-Api-Key updated to none (disabled)
503 """
504
32c97b56
CHB
505 url = 'http://127.0.0.1:' + str(self._webServerPort) + self._apiOnlyPath
506 self.sendConsoleCommand('setWebserverConfig({{apiKey="{}"}})'.format(self._webServerAPIKeyNew))
80dbd7d2
CHB
507
508 headers = {'x-api-key': self._webServerAPIKeyNew}
80dbd7d2
CHB
509 r = requests.get(url, headers=headers, timeout=self._webTimeout)
510 self.assertTrue(r)
511 self.assertEquals(r.status_code, 200)
512
513 # now disable apiKey
32c97b56 514 self.sendConsoleCommand('setWebserverConfig({apiKey=""})')
80dbd7d2 515
80dbd7d2
CHB
516 r = requests.get(url, headers=headers, timeout=self._webTimeout)
517 self.assertEquals(r.status_code, 401)