def test_add_workflow(datastore, login_session): _, session, host = login_session workflow = random_model_obj(Workflow).as_primitives() workflow['query'] = "sha256:[1 AND 'This is invalid!'" workflow['creator'] = 'admin' workflow['edited_by'] = 'admin' with pytest.raises(APIError): resp = get_api_data(session, f"{host}/api/v4/workflow/", method="PUT", data=json.dumps(workflow)) workflow['query'] = "file.sha256:*" resp = get_api_data(session, f"{host}/api/v4/workflow/", method="PUT", data=json.dumps(workflow)) assert resp['success'] workflow['workflow_id'] = resp['workflow_id'] workflow_list.append(resp['workflow_id']) datastore.workflow.commit() new_workflow = datastore.workflow.get(resp['workflow_id'], as_obj=False) assert new_workflow == workflow
def test_backup_and_restore(datastore, login_session): _, session, host = login_session backup = get_api_data(session, f"{host}/api/v4/service/backup/", raw=True) assert isinstance(backup, bytes) backup_data = yaml.safe_load(backup) assert isinstance(backup_data, dict) assert 'type' in backup_data assert 'server' in backup_data assert 'data' in backup_data service = random.choice(list(TEMP_SERVICES.keys())) resp = get_api_data(session, f"{host}/api/v4/service/{service}/", method="DELETE") assert resp['success'] datastore.service_delta.commit() assert datastore.service_delta.search(f"id:{service}", rows=0)['total'] == 0 resp = get_api_data(session, f"{host}/api/v4/service/restore/", data=backup, method="PUT") datastore.service_delta.commit() assert datastore.service_delta.search(f"id:{service}", rows=0)['total'] == 1
def test_delete_signature_source(datastore, login_session): _, session, host = login_session ds = datastore invalid_service = random.choice( ds.service.search("NOT _exists_:update_config.generates_signatures", rows=100, as_obj=False)['items']) with pytest.raises(APIError): resp = get_api_data( session, f"{host}/api/v4/signature/sources/{invalid_service['name']}/TEST_SOURCE/", method="DELETE") service = random.choice( ds.service.search("update_config.generates_signatures:true", rows=100, as_obj=False)['items']) service_data = ds.get_service_with_delta(service['name'], as_obj=False) source_name = service_data['update_config']['sources'][0]['name'] resp = get_api_data( session, f"{host}/api/v4/signature/sources/{service['name']}/{source_name}/", method="DELETE") assert resp['success'] ds.service.commit() new_service_data = ds.get_service_with_delta(service['name'], as_obj=False) found = False for source in new_service_data['update_config']['sources']: if source['name'] == source_name: found = True assert not found
def test_set_workflow(datastore, login_session): _, session, host = login_session workflow_id = random.choice(workflow_list) workflow_data = datastore.workflow.get(workflow_id, as_obj=False) workflow_data['edited_by'] = 'admin' workflow_data['hit_count'] = 111 workflow_data['last_seen'] = now_as_iso() workflow_data['query'] = "query:[1 AND 'THIS IS INVALID'" with pytest.raises(APIError): resp = get_api_data(session, f"{host}/api/v4/workflow/{workflow_id}/", method="POST", data=json.dumps(workflow_data)) workflow_data['query'] = "file.sha256:12*" resp = get_api_data(session, f"{host}/api/v4/workflow/{workflow_id}/", method="POST", data=json.dumps(workflow_data)) assert resp['success'] datastore.workflow.commit() new_workflow = datastore.workflow.get(workflow_id, as_obj=False) new_workflow['last_edit'] = workflow_data['last_edit'] assert workflow_data == new_workflow
def test_set_verdict(datastore, login_session): _, session, host = login_session submission = random.choice( datastore.submission.search("id:*", rows=NUM_SUBMISSIONS, as_obj=False)['items']) # Test setting MALICIOUS verdict resp = get_api_data( session, f"{host}/api/v4/submission/verdict/{submission['sid']}/malicious/", method="PUT") assert resp['success'] datastore.submission.commit() submission_data = datastore.submission.get(submission['sid']) assert 'admin' in submission_data['verdict']['malicious'] assert 'admin' not in submission_data['verdict']['non_malicious'] # Test setting NON-MALICOUS verdict resp = get_api_data( session, f"{host}/api/v4/submission/verdict/{submission['sid']}/non_malicious/", method="PUT") assert resp['success'] datastore.submission.commit() submission_data = datastore.submission.get(submission['sid']) assert 'admin' not in submission_data['verdict']['malicious'] assert 'admin' in submission_data['verdict']['non_malicious']
def test_setup_watch_queue(datastore, login_session): _, session, host = login_session with pytest.raises(APIError, match="No dispatchers are processing this submission."): get_api_data( session, f"{host}/api/v4/live/setup_watch_queue/{test_submission.sid}/")
def test_agree_to_tos(datastore, login_session): _, session, host = login_session username = random.choice(user_list) with pytest.raises(APIError): resp = get_api_data(session, f"{host}/api/v4/user/tos/{username}/") resp = get_api_data(session, f"{host}/api/v4/user/tos/admin/") assert resp['success']
def test_doc(datastore, login_session): _, session, host = login_session api_list = get_api_data(session, f"{host}/api/") assert len(api_list) > 0 for api in api_list: resp = get_api_data(session, f"{host}/api/{api}/") assert 'apis' in resp and 'blueprints' in resp
def test_login(datastore, login_session): user_info, session, host = login_session assert user_info['username'] == "admin" resp = get_api_data(session, f"{host}/api/") assert isinstance(resp, list) resp = get_api_data(session, f"{host}/api/v4/auth/logout/") assert resp.get('success', False) is True
def test_add_update_signature_many(datastore, login_session): _, session, host = login_session ds = datastore # Insert a dummy signature source = "source" s_type = "type" sig_list = [] for x in range(10): data = random_model_obj(Signature).as_primitives() data['signature_id'] = f"test_sig_{x}" data['name'] = f"sig_name_{x}" data['status'] = "DEPLOYED" data['source'] = source data['type'] = s_type sig_list.append(data) uri = f"{host}/api/v4/signature/add_update_many/?source={source}&sig_type={s_type}" resp = get_api_data(session, uri, data=json.dumps(sig_list), method="PUT") assert resp == {'errors': False, 'success': 10, 'skipped': []} # Test the signature data ds.signature.commit() data = random.choice(sig_list) key = f"{data['type']}_{data['source']}_{data['signature_id']}" added_sig = ds.signature.get(key, as_obj=False) assert data == added_sig # Change the signature status resp = get_api_data( session, f"{host}/api/v4/signature/change_status/{key}/DISABLED/") ds.signature.commit() assert resp['success'] # Update signature data new_sig_data = "NEW SIGNATURE DATA" data['data'] = new_sig_data uri = f"{host}/api/v4/signature/add_update_many/?source={source}&sig_type={s_type}" resp = get_api_data(session, uri, data=json.dumps([data]), method="POST") assert resp == {'errors': False, 'success': 1, 'skipped': []} # Remove state change data data.pop('status', None) data.pop('state_change_date', None) data.pop('state_change_user', None) # Test the signature data ds.signature.commit() modded_sig = ds.signature.get(key, as_obj=False) modded_sig.pop('state_change_date') # Was state kept? assert "DISABLED" == modded_sig.pop('status') # Was state_change_user kept? assert "admin" == modded_sig.pop('state_change_user') assert data == modded_sig
def test_setup_watch_queue(datastore, login_session): _, session, host = login_session resp = get_api_data( session, f"{host}/api/v4/live/setup_watch_queue/{test_submission.sid}/") assert resp['wq_id'].startswith("D-") and resp['wq_id'].endswith("-WQ") resp = get_api_data(session, f"{host}/api/v4/live/get_message/{resp['wq_id']}/") assert resp['type'] == 'start'
def test_update_available(datastore, login_session): _, session, host = login_session resp = get_api_data(session, f"{host}/api/v4/signature/update_available/") assert resp == {'update_available': True} params = {'last_update': '2030-01-01T00:00:00.000000Z'} resp = get_api_data(session, f"{host}/api/v4/signature/update_available/", params=params) assert resp == {'update_available': False}
def test_ownership(datastore, login_session): _, session, host = login_session resp = get_api_data( session, f"{host}/api/v4/alert/ownership/{test_alert.alert_id}/") assert resp.get('success', False) datastore.alert.commit() resp = get_api_data(session, f"{host}/api/v4/alert/ownership/batch/", params={'q': "id:*"}) assert resp.get('success', 0) > 0
def test_otp(datastore, login_session): _, session, host = login_session resp = get_api_data(session, f"{host}/api/v4/auth/setup_otp/") secret_key = resp.get('secret_key', None) assert secret_key is not None resp = get_api_data(session, f"{host}/api/v4/auth/validate_otp/{get_totp_token(secret_key)}/") if not resp.get('success', False): resp = get_api_data(session, f"{host}/api/v4/auth/validate_otp/{get_totp_token(secret_key)}/") assert resp.get('success', False) is True resp = get_api_data(session, f"{host}/api/v4/auth/disable_otp/") assert resp.get('success', False) is True
def test_add_update_signature(datastore, login_session): _, session, host = login_session ds = datastore # Insert a dummy signature data = random_model_obj(Signature).as_primitives() data['status'] = "DEPLOYED" key = f'{data["type"]}_{data["source"]}_{data["signature_id"]}' resp = get_api_data(session, f"{host}/api/v4/signature/add_update/", data=json.dumps(data), method="PUT") assert resp == {'id': key, 'success': True} # Test the signature data ds.signature.commit() added_sig = ds.signature.get(key, as_obj=False) assert data == added_sig # Change the signature status resp = get_api_data( session, f"{host}/api/v4/signature/change_status/{key}/DISABLED/") ds.signature.commit() assert resp['success'] # Update signature data new_sig_data = "NEW SIGNATURE DATA" data['data'] = new_sig_data resp = get_api_data(session, f"{host}/api/v4/signature/add_update/", data=json.dumps(data), method="POST") assert resp == {'id': key, 'success': True} # Remove state change data data.pop('status', None) data.pop('state_change_date', None) data.pop('state_change_user', None) # Test the signature data ds.signature.commit() modded_sig = ds.signature.get(key, as_obj=False) modded_sig.pop('state_change_date') # Was state kept? assert "DISABLED" == modded_sig.pop('status') # Was state_change_user kept? assert "admin" == modded_sig.pop('state_change_user') assert data == modded_sig
def test_get_service(datastore, login_session): _, session, host = login_session service = random.choice(list(SERVICES.keys())) resp = get_api_data(session, f"{host}/api/v4/service/{service}/") service_data = datastore.get_service_with_delta(service, as_obj=False) assert resp == service_data
def test_get_error(datastore, login_session): _, session, host = login_session resp = get_api_data(session, f"{host}/api/v4/error/{test_error.build_key()}/") err = Error(resp) assert err == test_error
def test_edit_service(datastore, login_session): _, session, host = login_session ds = datastore delta_data = ds.service_delta.search("id:*", rows=100, as_obj=False) svc_data = ds.service.search("id:*", rows=100, as_obj=False) service = random.choice(list(TEMP_SERVICES.keys())) service_data = Service({ "name": service, "enabled": True, "category": TEMP_SERVICES[service][0], "stage": TEMP_SERVICES[service][1], "version": "3.3.0", "docker_config": { "image": f"cccs/alsvc_{service.lower()}:latest", }, }).as_primitives() resp = get_api_data(session, f"{host}/api/v4/service/{service}/", method="POST", data=json.dumps(service_data)) assert resp['success'] ds.service_delta.commit() ds.service.commit() new_delta_data = ds.service_delta.search("id:*", rows=100, as_obj=False) new_svc_data = ds.service.search("id:*", rows=100, as_obj=False) assert new_delta_data != delta_data assert new_svc_data == svc_data for svc in new_delta_data['items']: if svc['id'] == service: assert svc['version'] == '3.3.0' else: assert svc['version'] == '4.0.0'
def test_get_user_settings(datastore, login_session): _, session, host = login_session username = random.choice(user_list) resp = get_api_data(session, f"{host}/api/v4/user/settings/{username}/") assert {'deep_scan', 'download_encoding', 'ignore_cache'}.issubset(set(resp.keys()))
def test_delete_service(datastore, login_session): _, session, host = login_session ds = datastore service = random.choice(list(SERVICES.keys())) resp = get_api_data(session, f"{host}/api/v4/service/{service}/", method="DELETE") assert resp['success'] ds.service_delta.commit() delta_data = ds.service_delta.search("id:*", rows=100, as_obj=False) assert delta_data['total'] == (len(SERVICES) - 1) for svc in delta_data['items']: assert svc['id'] != service ds.service.commit() svc_data = ds.service.search("id:*", rows=100, as_obj=False) assert (svc_data['total'] / 2) == (len(SERVICES) - 1) for svc in svc_data['items']: assert svc['id'] != service SERVICES.pop(service, None)
def test_outstanding_services(datastore, login_session): _, session, host = login_session resp = get_api_data( session, f"{host}/api/v4/live/outstanding_services/{test_submission.sid}/") assert isinstance(resp, dict)
def test_get_message(datastore, login_session): _, session, host = login_session r = random_model_obj(Result) wq.push({'status': "OK", 'cache_key': r.build_key()}) resp = get_api_data(session, f"{host}/api/v4/live/get_message/{wq_id}/") assert resp['msg'] == r.build_key()
def test_get_workflow(datastore, login_session): _, session, host = login_session workflow_id = random.choice(workflow_list) resp = get_api_data(session, f"{host}/api/v4/workflow/{workflow_id}/") assert resp == datastore.workflow.get(workflow_id, as_obj=False)
def test_alert_create_bundle(datastore, login_session): _, session, host = login_session resp = get_api_data(session, f"{host}/api/v4/bundle/{ALERT_ID}/?use_alert", raw=True) assert is_cart(resp[:256])
def test_import_bundle(datastore, login_session, filestore): _, session, host = login_session ds = datastore # Create a temporary bundle submission = random.choice( ds.submission.search('id:*', rows=100, as_obj=False)['items']) bundle_file = create_bundle(submission['sid'], working_dir='/tmp/bundle') # Delete associated submission ds.delete_submission_tree(submission['sid'], transport=filestore) ds.error.commit() ds.file.commit() ds.result.commit() ds.submission.commit() with open(bundle_file, 'rb') as bfh: resp = get_api_data(session, f"{host}/api/v4/bundle/", method="POST", data=bfh.read()) assert resp['success'] ds.submission.commit() assert submission == random.choice( ds.submission.search('id:*', rows=100, as_obj=False)['items'])
def test_get_fields(datastore, login_session): _, session, host = login_session for collection in collections: resp = get_api_data(session, f"{host}/api/v4/search/fields/{collection}/") for v in resp.values(): assert list(v.keys()) == ['default', 'indexed', 'list', 'stored', 'type']
def test_submit_binary(datastore, login_session): _, session, host = login_session sq.delete() byte_str = get_random_phrase(wmin=30, wmax=75).encode() fd, temp_path = tempfile.mkstemp() try: with os.fdopen(fd, 'wb') as fh: fh.write(byte_str) with open(temp_path, 'rb') as fh: sha256 = hashlib.sha256(byte_str).hexdigest() json_data = { 'name': 'text.txt', 'metadata': {'test': 'test_submit_binary'} } data = {'json': json.dumps(json_data)} resp = get_api_data(session, f"{host}/api/v4/submit/", method="POST", data=data, files={'bin': fh}, headers={}) assert isinstance(resp['sid'], str) for f in resp['files']: assert f['sha256'] == sha256 assert f['name'] == json_data['name'] msg = SubmissionTask(sq.pop(blocking=False)) assert msg.submission.sid == resp['sid'] finally: # noinspection PyBroadException try: os.unlink(temp_path) except Exception: pass
def test_get_ontology_for_submission(datastore, login_session): _, session, host = login_session data = get_api_data(session, f"{host}/api/v4/ontology/submission/{test_submission.sid}/", raw=True) res = [json.loads(line) for line in data.splitlines()] assert len(res) != 0 assert any([record['header']['sha256'] == test_submission.files[0].sha256 for record in res])
def test_delete_service(datastore, login_session): global TEMP_SERVICES _, session, host = login_session ds = datastore service = random.choice( [x for x in TEMP_SERVICES.keys() if x != 'Suricata']) resp = get_api_data(session, f"{host}/api/v4/service/{service}/", method="DELETE") assert resp['success'] ds.service_delta.commit() delta_data = ds.service_delta.search("id:*", rows=100, as_obj=False) assert delta_data['total'] == (len(TEMP_SERVICES) - 1) for svc in delta_data['items']: assert svc['id'] != service ds.service.commit() svc_data = ds.service.search("id:*", rows=100, as_obj=False) for svc in svc_data['items']: assert svc['name'] != service TEMP_SERVICES.pop(service, None)
def test_related(datastore, login_session): _, session, host = login_session resp = get_api_data(session, f"{host}/api/v4/alert/related/", params={'q': "id:*"}) assert isinstance(resp, list)