mirror of
https://github.com/cve-search/PyVulnerabilityLookup.git
synced 2024-11-25 16:27:23 +00:00
new: Add all missing endpoints, update existing ones.
Some checks failed
Python application - MyPy / Python 3.10 sample (push) Has been cancelled
Python application - MyPy / Python 3.11 sample (push) Has been cancelled
Python application - MyPy / Python 3.12 sample (push) Has been cancelled
Python application - MyPy / Python 3.13 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.10 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.11 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.12 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.13 sample (push) Has been cancelled
Some checks failed
Python application - MyPy / Python 3.10 sample (push) Has been cancelled
Python application - MyPy / Python 3.11 sample (push) Has been cancelled
Python application - MyPy / Python 3.12 sample (push) Has been cancelled
Python application - MyPy / Python 3.13 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.10 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.11 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.12 sample (push) Has been cancelled
Python application - Test Public Interface / Python 3.13 sample (push) Has been cancelled
This commit is contained in:
parent
97ca98f4ff
commit
51bcb96d61
2 changed files with 150 additions and 26 deletions
|
@ -65,6 +65,20 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.get(urljoin(self.root_url, 'redis_up'))
|
r = self.session.get(urljoin(self.root_url, 'redis_up'))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
|
# #### DB status ####
|
||||||
|
|
||||||
|
def get_info(self) -> dict[str, Any]:
|
||||||
|
'''Get more information about the current databases in use and when it was updated'''
|
||||||
|
r = self.session.get(urljoin(self.root_url, 'info'))
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
def get_config_info(self) -> dict[str, Any]:
|
||||||
|
'''Get more information about the current databases in use and when it was updated'''
|
||||||
|
r = self.session.get(urljoin(self.root_url, 'configInfo'))
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
# #### Vulnerabilities ####
|
||||||
|
|
||||||
def get_vulnerability(self, vulnerability_id: str) -> dict[str, Any]:
|
def get_vulnerability(self, vulnerability_id: str) -> dict[str, Any]:
|
||||||
'''Get a vulnerability
|
'''Get a vulnerability
|
||||||
|
|
||||||
|
@ -90,16 +104,6 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('vulnerability', vulnerability_id))))
|
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('vulnerability', vulnerability_id))))
|
||||||
return r.status_code
|
return r.status_code
|
||||||
|
|
||||||
def get_info(self) -> dict[str, Any]:
|
|
||||||
'''Get more information about the current databases in use and when it was updated'''
|
|
||||||
r = self.session.get(urljoin(self.root_url, 'info'))
|
|
||||||
return r.json()
|
|
||||||
|
|
||||||
def get_config_info(self) -> dict[str, Any]:
|
|
||||||
'''Get more information about the current databases in use and when it was updated'''
|
|
||||||
r = self.session.get(urljoin(self.root_url, 'configInfo'))
|
|
||||||
return r.json()
|
|
||||||
|
|
||||||
def get_last(self, number: int | None=None, source: str | None = None) -> list[dict[str, Any]]:
|
def get_last(self, number: int | None=None, source: str | None = None) -> list[dict[str, Any]]:
|
||||||
'''Get the last vulnerabilities
|
'''Get the last vulnerabilities
|
||||||
|
|
||||||
|
@ -115,7 +119,7 @@ class PyVulnerabilityLookup():
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def get_vendors(self) -> list[str]:
|
def get_vendors(self) -> list[str]:
|
||||||
'''Get the list of known vendors'''
|
'''Get the known vendors'''
|
||||||
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'browse'))))
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'browse'))))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
|
@ -136,15 +140,42 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'search', vendor, product))))
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'search', vendor, product))))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
# NOTE: endpoints /api/cve/*, /api/dbInfo, /api/last are alises for backward compat.
|
# #### Comments ####
|
||||||
|
|
||||||
def create_comment(self, comment: dict[str, Any]) -> dict[str, Any]:
|
def create_comment(self, /, *, comment: dict[str, Any] | None=None, description: str | None=None,
|
||||||
|
description_format: str | None = None, meta: dict[str, str] | None = None,
|
||||||
|
related_vulnerabilities: list[str] | None=None, title: str | None=None,
|
||||||
|
uuid: str | None=None, vulnerability: str | None = None) -> dict[str, Any]:
|
||||||
'''Create a comment.
|
'''Create a comment.
|
||||||
|
|
||||||
:param comment: The comment
|
:param comment: The comment
|
||||||
|
:param description: The description of the comment
|
||||||
|
:param description_format: Description format (markdown or text).
|
||||||
|
:param meta: Zero or more meta-fields.
|
||||||
|
:param related_vulnerabilities: Zero or more related vulnerabilities.
|
||||||
|
:param title: The title of the comment
|
||||||
|
:param uuid: The UUID of the comment
|
||||||
|
:param vulnerability: The vulnerability ID of the comment
|
||||||
'''
|
'''
|
||||||
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'comment'))),
|
|
||||||
json=comment)
|
if not comment:
|
||||||
|
comment = {}
|
||||||
|
if description:
|
||||||
|
comment['description'] = description
|
||||||
|
if description_format:
|
||||||
|
comment['description_format'] = description_format
|
||||||
|
if meta:
|
||||||
|
comment['meta'] = meta
|
||||||
|
if related_vulnerabilities:
|
||||||
|
comment['related_vulnerabilities'] = related_vulnerabilities
|
||||||
|
if title:
|
||||||
|
comment['title'] = title
|
||||||
|
if uuid:
|
||||||
|
comment['uuid'] = uuid
|
||||||
|
if vulnerability:
|
||||||
|
comment['vulnerability'] = vulnerability
|
||||||
|
|
||||||
|
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'comment'))), json=comment)
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def get_comments(self, uuid: str | None = None, vuln_id: str | None = None,
|
def get_comments(self, uuid: str | None = None, vuln_id: str | None = None,
|
||||||
|
@ -159,6 +190,15 @@ class PyVulnerabilityLookup():
|
||||||
params={'uuid': uuid, 'vuln_id': vuln_id, 'author': author})
|
params={'uuid': uuid, 'vuln_id': vuln_id, 'author': author})
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
|
def get_comment(self, comment_uuid: str) -> dict[str, Any]:
|
||||||
|
'''Get a comment
|
||||||
|
|
||||||
|
:param comment_uuid: The UUID of the comment
|
||||||
|
'''
|
||||||
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'comment', comment_uuid)))
|
||||||
|
)
|
||||||
|
return r.json()
|
||||||
|
|
||||||
def delete_comment(self, comment_uuid: str) -> int:
|
def delete_comment(self, comment_uuid: str) -> int:
|
||||||
'''Delete a comment.
|
'''Delete a comment.
|
||||||
|
|
||||||
|
@ -167,25 +207,65 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('api', 'comment', comment_uuid))))
|
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('api', 'comment', comment_uuid))))
|
||||||
return r.status_code
|
return r.status_code
|
||||||
|
|
||||||
def create_bundle(self, bundle: dict[str, Any]) -> dict[str, Any]:
|
# #### Bundles ####
|
||||||
|
|
||||||
|
def create_bundle(self, /, *, bundle: dict[str, Any] | None=None, description: str | None=None,
|
||||||
|
meta: dict[str, str] | None=None, name: str | None=None, related_vulnerabilities: list[str] | None=None,
|
||||||
|
uuid: str | None=None) -> dict[str, Any]:
|
||||||
'''Create a bundle.
|
'''Create a bundle.
|
||||||
|
|
||||||
:param bundle: The bundle
|
:param bundle: The bundle
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
if not bundle:
|
||||||
|
bundle = {}
|
||||||
|
if description:
|
||||||
|
bundle['description'] = description
|
||||||
|
if meta:
|
||||||
|
bundle['meta'] = meta
|
||||||
|
if name:
|
||||||
|
bundle['name'] = name
|
||||||
|
if related_vulnerabilities:
|
||||||
|
bundle['related_vulnerabilities'] = related_vulnerabilities
|
||||||
|
if uuid:
|
||||||
|
bundle['uuid'] = uuid
|
||||||
|
|
||||||
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'bundle'))),
|
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'bundle'))),
|
||||||
json=bundle)
|
json=bundle)
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def get_bundles(self, uuid: str | None = None, vuln_id: str | None = None,
|
def get_bundles(self, uuid: str | None = None, vuln_id: str | None = None,
|
||||||
author: str | None = None) -> dict[str, Any]:
|
author: str | None = None, per_page: int | None=None,
|
||||||
|
meta: list[dict[str, str]] | None=None) -> dict[str, Any]:
|
||||||
'''Get bundle(s)
|
'''Get bundle(s)
|
||||||
|
|
||||||
:param uuid: The UUID a specific bundle
|
:param uuid: The UUID a specific bundle
|
||||||
:param vuln_id: The vulnerability ID to get bundles of
|
:param vuln_id: The vulnerability ID to get bundles of
|
||||||
:param author: The author of the bundle(s)
|
:param author: The author of the bundle(s)
|
||||||
|
:param per_page: The number of bundles to get per page
|
||||||
|
:param meta: Query for the meta JSON field. Example: meta=[{‘tags’: [‘tcp’]}]
|
||||||
'''
|
'''
|
||||||
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'bundle'))),
|
params: dict[str, Any] = {}
|
||||||
params={'uuid': uuid, 'vuln_id': vuln_id, 'author': author})
|
if uuid:
|
||||||
|
params['uuid'] = uuid
|
||||||
|
if vuln_id:
|
||||||
|
params['vuln_id'] = vuln_id
|
||||||
|
if author:
|
||||||
|
params['author'] = author
|
||||||
|
if per_page is not None:
|
||||||
|
params['per_page'] = per_page
|
||||||
|
if meta:
|
||||||
|
params['meta'] = meta
|
||||||
|
|
||||||
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'bundle'))), params=params)
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
def get_bundle(self, bundle_uuid: str) -> dict[str, Any]:
|
||||||
|
'''Get a bundle
|
||||||
|
|
||||||
|
:param bundle_uuid: The UUID of the bundle
|
||||||
|
'''
|
||||||
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'bundle', bundle_uuid))))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def delete_bundle(self, bundle_uuid: str) -> int:
|
def delete_bundle(self, bundle_uuid: str) -> int:
|
||||||
|
@ -196,7 +276,11 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('api', 'bundle', bundle_uuid))))
|
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('api', 'bundle', bundle_uuid))))
|
||||||
return r.status_code
|
return r.status_code
|
||||||
|
|
||||||
def create_user(self, login: str, name: str, organisation: str, email: str) -> dict[str, Any]:
|
# #### Users ####
|
||||||
|
|
||||||
|
def create_user(self, /, *, user: dict[str, Any] | None=None,
|
||||||
|
login: str | None=None, name: str | None=None,
|
||||||
|
organisation: str | None=None, email: str | None=None) -> dict[str, Any]:
|
||||||
'''Create a user.
|
'''Create a user.
|
||||||
|
|
||||||
:param login: The login of the user
|
:param login: The login of the user
|
||||||
|
@ -204,11 +288,26 @@ class PyVulnerabilityLookup():
|
||||||
:param organisation: The organisation of the user
|
:param organisation: The organisation of the user
|
||||||
:param email: The email of the user
|
:param email: The email of the user
|
||||||
'''
|
'''
|
||||||
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'user'))),
|
|
||||||
json={'login': login, 'name': name, 'organisation': organisation, 'email': email})
|
if not user:
|
||||||
|
user = {}
|
||||||
|
if login:
|
||||||
|
user['login'] = login
|
||||||
|
if name:
|
||||||
|
user['name'] = name
|
||||||
|
if organisation:
|
||||||
|
user['organisation'] = organisation
|
||||||
|
if email:
|
||||||
|
user['email'] = email
|
||||||
|
|
||||||
|
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'user'))), json=user)
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def list_users(self) -> dict[str, Any]:
|
def list_users(self) -> dict[str, Any]:
|
||||||
|
# Alias this one to get_users for consistency
|
||||||
|
return self.get_users()
|
||||||
|
|
||||||
|
def get_users(self) -> dict[str, Any]:
|
||||||
'''List users'''
|
'''List users'''
|
||||||
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'user'))))
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'user'))))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
@ -218,6 +317,20 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'user', 'me'))))
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'user', 'me'))))
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
|
def reset_api_key(self) -> dict[str, Any]:
|
||||||
|
'''Reset the API key'''
|
||||||
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'user', 'api_key'))))
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
def delete_user(self, user_id: str) -> int:
|
||||||
|
'''Delete a user.
|
||||||
|
|
||||||
|
:param user_id: The user ID
|
||||||
|
'''
|
||||||
|
r = self.session.delete(urljoin(self.root_url, str(PurePosixPath('api', 'user', user_id)))
|
||||||
|
)
|
||||||
|
return r.status_code
|
||||||
|
|
||||||
# #### Sightings ####
|
# #### Sightings ####
|
||||||
|
|
||||||
def get_sighting(self, sighting_uuid: str) -> dict[str, Any]:
|
def get_sighting(self, sighting_uuid: str) -> dict[str, Any]:
|
||||||
|
@ -298,3 +411,13 @@ class PyVulnerabilityLookup():
|
||||||
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'sighting'))),
|
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('api', 'sighting'))),
|
||||||
json=sighting)
|
json=sighting)
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
|
# #### EPSS ####
|
||||||
|
|
||||||
|
def get_epss(self, vulnerability: str) -> dict[str, Any]:
|
||||||
|
'''Get the EPSS for a vulnerability
|
||||||
|
|
||||||
|
:param vulnerability: The vulnerability ID
|
||||||
|
'''
|
||||||
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('api', 'epss', vulnerability))))
|
||||||
|
return r.json()
|
||||||
|
|
|
@ -127,7 +127,7 @@ class TestPublic(unittest.TestCase):
|
||||||
"vulnerability": "CVE-2024-20401",
|
"vulnerability": "CVE-2024-20401",
|
||||||
"related_vulnerabilities": ["ghsa-4rcj-fmjg-q9fv"],
|
"related_vulnerabilities": ["ghsa-4rcj-fmjg-q9fv"],
|
||||||
}
|
}
|
||||||
comments = self.client.create_comment(comment)
|
comments = self.client.create_comment(comment=comment)
|
||||||
self.assertTrue(len(comments["data"]) == 1)
|
self.assertTrue(len(comments["data"]) == 1)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
comments["data"][0]["uuid"], "a309d024-2714-4a81-a425-60f83f6d5740"
|
comments["data"][0]["uuid"], "a309d024-2714-4a81-a425-60f83f6d5740"
|
||||||
|
@ -215,7 +215,7 @@ class TestPublic(unittest.TestCase):
|
||||||
"description_format": "markdown",
|
"description_format": "markdown",
|
||||||
"related_vulnerabilities": ["ghsa-4rcj-fmjg-q9fv", "CVE-2024-39573"],
|
"related_vulnerabilities": ["ghsa-4rcj-fmjg-q9fv", "CVE-2024-39573"],
|
||||||
}
|
}
|
||||||
bundles = self.client.create_bundle(bundle)
|
bundles = self.client.create_bundle(bundle=bundle)
|
||||||
self.assertTrue(len(bundles["data"]) == 1)
|
self.assertTrue(len(bundles["data"]) == 1)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
bundles["data"][0]["uuid"], "a23cbcad-e890-4df8-8736-9332ed4c3d47"
|
bundles["data"][0]["uuid"], "a23cbcad-e890-4df8-8736-9332ed4c3d47"
|
||||||
|
@ -293,7 +293,8 @@ class TestPublic(unittest.TestCase):
|
||||||
if not instance_config.get('registration'):
|
if not instance_config.get('registration'):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
user = self.client.create_user('test Name', 'test Login', 'test Organization', 'test@testorg.lu')
|
user = self.client.create_user(name='test Name', login='test Login',
|
||||||
|
organisation='test Organization', email='test@testorg.lu')
|
||||||
self.assertTrue(user)
|
self.assertTrue(user)
|
||||||
self.assertTrue('login' in user, user)
|
self.assertTrue('login' in user, user)
|
||||||
self.assertTrue('apikey' in user, user)
|
self.assertTrue('apikey' in user, user)
|
||||||
|
@ -303,7 +304,7 @@ class TestPublic(unittest.TestCase):
|
||||||
comment = {'title': 'test', 'description': 'test',
|
comment = {'title': 'test', 'description': 'test',
|
||||||
'vulnerability': 'CVE-2024-20401',
|
'vulnerability': 'CVE-2024-20401',
|
||||||
'related_vulnerabilities': ['CVE-2024-20402']}
|
'related_vulnerabilities': ['CVE-2024-20402']}
|
||||||
created_comment = self.client.create_comment(comment)
|
created_comment = self.client.create_comment(comment=comment)
|
||||||
new_comment_uuid = created_comment['data'][0]['uuid']
|
new_comment_uuid = created_comment['data'][0]['uuid']
|
||||||
comments = self.client.get_comments(uuid=new_comment_uuid)
|
comments = self.client.get_comments(uuid=new_comment_uuid)
|
||||||
self.assertTrue(len(comments['data']) == 0, comments)
|
self.assertTrue(len(comments['data']) == 0, comments)
|
||||||
|
|
Loading…
Reference in a new issue