fix(api): address Jira dedup review feedback

This commit is contained in:
Josema Camacho
2026-09-02 14:02:30 +02:00
committed by GitHub
parent ba0d1d42cd
commit 743a63b64e
4 changed files with 24 additions and 14 deletions
@@ -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:
+3 -13
View File
@@ -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.