def test_get_usage(status_info): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=status_info) result = get_usage(api) assert len(result) == 6 assert result[0]['system'] == 'darktrace-hostname-1' assert result[0]['type'] == 'master' assert result[0]['timestamp'] assert result[0]['cpu'] == 10 assert result[0]['dtqueue'] == 0 assert result[0]['memused'] == 10 assert result[0]['bandwidth'] == 1000000000 assert result[0]['connectionsPerMinuteCurrent'] == 100 assert result[0]['label'] == 'Label with a name1' assert result[1]['system'] == 'probe-hostname-1' assert result[1]['ip'] == '192.168.1.1' assert result[1]['type'] == 'probe' assert result[1]['timestamp'] assert result[1]['cpu'] == 2 assert result[1]['memused'] == 10 assert result[1]['bandwidth'] == 100000000 assert result[1]['connectionsPerMinuteCurrent'] == 10 assert result[1]['label'] == 'Label with a name1' assert 'dtqueue' not in result[1] # probes don't have dtqueue
def test_get_intelfeed(watchlist): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=watchlist) watched_items = get_intelfeed(api) assert len(watched_items) == len(watchlist) assert watched_items[2] == watchlist[2]
def test_api_get_signature(): api = Api(HOST, PUB_DTKEY, PRIVKEY) test_epoch = 1546304400 # 2019-01-01 01:00:00 timestamp = dt.datetime.utcfromtimestamp(test_epoch).strftime( '%Y%m%dT%H%M%S') assert PRE_COMPUTED_SIGNATURE == api.get_signature('/status', timestamp)
def test_get_tags(tags): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=tags) result = get_tags(api) assert len(result) == 6 assert result[3]['name'] == tags[3]['name']
def test_get_instances_region(status_info): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=status_info) instances = get_instances_region(api) assert instances[1]['label'] == 'Label with a name1' assert 'region' not in instances[1] assert instances[2]['label'] == 'Location2 - Name2' assert instances[2]['region'] == 'Location2'
def test_get_request_with_bad_status_code(requests_mock): api = Api(HOST, PUB_DTKEY, PRIVKEY) requests_mock.get(HOST + '/status', text='504 Server Error: Gateway Time-out', status_code=504) with pytest.raises(SystemExit) as exc_info: _ = api.get('/status') assert str(exc_info.value.args[0]).startswith('504')
def test_get_request(capsys, requests_mock): api = Api(HOST, PUB_DTKEY, PRIVKEY) success_respone = {'key': 'value'} requests_mock.get(HOST + '/info', json=success_respone) result = api.get('/info', test='test') captured = capsys.readouterr() assert result['key'] == 'value' assert HOST + '/info?test=test' not in captured.out
def test_get_headers(): api = Api(HOST, PUB_DTKEY, PRIVKEY) test_epoch = 1546304400 # 2019-01-01 01:00:00 timestamp = dt.datetime.utcfromtimestamp(test_epoch).strftime( '%Y%m%dT%H%M%S') headers = api.get_headers('/status', timestamp) assert headers['DTAPI-Token'] == PUB_DTKEY assert headers['DTAPI-Date'] == timestamp assert headers['DTAPI-Signature'] == PRE_COMPUTED_SIGNATURE
def test_addition_of_device_tag(): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.post = MagicMock(return_value=[{ "teid": 1000000000000, "tehid": 1000000000001, "entityType": "Device", "entityValue": "1000000000005", "valid": True }]) result = modify_device_tags(api, 'add', 'Admin', '1000000000005') assert result[0]['teid'] == 1000000000000
def test_search_tagged_devices(): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=[{ "teid": 1000000000000, "tehid": 1000000000001, "entityType": "Device", "entityValue": "1000000000005", "valid": True }]) result = search_tags(api, None, 'Admin') assert len(result) == 1
def test_post_request_with_bad_status_code(requests_mock): api = Api(HOST, PUB_DTKEY, PRIVKEY) entry = 'test.test.test' requests_mock.post(HOST + '/intelfeed?addentry', text='504 Server Error: Gateway Time-out', status_code=504) with pytest.raises(SystemExit) as exc_info: _ = api.post('/intelfeed', postdata={'addentry': entry}, addentry=entry) assert str(exc_info.value.args[0]).startswith('504')
def cli(ctx, host, pub_dtkey, priv_dtkey, cacert, insecure, debug, config_file): """Darktrace Command Line Interface""" config_dict = load_config(config_file) if '--help' in sys.argv: return # Provide fake values for when config command is given # This to pass the api_obj creation and still get a # valid ProgramState to the config subcommand if ctx.invoked_subcommand == 'config': host = '_' pub_dtkey = '_' priv_dtkey = '_' if not host: if 'host' in config_dict: host = config_dict['host'] else: raise click.UsageError('Host not specified or configured') if not pub_dtkey: if 'pub-dtkey' in config_dict: pub_dtkey = config_dict['pub-dtkey'] else: raise click.UsageError('pub-dtkey not specified or configured') if not cacert: if 'cacert' in config_dict: cacert = config_dict['cacert'] privkey = get_private_key(priv_dtkey, config_dict) api_obj = Api(host, pub_dtkey, privkey, cacert, insecure, debug) ctx.obj = ProgramState(api_obj, debug, config_dict, config_file)
def test_post_request(capsys, requests_mock): api = Api(HOST, PUB_DTKEY, PRIVKEY) entry = 'test.test.test' success_respone = {'response': 'SUCCESS', 'added': 1, 'updated': 0} requests_mock.post(HOST + '/intelfeed?addentry', json=success_respone) result = api.post('/intelfeed', postdata={'addentry': entry}, addentry=entry) captured = capsys.readouterr() assert result['response'] == 'SUCCESS' assert result['added'] == 1 assert result['updated'] == 0 assert HOST + '/intelfeed?addentry={0}'.format(entry) not in captured.out
def test_missing_values(): with pytest.raises(TypeError) as exc_info: _ = Api() assert isinstance(exc_info.value, TypeError) assert "__init__() missing 3 required positional arguments: " \ "'address', 'public_key', and 'private_key'" in exc_info.value.args[0]
def test_get_instances(status_info): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=status_info) instances = get_instances(api, True) assert instances['darktrace-instance-1']['id'] == 1 assert instances['darktrace-instance-1']['label'] == 'Label with a name1' assert len(instances['darktrace-instance-1']['probes']) == 1 assert instances['darktrace-instance-1']['probes'][0][ 'ip'] == '192.168.1.1' assert 'region' not in instances['darktrace-instance-1'] assert instances['darktrace-instance-2']['id'] == 2 assert instances['darktrace-instance-2']['label'] == 'Location2 - Name2' assert instances['darktrace-instance-2']['location'] == 'Location2' assert instances['darktrace-instance-2']['probes'][2]['error'] assert instances['darktrace-instance-3']['error']
def test_get_devices(devices): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=devices) result = get_devices(api, None, 3600) assert len(result) == 3 assert 'ips' in result[0] assert result[0]['ip'] == '10.0.0.10' assert result[0]['typename'] == 'desktop' assert 'credentials' in result[1] assert result[1]['typename'] == 'laptop' assert result[1]['hostname'] == 'testdevice.domain.dev' assert len(result[2]['ips']) == 1 assert result[2]['typename'] == 'server' assert result[2]['credentials'][0]['credential'] == 'testCredential2'
def test_setting_values(): api = Api(HOST, PUB_DTKEY, PRIVKEY, CACERT, INSECURE, DEBUG) assert api.address is HOST assert api.public_key is PUB_DTKEY assert api.private_key is PRIVKEY assert api.ca_cert is CACERT assert api.insecure assert api.debug
def test_add_entries_from_file_to_intelfeed(watchlist): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.post = MagicMock(return_value={ "response": "SUCCESS", "added": 1, "updated": 0 }) infile = 'tests/data/items_for_intelfeed.txt' results = add_entry_to_intelfeed(api, None, infile) assert results[0]['1.1.1.1']['response'] == 'SUCCESS' assert results[1]['2.2.2.2']['added'] == 1 assert results[2]['3.3.3.3']['updated'] == 0 assert results[5]['localhost.local']['response'] == 'SUCCESS' assert results[7][ 'https://www.notcorrect'] == 'Not a valid IPv4 address or domain name' assert results[8]['400.1.1.1'] == 'Not a valid IPv4 address or domain name'
def test_add_single_entry_to_intelfeed(): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.post = MagicMock(return_value={ "response": "SUCCESS", "added": 1, "updated": 0 }) response = add_entry_to_intelfeed(api, 'additional.test.dev', None) assert response['response'] == 'SUCCESS' assert response['added'] == 1 assert response['updated'] == 0 response = add_entry_to_intelfeed(api, '400.1.1.1', None) assert response == 'Not a valid domain, hostname, ip address or file' response = add_entry_to_intelfeed(api, 'https://www.google.com', None) assert response == 'Not a valid domain, hostname, ip address or file'
def test_search_tag_names(tags): api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=tags) result = search_tags(api, 'A*', None) assert len(result) == 5 result = search_tags(api, '*Threat', None) assert len(result) == 1 assert result[0]['name'] == 'Active Threat' result = search_tags(api, 'Antigen?', None) assert len(result) == 1 result = search_tags(api, 'Antigen*', None) assert len(result) == 2 result = search_tags(api, 'Android D?vice', None) assert len(result) == 1 assert result[0]['name'] == 'Android Device'
def test_deletion_of_device_tag(delete_responses): api = Api('http://127.0.0.1', 'pubkey', 'privkey') for i in [200, 201, 202, 204]: api.delete = MagicMock(return_value=delete_responses[i]) result = modify_device_tags(api, 'delete', 'Admin', '10000000') assert result['status_code'] == i assert result['status'] == 'success' for i in [401, 403, 405, 409]: api.delete = MagicMock(return_value=delete_responses[i]) result = modify_device_tags(api, 'delete', 'Admin', '10000000') assert result['status_code'] == i assert result['status'] == 'unauthorized' for i in [501, 502]: api.delete = MagicMock(return_value=delete_responses[i]) result = modify_device_tags(api, 'delete', 'Admin', '10000000') assert result['status_code'] == i assert result['status'] == 'error'
def test_get_info(): data_file = 'tests/data/time.json' with open(data_file) as infile: json_data = json.load(infile) api = Api('http://127.0.0.1', 'pubkey', 'privkey') api.get = MagicMock(return_value=json_data) result = get_info(api) assert json_data['antigena'] == result['antigena'] assert json_data['antigenainternet'] == result['antigenainternet'] assert json_data['antigenanetwork'] == result['antigenanetwork'] assert json_data['build'] == result['build'] assert json_data['inoculation'] == result['inoculation'] assert json_data['mobileAppConfigured'] == result['mobileAppConfigured'] assert json_data['time'] == result['time'] assert json_data['timems'] == result['timems'] assert json_data['uptime'] == result['uptime'] assert json_data['version'] == result['version']
def test_api_endpoint_not_supported(requests_mock): api = Api(HOST, PUB_DTKEY, PRIVKEY) entry = 'test.test.test' # Darktrace provides positive status_codes, even on redirects requests_mock.post(HOST + '/intelfeed?addentry', text='<title>Darktrace | Login</title>', status_code=200) requests_mock.get(HOST + '/non-supported-endpoint', text='<title>Darktrace | Login</title>', status_code=201) with pytest.raises(SystemExit) as exc_info: _ = api.post('/intelfeed', postdata={'addentry': entry}, addentry=entry) assert 'API endpoint not supported' == exc_info.value.args[0] with pytest.raises(SystemExit) as exc_info: _ = api.get('/non-supported-endpoint') assert 'API endpoint not supported' == exc_info.value.args[0]
def test_default_values(): api = Api(HOST, PUB_DTKEY, PRIVKEY) assert api.ca_cert is None assert not api.insecure assert not api.debug