#!/usr/bin/env python3 import unittest import time import os from pyvulnerabilitylookup import PyVulnerabilityLookup # NOTE: # * to run the tests with a pre-configured admin key: # API_KEY="" pytest tests/test_web.py # * to run the test against a local instance (fallback to public): # INSTANCE_URL="http://0.0.0.0:10001" pytest tests/test_web.py class TestPublic(unittest.TestCase): def setUp(self) -> None: self.admin_token = os.getenv("API_KEY", '').strip() instance_url = os.getenv("INSTANCE_URL", 'https://vulnerability.circl.lu').strip() self.public_test = instance_url == 'https://vulnerability.circl.lu' self.client = PyVulnerabilityLookup(root_url=instance_url, token=self.admin_token) def test_up(self) -> None: self.assertTrue(self.client.is_up) self.assertTrue(self.client.redis_up()) def test_get_vulnerability(self) -> None: while True: if vuln := self.client.get_vulnerability('PYSEC-2024-4'): self.assertEqual(vuln['id'], 'PYSEC-2024-4') break print('waiting for pysec to be imported') time.sleep(1) def test_get_info(self) -> None: info = self.client.get_info() self.assertTrue(info['last_updates']) self.assertTrue(info['db_sizes']) def test_get_last(self) -> None: last = self.client.get_last() self.assertTrue(last) self.assertTrue(isinstance(last, list)) last = self.client.get_last(number=1) self.assertTrue(isinstance(last, list)) self.assertEqual(len(last), 1) last = self.client.get_last(source='pysec') for vuln in last: self.assertTrue(vuln['id'].startswith('PYSEC')) last = self.client.get_last(source='pysec', number=1) self.assertEqual(len(last), 1) self.assertTrue(last[-1]['id'].startswith('PYSEC')) # TODO: POST Vulnerability / Delete vulnerability # Test API def test_get_vendors(self) -> None: vendors = self.client.get_vendors() self.assertTrue(isinstance(vendors, list)) def test_get_vendor_products(self) -> None: if not self.public_test: return None products = self.client.get_vendor_products('misp') self.assertTrue(isinstance(products, list)) self.assertTrue('misp' in products) def test_get_vendor_product_vulnerabilities(self) -> None: if not self.public_test: return None vulns = self.client.get_vendor_product_vulnerabilities('misp', 'misp') self.assertTrue(isinstance(vulns, dict)) self.assertTrue('cvelistv5' in vulns) # Test comments def test_get_comments_public(self) -> None: if not self.public_test: return None comments = self.client.get_comments() self.assertTrue('metadata' in comments) self.assertTrue('data' in comments) self.assertTrue(len(comments['data']) > 0) comments = self.client.get_comments(uuid='a309d024-2714-4a81-a425-60f83f6d5740') self.assertTrue(len(comments['data']) == 1) self.assertEqual(comments['data'][0]['uuid'], 'a309d024-2714-4a81-a425-60f83f6d5740') comments = self.client.get_comments(vuln_id='CVE-2024-20401') self.assertTrue(len(comments['data']) >= 1) for comment in comments['data']: self.assertEqual(comment['vulnerability'], 'CVE-2024-20401') comments = self.client.get_comments(author='admin') self.assertTrue(len(comments['data']) >= 1) for comment in comments['data']: self.assertEqual(comment['author']['login'], 'admin') comments = self.client.get_comments(uuid='a309d024-2714-4a81-a425-60f83f6d5740', vuln_id='CVE-2024-20401', author='admin') self.assertTrue(len(comments['data']) == 1) self.assertEqual(comments['data'][0]['uuid'], 'a309d024-2714-4a81-a425-60f83f6d5740') self.assertEqual(comments['data'][0]['vulnerability'], 'CVE-2024-20401') self.assertEqual(comments['data'][0]['author']['login'], 'admin') def test_comments_local(self) -> None: if not self.admin_token: # this test is only working if the admin token is set return None # Makes sure the userkey is set to the right one self.client.set_apikey(self.admin_token) comment = {'title': 'test', 'description': 'test', 'vulnerability': 'CVE-2024-20401', 'related_vulnerabilities': ['CVE-2024-20402']} created_comment = self.client.create_comment(comment) new_comment_uuid = created_comment['data'][0]['uuid'] comments = self.client.get_comments(uuid=new_comment_uuid) self.assertTrue(len(comments['data']) == 1) deleted_comment = self.client.delete_comment(new_comment_uuid) self.assertTrue(deleted_comment < 300) # Test bundles def test_get_bundles_public(self) -> None: if not self.public_test: return None bundles = self.client.get_bundles() self.assertTrue('metadata' in bundles) self.assertTrue('data' in bundles) self.assertTrue(len(bundles['data']) > 0) bundles = self.client.get_bundles(uuid='a23cbcad-e890-4df8-8736-9332ed4c3d47') self.assertTrue(len(bundles['data']) == 1) self.assertEqual(bundles['data'][0]['uuid'], 'a23cbcad-e890-4df8-8736-9332ed4c3d47') bundles = self.client.get_bundles(vuln_id='CVE-2024-39573') self.assertTrue(len(bundles['data']) >= 1) for bundle in bundles['data']: self.assertTrue('CVE-2024-39573' in bundle['related_vulnerabilities']) bundles = self.client.get_bundles(author='admin') self.assertTrue(len(bundles['data']) >= 1) for bundle in bundles['data']: self.assertEqual(bundle['author']['login'], 'admin') bundles = self.client.get_bundles(uuid='a23cbcad-e890-4df8-8736-9332ed4c3d47', vuln_id='CVE-2024-39573', author='admin') self.assertTrue(len(bundles['data']) == 1) self.assertEqual(bundles['data'][0]['uuid'], 'a23cbcad-e890-4df8-8736-9332ed4c3d47') self.assertTrue('CVE-2024-39573' in bundles['data'][0]['related_vulnerabilities']) self.assertEqual(bundles['data'][0]['author']['login'], 'admin') def test_bundles_local(self) -> None: if not self.admin_token: # this test is only working if the admin token is set return None # Makes sure the userkey is set to the right one self.client.set_apikey(self.admin_token) bundle = {'name': 'test', 'description': 'test', 'related_vulnerabilities': ['CVE-2024-20402', 'CVE-2024-20403']} created_bundle = self.client.create_bundle(bundle) new_bundle_uuid = created_bundle['data'][0]['uuid'] bundles = self.client.get_bundles(uuid=new_bundle_uuid) self.assertTrue(len(bundles['data']) == 1) deleted_bundle = self.client.delete_bundle(new_bundle_uuid) self.assertTrue(deleted_bundle < 300) # Test User def test_list_users(self) -> None: if not self.admin_token: # this test is only working if the admin token is set return None # Makes sure the userkey is set to the right one self.client.set_apikey(self.admin_token) users = self.client.list_users() self.assertTrue(isinstance(users, dict)) self.assertTrue(len(users['data']) > 0) got_admin = False for user in users['data']: self.assertTrue('login' in user) self.assertTrue('apikey' in user) if user['apikey'] == self.admin_token: self.assertTrue(user['is_admin']) got_admin = True self.assertTrue(got_admin) def test_create_user_comment(self) -> None: if self.public_test: # Do not run that test against the public instance, it would create users. return None instance_config = self.client.get_config_info() if not instance_config.get('registration'): return None user = self.client.create_user('test Name', 'test Login', 'test Organization', 'test@testorg.lu') self.assertTrue(user) self.assertTrue('login' in user, user) self.assertTrue('apikey' in user, user) self.assertTrue('is_commenter' in user, user) self.assertTrue(user['is_commenter']) self.client.set_apikey(user['apikey']) comment = {'title': 'test', 'description': 'test', 'vulnerability': 'CVE-2024-20401', 'related_vulnerabilities': ['CVE-2024-20402']} created_comment = self.client.create_comment(comment) new_comment_uuid = created_comment['data'][0]['uuid'] comments = self.client.get_comments(uuid=new_comment_uuid) self.assertTrue(len(comments['data']) == 0, comments) deleted_comment = self.client.delete_comment(new_comment_uuid) self.assertTrue(deleted_comment < 300)