async def test_unspecified_port_allocates_a_random_port(responder): server1 = WebhookServer(addr='127.0.0.1', path='/p1/p2', insecure=True) server2 = WebhookServer(addr='127.0.0.1', path='/p1/p2', insecure=True) async for client_config1 in server1(responder.fn): async for client_config2 in server2(responder.fn): assert client_config1['url'] != client_config2['url'] break # do not sleep break # do not sleep
async def test_starts_as_http_ipv6(responder): server = WebhookServer(addr='::1', port=22533, path='/p1/p2', insecure=True) async with server: async for client_config in server(responder.fn): assert client_config['url'] == 'http://[::1]:22533/p1/p2' assert 'caBundle' not in client_config break # do not sleep
async def test_webhookserver_starts_as_https_with_provided_cert( certfile, pkeyfile, certpkey, responder): server = WebhookServer(port=22533, certfile=certfile, pkeyfile=pkeyfile) async for client_config in server(responder.fn): assert client_config['url'] == 'https://localhost:22533' assert base64.b64decode(client_config['caBundle']) == certpkey[0] break # do not sleep
async def test_webhookserver_starts_as_https_with_selfsigned_cert( responder): server = WebhookServer(addr='127.0.0.1', port=22533, path='/p1/p2', host='somehost') async with server: async for client_config in server(responder.fn): assert client_config['url'] == 'https://somehost:22533/p1/p2' assert 'caBundle' in client_config # regardless of the value break # do not sleep
async def test_unspecified_addr_uses_all_interfaces(responder, caplog, assert_logs): caplog.set_level(0) server = WebhookServer(port=22533, path='/p1/p2', insecure=True) async with server: async for client_config in server(responder.fn): assert client_config['url'] == 'http://localhost:22533/p1/p2' break # do not sleep assert_logs([r"Listening for webhooks at http://\*:22533/p1/p2"])
def test_certificate_generation(): names = ['hostname1', 'hostname2', '1.2.3.4', '0:0:0:0:0:0:0:1'] cert, pkey = WebhookServer.build_certificate(names) context = certvalidator.ValidationContext(extra_trust_roots=[cert]) validator = certvalidator.CertificateValidator(cert, validation_context=context) path = validator.validate_tls('hostname1') assert len(path) == 1 # self-signed assert path.first.ca assert path.first.self_issued assert set(path.first.valid_domains) == {'hostname1', 'hostname2', '1.2.3.4', '::1'} assert set(path.first.valid_ips) == {'1.2.3.4', '::1'}
async def test_webhookserver_errors( certfile, pkeyfile, responder, adm_request, code, error): responder.fut.set_exception(error()) server = WebhookServer(certfile=certfile, pkeyfile=pkeyfile) async with server: async for client_config in server(responder.fn): cadata = base64.b64decode(client_config['caBundle']).decode('ascii') sslctx = ssl.create_default_context(cadata=cadata) async with aiohttp.ClientSession() as client: async with client.post(client_config['url'], ssl=sslctx, json=adm_request) as resp: assert resp.status == code break # do not sleep
async def test_webhookserver_serves( certfile, pkeyfile, responder, adm_request): responder.fut.set_result({'hello': 'world'}) server = WebhookServer(certfile=certfile, pkeyfile=pkeyfile) async with server: async for client_config in server(responder.fn): cadata = base64.b64decode(client_config['caBundle']).decode('ascii') sslctx = ssl.create_default_context(cadata=cadata) async with aiohttp.ClientSession() as client: async with client.post(client_config['url'], ssl=sslctx, json=adm_request) as resp: text = await resp.text() assert text == '{"hello": "world"}' assert resp.status == 200 break # do not sleep
def certpkey(): cert, pkey = WebhookServer.build_certificate(['localhost', '127.0.0.1']) return cert, pkey
def test_missing_oscrypto(no_oscrypto): with pytest.raises(ImportError) as err: WebhookServer.build_certificate(['...']) assert "pip install certbuilder" in str(err.value)
def test_common_name_selection(hostnames, common_name): cert, pkey = WebhookServer.build_certificate(hostnames) context = certvalidator.ValidationContext(extra_trust_roots=[cert]) validator = certvalidator.CertificateValidator(cert, validation_context=context) path = validator.validate_tls(common_name) assert path.first.subject.native['common_name'] == common_name