feat(api): add provider group filters#11573
Conversation
- Add provider group filters alongside provider type filters - Support exact and comma-separated provider group filtering - Cover provider group filtering across API views and overviews
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR extends the Prowler API to support filtering by provider groups across multiple endpoints. FilterSet classes are updated with ChangesProvider Group Filtering Support
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
✅ Conflict Markers Resolved All conflict markers have been successfully resolved in this pull request. |
|
✅ All necessary |
🔒 Container Security ScanImage: ✅ No Vulnerabilities DetectedThe container image passed all security checks. No known CVEs were found.📋 Resources:
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
api/src/backend/api/tests/test_views.py (1)
1414-18238:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRun ruff formatter to fix code style.
The pipeline indicates this file needs reformatting.
Run the following command to fix:
uv run ruff format src/backend/api/tests/test_views.py🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/src/backend/api/tests/test_views.py` around lines 1414 - 18238, Summary: The test file src/backend/api/tests/test_views.py is not formatted to project style (ruff) causing CI failures. Fix: run the project formatter (ruff) over the file and commit the changes; e.g. execute the ruff format command the reviewer suggested to automatically reformat the whole file including tests like test_providers_filter_provider_groups, TestProviderGroupViewSet, and other test_* functions; verify no functional changes and then add/commit the formatted file and push. Ensure you run the same command in CI/pre-commit locally (uv run ruff format src/backend/api/tests/test_views.py) so lint/format passes.Source: Pipeline failures
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@api/src/backend/api/tests/test_views.py`:
- Around line 1414-18238: Summary: The test file
src/backend/api/tests/test_views.py is not formatted to project style (ruff)
causing CI failures. Fix: run the project formatter (ruff) over the file and
commit the changes; e.g. execute the ruff format command the reviewer suggested
to automatically reformat the whole file including tests like
test_providers_filter_provider_groups, TestProviderGroupViewSet, and other
test_* functions; verify no functional changes and then add/commit the formatted
file and push. Ensure you run the same command in CI/pre-commit locally (uv run
ruff format src/backend/api/tests/test_views.py) so lint/format passes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 43caf620-81dd-49e3-a170-f580de34e505
📒 Files selected for processing (4)
api/CHANGELOG.mdapi/src/backend/api/filters.pyapi/src/backend/api/tests/test_views.pyapi/src/backend/api/v1/views.py
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #11573 +/- ##
==========================================
+ Coverage 94.02% 94.11% +0.08%
==========================================
Files 241 247 +6
Lines 35705 36352 +647
==========================================
+ Hits 33573 34212 +639
- Misses 2132 2140 +8
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
24232e7
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
api/src/backend/api/v1/views.py (1)
5857-5866:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDocument provider-group filters with JSON:API parameter names.
These new filters are exposed as top-level
provider_groupsparams in the schema. Document the canonical JSON:API shape so generated clients sendfilter[provider_groups]/filter[provider_groups__in].📝 Proposed schema fix
OpenApiParameter( - name="provider_groups", + name="filter[provider_groups]", type=OpenApiTypes.UUID, location=OpenApiParameter.QUERY, description="Filter by provider group ID", ), OpenApiParameter( - name="provider_groups__in", + name="filter[provider_groups__in]", type=OpenApiTypes.STR, location=OpenApiParameter.QUERY, description="Filter by multiple provider group IDs (comma-separated UUIDs)", ),As per coding guidelines, "Use JSON:API filtering with
?filter[field]=valueand?filter[field__in]=val1,val2query parameters."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/src/backend/api/v1/views.py` around lines 5857 - 5866, The descriptions for the OpenApiParameter definitions named "provider_groups" and "provider_groups__in" do not document the canonical JSON:API query parameter format that clients should use. Update the description fields for both parameters to explicitly document the JSON:API filter syntax: clarify that "provider_groups" should be sent as `filter[provider_groups]=value` and "provider_groups__in" should be sent as `filter[provider_groups__in]=value1,value2` so that generated clients follow the JSON:API filtering convention.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/src/backend/api/tests/test_views.py`:
- Line 9777: Remove the redundant invariant assertion checks that verify
test-setup constraints rather than API behavior. In the test code at line 9777,
remove the assertion that verifies latest_scan1.provider_id == provider1.id, and
at line 9787, remove the corresponding assertion that verifies
latest_scan2.provider_id == provider2.id. These checks are redundant because the
subsequent assertions validating the requirements_passed and requirements_failed
counts are sufficient to validate the filter logic and expected API behavior,
while the provider_id assertions merely confirm that the test fixtures were set
up correctly.
- Around line 9448-9462: The failed_checks assignment in the _create_requirement
helper currently only excludes StatusChoices.PASS from setting failed_checks=1,
but production code and existing test fixtures show that StatusChoices.MANUAL
requirements should also have failed_checks=0. Update the condition on the
failed_checks line to include both StatusChoices.PASS and StatusChoices.MANUAL
in the tuple check: change from `failed_checks=0 if status_choice ==
StatusChoices.PASS else 1` to `failed_checks=0 if status_choice in
(StatusChoices.PASS, StatusChoices.MANUAL) else 1` to ensure consistency between
MANUAL and PASS requirement handling.
In `@api/src/backend/api/v1/views.py`:
- Around line 4813-4822: The method _filtered_queryset_for_latest_provider_scans
and the related code paths at lines 4979-4990, 5035-5050, and 5065-5150 retrieve
the latest scan IDs via _latest_scan_ids_for_provider_filters() but then discard
them and fall through to _task_response_if_running(None), which cannot check
individual scans for in-progress status. Preserve the latest_scan_ids obtained
from _latest_scan_ids_for_provider_filters() and before returning empty
compliance data, check _task_response_if_running() for each of the selected scan
IDs to detect and preserve in-progress compliance responses rather than
returning an empty 200 response. Apply this same pattern across all affected
locations so that provider-filtered latest scans properly check for running
tasks before returning empty results.
---
Outside diff comments:
In `@api/src/backend/api/v1/views.py`:
- Around line 5857-5866: The descriptions for the OpenApiParameter definitions
named "provider_groups" and "provider_groups__in" do not document the canonical
JSON:API query parameter format that clients should use. Update the description
fields for both parameters to explicitly document the JSON:API filter syntax:
clarify that "provider_groups" should be sent as `filter[provider_groups]=value`
and "provider_groups__in" should be sent as
`filter[provider_groups__in]=value1,value2` so that generated clients follow the
JSON:API filtering convention.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 459ef478-a216-452f-a824-c7c1d04d52d9
📒 Files selected for processing (5)
api/CHANGELOG.mdapi/src/backend/api/filters.pyapi/src/backend/api/tests/test_views.pyapi/src/backend/api/v1/mixins.pyapi/src/backend/api/v1/views.py
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
api/src/backend/api/v1/views.py (1)
5672-5685:⚠️ Potential issue | 🟠 Major | ⚡ Quick winInitialize provider RBAC scope before counting providers.
This action never calls
get_queryset()or_get_provider_filter(), soallowed_providersis unset on a fresh request and limited-visibility users can receive tenant-wide provider counts. Scope theProviderquery through the same RBAC helper used by the other overview actions.Suggested fix
def providers_count(self, request): tenant_id = self.request.tenant_id providers_qs = Provider.objects.filter(tenant_id=tenant_id) - if hasattr(self, "allowed_providers"): - allowed_ids = list(self.allowed_providers.values_list("id", flat=True)) - if not allowed_ids: - overview = [] - return Response( - self.get_serializer(overview, many=True).data, - status=status.HTTP_200_OK, - ) - providers_qs = providers_qs.filter(id__in=allowed_ids) + self._ensure_allowed_providers() + if hasattr(self, "allowed_providers"): + providers_qs = providers_qs.filter( + id__in=self.allowed_providers.values("id") + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/src/backend/api/v1/views.py` around lines 5672 - 5685, The providers_count method checks for the allowed_providers attribute without first initializing it through proper RBAC scoping, which allows limited-visibility users to see tenant-wide provider counts. Before checking for allowed_providers in the method, call the same RBAC helper method (either get_queryset() or _get_provider_filter()) that other overview actions use to properly initialize the provider filter scope based on the user's permissions, ensuring the Provider queryset is scoped through RBAC before counting.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/src/backend/api/tests/test_views.py`:
- Around line 9792-9893: The file api/src/backend/api/tests/test_views.py fails
the ruff format check, meaning the code does not conform to the project's
formatting standards. Run the repository's formatting command (typically `ruff
format api/src/backend/api/tests/test_views.py` or your project's equivalent
formatting tool) to automatically reformat the entire file according to the
configured style rules, then commit the reformatted result. This will resolve
the code-quality check failure.
In `@api/src/backend/api/v1/views.py`:
- Around line 4947-4970: The method `_latest_provider_scan_ids_without_data`
currently uses a queryset that already includes user filters like region or
compliance_id to determine if a scan has data. This causes scans to be
incorrectly marked as "without data" when filters legitimately exclude their
rows, leading to wrong 202/500 responses instead of 200. Create a separate
data-presence queryset scoped only by tenant/RBAC and latest_scan_ids (excluding
user filters) and pass this to `_latest_provider_scan_ids_without_data` instead
of the filtered queryset. Keep the original filtered queryset in
`_task_response_for_latest_provider_scans_without_data` for response aggregation
only.
---
Outside diff comments:
In `@api/src/backend/api/v1/views.py`:
- Around line 5672-5685: The providers_count method checks for the
allowed_providers attribute without first initializing it through proper RBAC
scoping, which allows limited-visibility users to see tenant-wide provider
counts. Before checking for allowed_providers in the method, call the same RBAC
helper method (either get_queryset() or _get_provider_filter()) that other
overview actions use to properly initialize the provider filter scope based on
the user's permissions, ensuring the Provider queryset is scoped through RBAC
before counting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 91a95881-c58b-4e7b-9c64-69048a5c021e
📒 Files selected for processing (3)
api/CHANGELOG.mdapi/src/backend/api/tests/test_views.pyapi/src/backend/api/v1/views.py
- Scope provider counts through RBAC visibility - Check compliance data presence without response filters - Add regression coverage for provider-filtered overview cases
Context
Provider group filtering should be available wherever API consumers can already filter cloud-scoped data by provider type, so provider group based workflows can query the same API surfaces without expanding groups client-side.
Description
This PR adds
provider_groupsandprovider_groups__infilters across the API filtersets and overview paths that already support cloud provider filtering.The change covers exact provider group matching, comma-separated
__inmatching, distinct result handling for providers that belong to multiple groups, and OpenAPI filter documentation for the affected routes. Lighthouse endpoints are intentionally excluded because theirprovider_typeparameter refers to LLM providers such asopenaiandbedrock, not Prowler cloud providers.The API changelog includes the new provider group filters entry for this PR.
Steps to review
api/src/backend/api/filters.pyand confirmprovider_groups/provider_groups__inare added alongside cloud provider type filters.api/src/backend/api/v1/views.pyand confirm overview/manual filter handling includes provider groups, includingoverviews/threatscorequery parameters.api/src/backend/api/tests/test_views.pyfor exact and__incoverage across providers, scans, resources, findings, finding groups, and overviews.uv run pytest src/backend/api/tests/test_views.py -k provider_groups -qfromapi/.uv run ruff check src/backend/api/filters.py src/backend/api/tests/test_views.py src/backend/api/v1/views.pyfromapi/.local_scripts/provider_groups_filter_e2e.pyagainst the dev API to recreate provider groups and compare provider group filters against equivalent provider ID filters.Checklist
Community Checklist
SDK/CLI
UI
API
License
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Summary by CodeRabbit
Release Notes
New Features
filter[provider_groups]) and multi-value (filter[provider_groups__in]), aggregating using the latest completed scans per matching provider.Documentation
list,metadata, andrequirements.filter[scan_id].Tests