mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-05 03:12:14 +00:00
fix(api): address Jira dedup review feedback
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from api.models import Integration, IntegrationProviderRelationship, Provider
|
||||
from api.v1.serializer_utils.base import BaseValidateSerializer
|
||||
@@ -12,6 +13,24 @@ ATLASSIAN_SITE_NAME_REGEX = re.compile(
|
||||
)
|
||||
|
||||
|
||||
def sanitize_integration_task_result(task_name: str | None, result: Any) -> Any:
|
||||
"""Remove private integration metadata from task results."""
|
||||
if task_name != "integration-jira" or not isinstance(result, dict):
|
||||
return result
|
||||
|
||||
skipped = result.get("skipped")
|
||||
if not isinstance(skipped, list):
|
||||
return result
|
||||
|
||||
sanitized_result = result.copy()
|
||||
sanitized_result["skipped"] = [
|
||||
{"finding_id": entry["finding_id"]}
|
||||
for entry in skipped
|
||||
if isinstance(entry, dict) and "finding_id" in entry
|
||||
]
|
||||
return sanitized_result
|
||||
|
||||
|
||||
def replace_integration_providers(
|
||||
integration: Integration, providers: list[Provider], tenant_id: str
|
||||
) -> None:
|
||||
|
||||
@@ -51,6 +51,7 @@ from api.v1.serializer_utils.integrations import (
|
||||
S3ConfigSerializer,
|
||||
SecurityHubConfigSerializer,
|
||||
replace_integration_providers,
|
||||
sanitize_integration_task_result,
|
||||
)
|
||||
from api.v1.serializer_utils.lighthouse import (
|
||||
BedrockCredentialsSerializer,
|
||||
@@ -639,19 +640,8 @@ class TaskSerializer(RLSSerializer, TaskBase):
|
||||
@extend_schema_field(serializers.JSONField())
|
||||
def get_result(self, obj):
|
||||
result = self.get_json_field(obj, "result")
|
||||
if (
|
||||
isinstance(result, dict)
|
||||
and obj.task_runner_task
|
||||
and obj.task_runner_task.task_name == "integration-jira"
|
||||
):
|
||||
skipped = result.get("skipped")
|
||||
if isinstance(skipped, list):
|
||||
result["skipped"] = [
|
||||
{"finding_id": entry["finding_id"]}
|
||||
for entry in skipped
|
||||
if isinstance(entry, dict) and "finding_id" in entry
|
||||
]
|
||||
return result
|
||||
task_name = obj.task_runner_task.task_name if obj.task_runner_task else None
|
||||
return sanitize_integration_task_result(task_name, result)
|
||||
|
||||
@extend_schema_field(serializers.JSONField())
|
||||
def get_task_args(self, obj):
|
||||
|
||||
@@ -1690,6 +1690,7 @@ class TestJiraIntegration:
|
||||
_refresh_jira_issue_statuses=MagicMock(return_value={}),
|
||||
_reserve_initial_jira_issue=MagicMock(return_value=reservation),
|
||||
_reserve_jira_issue_replacement=MagicMock(return_value=reservation),
|
||||
_start_jira_delivery_attempt=MagicMock(return_value=True),
|
||||
_link_jira_issue=MagicMock(return_value=True),
|
||||
_release_jira_delivery_attempt=MagicMock(return_value=True),
|
||||
):
|
||||
|
||||
@@ -147,7 +147,7 @@ Prowler remembers each confirmed Jira issue created for a Finding, keyed by the
|
||||
* If the linked issue has a Jira status in the **Done** category, Prowler creates a replacement and links the Finding to the new issue after Jira confirms it.
|
||||
* If Jira reports that the issue is missing or forbidden, or its status cannot be determined safely, Prowler keeps the existing link and skips the Finding.
|
||||
|
||||
The link, and the last status observed in Jira, are available through the API at `GET /api/v1/jira-issues` (filter by `finding_uid`, `finding_uid__in`, `provider_id`, `integration` or `issue_key`). Each Jira integration keeps its own links, so the same Finding can have one issue per integration.
|
||||
The link, and the last status observed in Jira, are available through the API at `GET /api/v1/jira-issues` (filter by `finding_uid`, `finding_uid__in`, `provider_id`, `integration`, `issue_key`, `issue_status_category` or `issue_status_category__in`). Each Jira integration keeps its own links, so the same Finding can have one issue per integration.
|
||||
|
||||
Prowler uses a private delivery marker to check whether Jira created an issue when a delivery result is uncertain. A reservation that stopped before the delivery attempt began can be resumed safely by a later explicit send. After an attempt starts, Prowler searches Jira by the marker: exactly one matching issue completes the link, while no match, multiple matches, or a lookup error keeps the reservation and prevents an automatic retry. A process failure after the attempt starts but before Jira receives the request can still require manual investigation because Prowler cannot prove whether Jira accepted the request.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user