Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions gvm/protocols/gmp/_gmpnext.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
ReportPorts,
ReportTlsCertificates,
ReportVulnerabilities,
ScanReports,
Targets,
Tasks,
WebApplicationTargets,
Expand Down Expand Up @@ -1642,3 +1643,31 @@ def get_targets(
tasks=tasks,
)
)

def get_scan_report(
self,
scan_report_id: EntityID,
*,
filter_string: str | None = None,
filter_id: str | None = None,
) -> T:
""" "Request a structured summary of a single scan report.

Args:
scan_report_id: UUID of an existing scan report.
filter_string: Filter term to apply to the report results.
filter_id: UUID of a saved filter to apply to the report results.

Returns:
A request for the get_scan_report GMP command.

Raises:
RequiredArgument: If scan_report_id is not provided.
"""
return self._send_request_and_transform_response(
ScanReports.get_scan_report(
scan_report_id=scan_report_id,
filter_string=filter_string,
filter_id=filter_id,
)
)
2 changes: 2 additions & 0 deletions gvm/protocols/gmp/requests/next/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from gvm.protocols.gmp.requests.next._report_vulnerabilities import (
ReportVulnerabilities,
)
from gvm.protocols.gmp.requests.next._scan_report import ScanReports
from gvm.protocols.gmp.requests.next._targets import AliveTest, Targets
from gvm.protocols.gmp.requests.next._tasks import Tasks
from gvm.protocols.gmp.requests.next._web_application_targets import (
Expand Down Expand Up @@ -184,6 +185,7 @@
"Results",
"Roles",
"ScanConfigs",
"ScanReports",
"ScannerType",
"Scanners",
"Schedules",
Expand Down
39 changes: 39 additions & 0 deletions gvm/protocols/gmp/requests/next/_scan_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from gvm.errors import RequiredArgument
from gvm.protocols.core import Request
from gvm.protocols.gmp.requests import EntityID
from gvm.xml import XmlCommand


class ScanReports:
@classmethod
def get_scan_report(
cls,
scan_report_id: EntityID,
*,
filter_string: str | None = None,
filter_id: str | None = None,
) -> Request:
"""Request a structured summary of a single scan report.

Args:
scan_report_id: UUID of an existing scan report.
filter_string: Filter term to apply to the report results.
filter_id: UUID of a saved filter to apply to the report results.

Returns:
A request for the get_scan_report GMP command.

Raises:
RequiredArgument: If scan_report_id is not provided.
"""
if not scan_report_id:
raise RequiredArgument(
function=cls.get_scan_report.__name__,
argument="scan_report_id",
)

cmd = XmlCommand("get_scan_report")
cmd.set_attribute("scan_report_id", str(scan_report_id))
cmd.add_filter(filter_string, filter_id)

return cmd
10 changes: 10 additions & 0 deletions tests/protocols/gmpnext/entities/scan_reports/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from .test_get_scan_report import (
GmpGetScanReportTestMixin,
)

__all__ = ("GmpGetScanReportTestMixin",)
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from gvm.errors import RequiredArgument


class GmpGetScanReportTestMixin:
def test_get_scan_report_without_id(self):
with self.assertRaises(RequiredArgument):
self.gmp.get_scan_report(None)

with self.assertRaises(RequiredArgument):
self.gmp.get_scan_report("")

def test_get_scan_report_with_id(self):
self.gmp.get_scan_report(scan_report_id="r1")

self.connection.send.has_been_called_with(
b'<get_scan_report scan_report_id="r1"/>'
)

def test_get_scan_report_with_filter_string(self):
self.gmp.get_scan_report(
scan_report_id="r1",
filter_string="name=foo",
)

self.connection.send.has_been_called_with(
b'<get_scan_report scan_report_id="r1" filter="name=foo"/>'
)

def test_get_scan_report_with_filter_id(self):
self.gmp.get_scan_report(
scan_report_id="r1",
filter_id="f1",
)

self.connection.send.has_been_called_with(
b'<get_scan_report scan_report_id="r1" filt_id="f1"/>'
)

def test_get_scan_report_with_filter_string_and_filter_id(self):
self.gmp.get_scan_report(
scan_report_id="r1",
filter_string="name=foo",
filter_id="f1",
)

self.connection.send.has_been_called_with(
b'<get_scan_report scan_report_id="r1" '
b'filter="name=foo" filt_id="f1"/>'
)
13 changes: 13 additions & 0 deletions tests/protocols/gmpnext/entities/test_scan_reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2026 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
#

from ...gmpnext import GMPTestCase
from .scan_reports.test_get_scan_report import (
GmpGetScanReportTestMixin,
)


class GmpGetScanReportTestCase(GmpGetScanReportTestMixin, GMPTestCase):
pass
Loading