mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-04-14 08:28:16 +00:00
feat(api): add provider_id__in filter for ScanSummary queries (#8951)
This commit is contained in:
committed by
GitHub
parent
c4a0da8204
commit
524209bdf2
@@ -14,6 +14,7 @@ All notable changes to the **Prowler API** are documented in this file.
|
||||
- Support for `passed_findings` and `total_findings` fields in compliance requirement overview for accurate Prowler ThreatScore calculation [(#8582)](https://github.com/prowler-cloud/prowler/pull/8582)
|
||||
- Database read replica support [(#8869)](https://github.com/prowler-cloud/prowler/pull/8869)
|
||||
- Support Common Cloud Controls for AWS, Azure and GCP [(#8000)](https://github.com/prowler-cloud/prowler/pull/8000)
|
||||
- Add `provider_id__in` filter support to findings and findings severity overview endpoints [(#8951)](https://github.com/prowler-cloud/prowler/pull/8951)
|
||||
|
||||
### Changed
|
||||
- Now the MANAGE_ACCOUNT permission is required to modify or read user permissions instead of MANAGE_USERS [(#8281)](https://github.com/prowler-cloud/prowler/pull/8281)
|
||||
|
||||
@@ -765,6 +765,7 @@ class ComplianceOverviewFilter(FilterSet):
|
||||
class ScanSummaryFilter(FilterSet):
|
||||
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
|
||||
provider_id = UUIDFilter(field_name="scan__provider__id", lookup_expr="exact")
|
||||
provider_id__in = UUIDInFilter(field_name="scan__provider__id", lookup_expr="in")
|
||||
provider_type = ChoiceFilter(
|
||||
field_name="scan__provider__provider", choices=Provider.ProviderChoices.choices
|
||||
)
|
||||
|
||||
@@ -3611,6 +3611,16 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: filter[provider_id__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[provider_type]
|
||||
schema:
|
||||
@@ -3778,6 +3788,16 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: filter[provider_id__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[provider_type]
|
||||
schema:
|
||||
@@ -3980,6 +4000,16 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: filter[provider_id__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[provider_type]
|
||||
schema:
|
||||
|
||||
@@ -46,6 +46,7 @@ from api.models import (
|
||||
SAMLConfiguration,
|
||||
SAMLToken,
|
||||
Scan,
|
||||
ScanSummary,
|
||||
StateChoices,
|
||||
Task,
|
||||
TenantAPIKey,
|
||||
@@ -5766,6 +5767,171 @@ class TestOverviewViewSet:
|
||||
assert service1_data["attributes"]["muted"] == 1
|
||||
assert service2_data["attributes"]["muted"] == 0
|
||||
|
||||
def test_overview_findings_provider_id_in_filter(
|
||||
self, authenticated_client, tenants_fixture, providers_fixture
|
||||
):
|
||||
tenant = tenants_fixture[0]
|
||||
provider1, provider2, *_ = providers_fixture
|
||||
|
||||
scan1 = Scan.objects.create(
|
||||
name="scan-one",
|
||||
provider=provider1,
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
tenant=tenant,
|
||||
)
|
||||
scan2 = Scan.objects.create(
|
||||
name="scan-two",
|
||||
provider=provider2,
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
tenant=tenant,
|
||||
)
|
||||
|
||||
ScanSummary.objects.create(
|
||||
tenant=tenant,
|
||||
scan=scan1,
|
||||
check_id="check-provider-one",
|
||||
service="service-a",
|
||||
severity="high",
|
||||
region="region-a",
|
||||
_pass=5,
|
||||
fail=1,
|
||||
muted=2,
|
||||
total=8,
|
||||
new=5,
|
||||
changed=2,
|
||||
unchanged=1,
|
||||
fail_new=1,
|
||||
fail_changed=0,
|
||||
pass_new=3,
|
||||
pass_changed=2,
|
||||
muted_new=1,
|
||||
muted_changed=1,
|
||||
)
|
||||
|
||||
ScanSummary.objects.create(
|
||||
tenant=tenant,
|
||||
scan=scan2,
|
||||
check_id="check-provider-two",
|
||||
service="service-b",
|
||||
severity="medium",
|
||||
region="region-b",
|
||||
_pass=2,
|
||||
fail=3,
|
||||
muted=1,
|
||||
total=6,
|
||||
new=3,
|
||||
changed=2,
|
||||
unchanged=1,
|
||||
fail_new=2,
|
||||
fail_changed=1,
|
||||
pass_new=1,
|
||||
pass_changed=1,
|
||||
muted_new=1,
|
||||
muted_changed=0,
|
||||
)
|
||||
|
||||
single_response = authenticated_client.get(
|
||||
reverse("overview-findings"),
|
||||
{"filter[provider_id__in]": str(provider1.id)},
|
||||
)
|
||||
assert single_response.status_code == status.HTTP_200_OK
|
||||
single_attributes = single_response.json()["data"]["attributes"]
|
||||
assert single_attributes["pass"] == 5
|
||||
assert single_attributes["fail"] == 1
|
||||
assert single_attributes["muted"] == 2
|
||||
assert single_attributes["total"] == 8
|
||||
|
||||
combined_response = authenticated_client.get(
|
||||
reverse("overview-findings"),
|
||||
{"filter[provider_id__in]": f"{provider1.id},{provider2.id}"},
|
||||
)
|
||||
assert combined_response.status_code == status.HTTP_200_OK
|
||||
combined_attributes = combined_response.json()["data"]["attributes"]
|
||||
assert combined_attributes["pass"] == 7
|
||||
assert combined_attributes["fail"] == 4
|
||||
assert combined_attributes["muted"] == 3
|
||||
assert combined_attributes["total"] == 14
|
||||
|
||||
def test_overview_findings_severity_provider_id_in_filter(
|
||||
self, authenticated_client, tenants_fixture, providers_fixture
|
||||
):
|
||||
tenant = tenants_fixture[0]
|
||||
provider1, provider2, *_ = providers_fixture
|
||||
|
||||
scan1 = Scan.objects.create(
|
||||
name="severity-scan-one",
|
||||
provider=provider1,
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
tenant=tenant,
|
||||
)
|
||||
scan2 = Scan.objects.create(
|
||||
name="severity-scan-two",
|
||||
provider=provider2,
|
||||
trigger=Scan.TriggerChoices.MANUAL,
|
||||
state=StateChoices.COMPLETED,
|
||||
tenant=tenant,
|
||||
)
|
||||
|
||||
ScanSummary.objects.create(
|
||||
tenant=tenant,
|
||||
scan=scan1,
|
||||
check_id="severity-check-one",
|
||||
service="service-a",
|
||||
severity="high",
|
||||
region="region-a",
|
||||
_pass=4,
|
||||
fail=4,
|
||||
muted=0,
|
||||
total=8,
|
||||
)
|
||||
ScanSummary.objects.create(
|
||||
tenant=tenant,
|
||||
scan=scan1,
|
||||
check_id="severity-check-two",
|
||||
service="service-a",
|
||||
severity="medium",
|
||||
region="region-b",
|
||||
_pass=2,
|
||||
fail=2,
|
||||
muted=0,
|
||||
total=4,
|
||||
)
|
||||
ScanSummary.objects.create(
|
||||
tenant=tenant,
|
||||
scan=scan2,
|
||||
check_id="severity-check-three",
|
||||
service="service-b",
|
||||
severity="critical",
|
||||
region="region-c",
|
||||
_pass=1,
|
||||
fail=2,
|
||||
muted=0,
|
||||
total=3,
|
||||
)
|
||||
|
||||
single_response = authenticated_client.get(
|
||||
reverse("overview-findings_severity"),
|
||||
{"filter[provider_id__in]": str(provider1.id)},
|
||||
)
|
||||
assert single_response.status_code == status.HTTP_200_OK
|
||||
single_attributes = single_response.json()["data"]["attributes"]
|
||||
assert single_attributes["high"] == 8
|
||||
assert single_attributes["medium"] == 4
|
||||
assert single_attributes["critical"] == 0
|
||||
|
||||
combined_response = authenticated_client.get(
|
||||
reverse("overview-findings_severity"),
|
||||
{"filter[provider_id__in]": f"{provider1.id},{provider2.id}"},
|
||||
)
|
||||
assert combined_response.status_code == status.HTTP_200_OK
|
||||
combined_attributes = combined_response.json()["data"]["attributes"]
|
||||
assert combined_attributes["high"] == 8
|
||||
assert combined_attributes["medium"] == 4
|
||||
assert combined_attributes["critical"] == 3
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestScheduleViewSet:
|
||||
|
||||
Reference in New Issue
Block a user