mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
fix(sdk): exclude sdk_only providers from scan config schema
- Filter _build_aggregated_schema by Provider.get_app_providers - Keep provider schemas in SCHEMAS for CLI config.yaml validation - Cover the app-facing schema with tests
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Scan configuration schema no longer exposes SDK/CLI-only providers such as `e2enetworks`; the aggregated schema served by `/scan-configurations/schema` now includes only app providers (`sdk_only = False`)
|
||||
@@ -225,9 +225,20 @@ def _build_aggregated_schema() -> dict:
|
||||
|
||||
The output mirrors the layout of `prowler/config/config.yaml` (a mapping
|
||||
keyed by provider type) and is what the UI consumes via `ajv`.
|
||||
|
||||
Only app-facing providers (`sdk_only = False`, see
|
||||
`Provider.get_app_providers`) are included. SDK/CLI-only providers may
|
||||
still have a schema registered in `SCHEMAS` so the CLI validates their
|
||||
`config.yaml` (`load_and_validate_config_file` reads `SCHEMAS.get`), but
|
||||
they must not surface in this app-facing schema.
|
||||
"""
|
||||
from prowler.providers.common.provider import Provider
|
||||
|
||||
app_providers = set(Provider.get_app_providers())
|
||||
properties: dict[str, dict] = {}
|
||||
for provider, schema_cls in SCHEMAS.items():
|
||||
if provider not in app_providers:
|
||||
continue
|
||||
properties[provider] = schema_cls.model_json_schema()
|
||||
return {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
|
||||
@@ -20,7 +20,10 @@ EXCLUSION_FIELDS = ("excluded_checks", "excluded_services")
|
||||
|
||||
|
||||
class Test_JSON_Schema_Exposes_Exclusion_Fields:
|
||||
@pytest.mark.parametrize("provider", sorted(SCHEMAS))
|
||||
# The aggregated schema is app-facing and only carries app providers
|
||||
# (``sdk_only = False``); iterate exactly what it exposes so SDK/CLI-only
|
||||
# providers (still in ``SCHEMAS`` for CLI validation) are not asserted here.
|
||||
@pytest.mark.parametrize("provider", sorted(SCAN_CONFIG_SCHEMA["properties"]))
|
||||
@pytest.mark.parametrize("field", EXCLUSION_FIELDS)
|
||||
def test_field_shape(self, provider, field):
|
||||
field_schema = SCAN_CONFIG_SCHEMA["properties"][provider]["properties"][field]
|
||||
|
||||
@@ -13,11 +13,15 @@ from unittest.mock import call, patch
|
||||
import pytest
|
||||
|
||||
from prowler.config.scan_config_schema import (
|
||||
SCAN_CONFIG_SCHEMA,
|
||||
_build_aggregated_schema,
|
||||
_get_provider_check_ids,
|
||||
_get_provider_services,
|
||||
validate_and_normalize_scan_config,
|
||||
validate_scan_config,
|
||||
)
|
||||
from prowler.config.schema.registry import SCHEMAS
|
||||
from prowler.providers.common.provider import Provider
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -391,3 +395,38 @@ class Test_Backward_Compatible_Wrapper:
|
||||
"message": "Scan config must be a mapping with provider sections.",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class Test_Aggregated_Schema_Is_App_Facing:
|
||||
"""``SCAN_CONFIG_SCHEMA`` is served by the app
|
||||
(``/scan-configurations/schema``) and consumed by the UI editor, so it must
|
||||
expose only app providers (``sdk_only = False``). SDK/CLI-only providers
|
||||
must not leak into it, even when they have a config schema registered in
|
||||
``SCHEMAS`` for CLI ``config.yaml`` validation."""
|
||||
|
||||
def test_sdk_only_provider_is_absent_from_schema(self):
|
||||
# ``e2enetworks`` is ``sdk_only = True`` yet has a schema registered in
|
||||
# ``SCHEMAS``; it must not surface in the app-facing aggregated schema.
|
||||
assert "e2enetworks" not in SCAN_CONFIG_SCHEMA["properties"]
|
||||
|
||||
def test_schema_contains_only_app_providers(self):
|
||||
app_providers = set(Provider.get_app_providers())
|
||||
assert set(SCAN_CONFIG_SCHEMA["properties"]).issubset(app_providers)
|
||||
|
||||
def test_app_provider_with_registered_schema_is_present(self):
|
||||
assert "aws" in SCAN_CONFIG_SCHEMA["properties"]
|
||||
|
||||
def test_registry_still_registers_sdk_only_provider_for_cli(self):
|
||||
# Guard against "fixing" the leak by dropping ``e2enetworks`` from
|
||||
# ``SCHEMAS``: ``load_and_validate_config_file()`` relies on
|
||||
# ``SCHEMAS.get(provider)`` and a missing schema silently disables
|
||||
# ``config.yaml`` validation for that provider on the CLI.
|
||||
assert "e2enetworks" in SCHEMAS
|
||||
|
||||
def test_build_filters_registry_by_app_providers(self):
|
||||
# Deterministic mechanism check: only providers returned by
|
||||
# ``get_app_providers()`` survive the aggregation, regardless of what
|
||||
# ``SCHEMAS`` contains.
|
||||
with patch.object(Provider, "get_app_providers", return_value=["aws"]):
|
||||
schema = _build_aggregated_schema()
|
||||
assert set(schema["properties"]) == {"aws"}
|
||||
|
||||
Reference in New Issue
Block a user