Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for GET /api/v1/vectors endpoint - fix - snake case #822

Merged
merged 15 commits into from
Jul 29, 2024
10 changes: 5 additions & 5 deletions tenable/apa/vectors/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ def _get_page(self) -> None:
Request the next page of data
"""
payload = copy(self._payload)
payload["pageNumber"] = self._next_page
payload["page_number"] = self._next_page

resp = self._api.get("apa/api/discover/v1/vectors",
params=payload, box=True)
self._next_page = resp.get("pageNumber") + 1
self._next_page = resp.get("page_number") + 1
self.page = resp.data
self.total = resp.get("total")

Expand Down Expand Up @@ -112,11 +112,11 @@ def list(
"""

payload = {
"pageNumber": page_number,
"page_number": page_number,
"limit": limit,
"filter": filter,
"sortField": sort_field,
"sortOrder": sort_order}
"sort_field": sort_field,
"sort_order": sort_order}
if return_iterator:
return VectorIterator(self._api, _payload=payload)
return self._schema.load(
Expand Down
18 changes: 9 additions & 9 deletions tenable/apa/vectors/schema.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from marshmallow import fields, Schema, validates_schema, ValidationError
from marshmallow import fields, Schema


class SourceInformationSchema(Schema):
Expand All @@ -16,7 +16,7 @@ class SourceInformationSchema(Schema):
class TechniqueSchema(Schema):
source_information = fields.Str(allow_none=True)
name = fields.Str(allow_none=True)
fullName = fields.Str(allow_none=True)
full_name = fields.Str(allow_none=True)
asset_id = fields.Str(allow_none=True)
id = fields.Int(allow_none=True)
labels = fields.List(fields.Str(), allow_none=True)
Expand All @@ -25,27 +25,27 @@ class TechniqueSchema(Schema):

class NodeSchema(Schema):
name = fields.Str(allow_none=True)
fullName = fields.Str(allow_none=True)
full_name = fields.Str(allow_none=True)
asset_id = fields.Str(allow_none=True)
id = fields.Int(allow_none=True)
labels = fields.List(fields.Str(), allow_none=True)


class VectorSchema(Schema):
isNew = fields.Bool(allow_none=True)
vectorId = fields.Str(allow_none=True)
is_new = fields.Bool(allow_none=True)
vector_id = fields.Str(allow_none=True)
path = fields.Raw(allow_none=True)
techniques = fields.List(fields.Nested(TechniqueSchema), allow_none=True)
nodes = fields.List(fields.Nested(NodeSchema), allow_none=True)
findingsNames = fields.List(fields.Str(), allow_none=True)
findings_names = fields.List(fields.Str(), allow_none=True)
name = fields.Str(allow_none=True)
summary = fields.Str(allow_none=True)
firstAES = fields.Raw(allow_none=True)
lastACR = fields.Int(allow_none=True)
first_aes = fields.Raw(allow_none=True)
last_acr = fields.Int(allow_none=True)


class VectorsPageSchema(Schema):
data = fields.List(fields.Nested(VectorSchema), allow_none=True)
pageNumber = fields.Int(allow_none=True)
page_number = fields.Int(allow_none=True)
count = fields.Int(allow_none=True)
total = fields.Int(allow_none=True)
36 changes: 18 additions & 18 deletions tests/apa/vectors/test_vectors_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
@pytest.fixture
def vector():
return {
"isNew": False,
"vectorId": "FFF93960363C0755F8C9D93E241DD26E",
"is_new": False,
"vector_id": "FFF93960363C0755F8C9D93E241DD26E",
"path": None,
"techniques": [
{
"source_information": "[{\"provider_detection_id\":\"71246\",\"detection_code\":\"Enumerate Local Group Memberships\",\"reason_code_name\":null,\"asset_id\":\"0bd1382d-8ba7-41d7-bc27-0e874c655737\",\"id\":\"nessus:71246\",\"provider_code\":\"NESSUS\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"44401\",\"detection_code\":\"Microsoft Windows SMB Service Config Enumeration\",\"reason_code_name\":null,\"asset_id\":\"0bd1382d-8ba7-41d7-bc27-0e874c655737\",\"id\":\"nessus:44401\",\"provider_code\":\"NESSUS\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"64582\",\"detection_code\":\"Netstat Connection Information\",\"reason_code_name\":null,\"asset_id\":\"0bd1382d-8ba7-41d7-bc27-0e874c655737\",\"id\":\"nessus:64582\",\"provider_code\":\"NESSUS\",\"type\":\"nessus plugin\",\"reason_id\":null}]",
"name": "Remote Desktop Protocol-251714",
"fullName": "Remote Desktop Protocol-251714",
"full_name": "Remote Desktop Protocol-251714",
"asset_id": "",
"id": 82656,
"labels": [
Expand All @@ -26,7 +26,7 @@ def vector():
{
"source_information": "[{\"provider_detection_id\":\"64582\",\"detection_code\":\"Netstat Connection Information\",\"reason_code_name\":null,\"asset_id\":\"fa6ed6d3-9426-4f7e-b414-373eace37f5f\",\"id\":\"nessus:64582\",\"provider_code\":\"NESSUS\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"191947\",\"detection_code\":null,\"reason_code_name\":null,\"asset_id\":\"fa6ed6d3-9426-4f7e-b414-373eace37f5f\",\"id\":\"nessus:191947\",\"provider_code\":\"NESSUS\",\"plugin_name\":\"\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"191947\",\"detection_code\":null,\"reason_code_name\":null,\"asset_id\":\"fa6ed6d3-9426-4f7e-b414-373eace37f5f\",\"id\":\"nessus:191947\",\"provider_code\":\"NESSUS\",\"plugin_name\":\"KB5035857: Windows 2022 / Azure Stack HCI 22H2 Security Update (March 2024)\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"CVE-2024-21444\",\"detection_code\":\"CVE-2024-21444\",\"reason_code_name\":null,\"id\":\"CVE-2024-21444\",\"provider_code\":\"NVD\",\"type\":\"CVE\",\"reason_id\":null}]",
"name": "Exploitation of Remote Services-20940:251097",
"fullName": "Exploitation of Remote Services-20940:251097",
"full_name": "Exploitation of Remote Services-20940:251097",
"asset_id": "",
"id": 117132,
"labels": [
Expand All @@ -37,7 +37,7 @@ def vector():
{
"source_information": "[{\"provider_detection_id\":\"64582\",\"detection_code\":\"Netstat Connection Information\",\"reason_code_name\":null,\"asset_id\":\"037cb20a-5b0a-40d2-b5cc-3306ee005429\",\"id\":\"nessus:64582\",\"provider_code\":\"NESSUS\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"160937\",\"detection_code\":null,\"reason_code_name\":null,\"asset_id\":\"037cb20a-5b0a-40d2-b5cc-3306ee005429\",\"id\":\"nessus:160937\",\"provider_code\":\"NESSUS\",\"plugin_name\":\"\",\"type\":\"nessus plugin\",\"reason_id\":null},{\"provider_detection_id\":\"CVE-2022-26936\",\"detection_code\":\"CVE-2022-26936\",\"reason_code_name\":null,\"id\":\"CVE-2022-26936\",\"provider_code\":\"NVD\",\"type\":\"CVE\",\"reason_id\":null}]",
"name": "Exploitation of Remote Services-12298:19222",
"fullName": "Exploitation of Remote Services-12298:19222",
"full_name": "Exploitation of Remote Services-12298:19222",
"asset_id": "",
"id": 27049,
"labels": [
Expand All @@ -49,7 +49,7 @@ def vector():
"nodes": [
{
"name": "Domain Users",
"fullName": "APADOMAIN\\domain users",
"full_name": "APADOMAIN\\domain users",
"asset_id": "",
"id": 252949,
"labels": [
Expand All @@ -60,7 +60,7 @@ def vector():
},
{
"name": "APAENG",
"fullName": "apaeng.apadomain.internal",
"full_name": "apaeng.apadomain.internal",
"asset_id": "0bd1382d-8ba7-41d7-bc27-0e874c655737",
"id": 251098,
"labels": [
Expand All @@ -72,7 +72,7 @@ def vector():
},
{
"name": "APADC",
"fullName": "apadc.apadomain.internal",
"full_name": "apadc.apadomain.internal",
"asset_id": "fa6ed6d3-9426-4f7e-b414-373eace37f5f",
"id": 251097,
"labels": [
Expand All @@ -85,7 +85,7 @@ def vector():
},
{
"name": "baaaaacnet",
"fullName": "baaaaacnet.indegy.local",
"full_name": "baaaaacnet.indegy.local",
"asset_id": "037cb20a-5b0a-40d2-b5cc-3306ee005429",
"id": 19222,
"labels": [
Expand All @@ -94,30 +94,30 @@ def vector():
]
}
],
"findingsNames": [],
"findings_names": [],
"name": "Domain Users can reach baaaaacnet by exploiting CVE-2024-21444 and CVE-2022-26936",
"summary": "An attacker can use Domain Users to access baaaaacnet by exploiting two vulnerabilities. First, the attacker exploits CVE-2024-21444 on APAENG to gain access to APADC. Then, the attacker exploits CVE-2022-26936 on APADC to gain access to baaaaacnet. This attack path is possible because Domain Users is a member of Remote Desktop Users, which has remote desktop access to APAENG. This attack path is dangerous because it allows an attacker to gain access to a critical asset, baaaaacnet, by exploiting two vulnerabilities.",
"firstAES": None,
"lastACR": 9
"first_aes": None,
"last_acr": 9
}


@responses.activate
def test_vectors_list_iterator(api, vector):
responses.get('https://cloud.tenable.com/apa/api/discover/v1/vectors',
json={"pageNumber": 1, "count": 10, "total": 21,
json={"page_number": 1, "count": 10, "total": 21,
"data": [vector for _ in range(10)]},
match=[responses.matchers.query_param_matcher({"limit": 10})])

responses.get('https://cloud.tenable.com/apa/api/discover/v1/vectors',
json={"pageNumber": 2, "count": 10, "total": 21,
json={"page_number": 2, "count": 10, "total": 21,
"data": [vector for _ in range(10)]},
match=[responses.matchers.query_param_matcher({"limit": 10, "pageNumber": 2})])
match=[responses.matchers.query_param_matcher({"limit": 10, "page_number": 2})])

responses.get('https://cloud.tenable.com/apa/api/discover/v1/vectors',
json={"pageNumber": 3, "count": 10, "total": 21,
json={"page_number": 3, "count": 10, "total": 21,
"data": [vector for _ in range(1)]},
match=[responses.matchers.query_param_matcher({"limit": 10, "pageNumber": 3})])
match=[responses.matchers.query_param_matcher({"limit": 10, "page_number": 3})])

vectors: VectorIterator = api.vectors.list()

Expand All @@ -129,7 +129,7 @@ def test_vectors_list_iterator(api, vector):

@responses.activate
def test_vectors_list_vector_page_response(api, vector):
vectors_page_response = {"pageNumber": 1, "count": 10, "total": 10,
vectors_page_response = {"page_number": 1, "count": 10, "total": 10,
"data": [vector for _ in range(10)]}
responses.get('https://cloud.tenable.com/apa/api/discover/v1/vectors',
json=vectors_page_response,
Expand Down