mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
Compare commits
13 Commits
d1d03ba421
...
DEVREL-98-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60350794da | ||
|
|
6a876a3205 | ||
|
|
e9f6bc8604 | ||
|
|
dc71d86c35 | ||
|
|
7a54900a62 | ||
|
|
1d62b8d64e | ||
|
|
0f5dc165bb | ||
|
|
676a11bb13 | ||
|
|
4b80544f0a | ||
|
|
6815a9dd86 | ||
|
|
00441e776d | ||
|
|
4037927c61 | ||
|
|
20337b7e0c |
@@ -14,6 +14,7 @@ All notable changes to the **Prowler API** are documented in this file.
|
||||
- Support muting findings based on simple rules with custom reason [(#9051)](https://github.com/prowler-cloud/prowler/pull/9051)
|
||||
- Support C5 compliance framework for the GCP provider [(#9097)](https://github.com/prowler-cloud/prowler/pull/9097)
|
||||
- Support for Amazon Bedrock and OpenAI compatible providers in Lighthouse AI [(#8957)](https://github.com/prowler-cloud/prowler/pull/8957)
|
||||
- OpenAPI schema integration with Mintlify documentation including compatibility fixes and dynamic server URL configuration [(#9168)](https://github.com/prowler-cloud/prowler/pull/9168)
|
||||
- Tenant-wide ThreatScore overview aggregation and snapshot persistence with backfill support [(#9148)](https://github.com/prowler-cloud/prowler/pull/9148)
|
||||
- Support for MongoDB Atlas provider [(#9167)](https://github.com/prowler-cloud/prowler/pull/9167)
|
||||
|
||||
|
||||
@@ -36,6 +36,143 @@ def _extract_task_example_from_components(components):
|
||||
}
|
||||
|
||||
|
||||
def fix_empty_id_fields(result, generator, request, public): # noqa: F841
|
||||
"""
|
||||
Fix empty id fields in JSON:API request schemas.
|
||||
drf-spectacular-jsonapi sometimes generates empty id field definitions ({})
|
||||
which cause validation errors in Mintlify and other OpenAPI validators.
|
||||
"""
|
||||
if not isinstance(result, dict):
|
||||
return result
|
||||
|
||||
components = result.get("components", {}) or {}
|
||||
schemas = components.get("schemas", {}) or {}
|
||||
|
||||
for schema_name, schema in schemas.items():
|
||||
if not isinstance(schema, dict):
|
||||
continue
|
||||
|
||||
# Check if this is a JSON:API request schema with a data object
|
||||
properties = schema.get("properties", {})
|
||||
if not isinstance(properties, dict):
|
||||
continue
|
||||
|
||||
data_prop = properties.get("data")
|
||||
if not isinstance(data_prop, dict):
|
||||
continue
|
||||
|
||||
data_properties = data_prop.get("properties", {})
|
||||
if not isinstance(data_properties, dict):
|
||||
continue
|
||||
|
||||
# Fix empty id field
|
||||
id_field = data_properties.get("id")
|
||||
if id_field == {} or (isinstance(id_field, dict) and not id_field):
|
||||
data_properties["id"] = {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Unique identifier for this resource object.",
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def convert_pattern_properties_to_additional(obj):
|
||||
"""
|
||||
Recursively convert patternProperties to additionalProperties.
|
||||
OpenAPI 3.0.x doesn't support patternProperties (only available in 3.1+).
|
||||
"""
|
||||
if isinstance(obj, dict):
|
||||
if "patternProperties" in obj:
|
||||
# Get the pattern and its schema
|
||||
pattern_props = obj.pop("patternProperties")
|
||||
# Use the first pattern's schema as additionalProperties
|
||||
if pattern_props:
|
||||
first_pattern_schema = next(iter(pattern_props.values()))
|
||||
obj["additionalProperties"] = first_pattern_schema
|
||||
|
||||
# Recursively process all nested objects
|
||||
for key, value in obj.items():
|
||||
obj[key] = convert_pattern_properties_to_additional(value)
|
||||
elif isinstance(obj, list):
|
||||
return [convert_pattern_properties_to_additional(item) for item in obj]
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
def fix_pattern_properties(result, generator, request, public): # noqa: F841
|
||||
"""
|
||||
Convert patternProperties to additionalProperties for OpenAPI 3.0 compatibility.
|
||||
patternProperties is only supported in OpenAPI 3.1+, but drf-spectacular
|
||||
generates OpenAPI 3.0.x specs.
|
||||
"""
|
||||
if not isinstance(result, dict):
|
||||
return result
|
||||
|
||||
return convert_pattern_properties_to_additional(result)
|
||||
|
||||
|
||||
def fix_invalid_types(obj):
|
||||
"""
|
||||
Recursively fix invalid type values in OpenAPI schemas.
|
||||
Converts invalid types like "email" to proper OpenAPI format.
|
||||
"""
|
||||
if isinstance(obj, dict):
|
||||
# Fix invalid "type" values
|
||||
if "type" in obj:
|
||||
type_value = obj["type"]
|
||||
if type_value == "email":
|
||||
obj["type"] = "string"
|
||||
obj["format"] = "email"
|
||||
elif type_value == "url":
|
||||
obj["type"] = "string"
|
||||
obj["format"] = "uri"
|
||||
elif type_value == "uuid":
|
||||
obj["type"] = "string"
|
||||
obj["format"] = "uuid"
|
||||
|
||||
# Recursively process all nested objects
|
||||
for key, value in list(obj.items()):
|
||||
obj[key] = fix_invalid_types(value)
|
||||
elif isinstance(obj, list):
|
||||
return [fix_invalid_types(item) for item in obj]
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
def fix_type_formats(result, generator, request, public): # noqa: F841
|
||||
"""
|
||||
Fix invalid type values in OpenAPI schemas.
|
||||
drf-spectacular sometimes generates invalid type values like "email"
|
||||
instead of "type": "string" with "format": "email".
|
||||
"""
|
||||
if not isinstance(result, dict):
|
||||
return result
|
||||
|
||||
return fix_invalid_types(result)
|
||||
|
||||
|
||||
def add_api_servers(result, generator, request, public): # noqa: F841
|
||||
"""
|
||||
Add servers configuration to OpenAPI spec for Mintlify API playground.
|
||||
This enables the "Try it out" feature in the documentation.
|
||||
Only adds the production URL to ensure consistent documentation.
|
||||
"""
|
||||
if not isinstance(result, dict):
|
||||
return result
|
||||
|
||||
# Add servers array if not already present
|
||||
if "servers" not in result:
|
||||
result["servers"] = [
|
||||
{
|
||||
"url": "https://api.prowler.com",
|
||||
"description": "Prowler Cloud API",
|
||||
}
|
||||
]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def attach_task_202_examples(result, generator, request, public): # noqa: F841
|
||||
if not isinstance(result, dict):
|
||||
return result
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -125,6 +125,10 @@ SPECTACULAR_SETTINGS = {
|
||||
"drf_spectacular_jsonapi.hooks.fix_nested_path_parameters",
|
||||
],
|
||||
"POSTPROCESSING_HOOKS": [
|
||||
"api.schema_hooks.fix_empty_id_fields",
|
||||
"api.schema_hooks.fix_pattern_properties",
|
||||
"api.schema_hooks.fix_type_formats",
|
||||
"api.schema_hooks.add_api_servers",
|
||||
"api.schema_hooks.attach_task_202_examples",
|
||||
],
|
||||
"TITLE": "API Reference - Prowler",
|
||||
|
||||
18987
docs/api-reference/openapi.yml
Normal file
18987
docs/api-reference/openapi.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -329,6 +329,10 @@
|
||||
{
|
||||
"tab": "Public Roadmap",
|
||||
"href": "https://roadmap.prowler.com/"
|
||||
},
|
||||
{
|
||||
"tab": "API Reference",
|
||||
"openapi": "api-reference/openapi.yml"
|
||||
}
|
||||
],
|
||||
"global": {
|
||||
|
||||
Reference in New Issue
Block a user