Jira webhook: stop mis-mitigating findings on non-"done" issues#14716
Jira webhook: stop mis-mitigating findings on non-"done" issues#14716mtesauro merged 4 commits intoDefectDojo:devfrom
Conversation
valentijnscholten
left a comment
There was a problem hiding this comment.
This makes sesnse. Can you look at #14611? I think the statusCategory itself could be used to determine the state, even if there is no resolution.
|
@valentijnscholten to fix ruff:
|
There was a problem hiding this comment.
@paulOsinski @Maffooch It's OK, but should this be combined with #14743 in dev to reduce the chances of errors during conflict resolution? The change from resolution to statusCategory is also more than just a bugfix.
|
I'm good with holding it a week to ensure everything rolls out with conflict issue |
Co-authored-by: valentijnscholten <valentijnscholten@gmail.com>
5e3e0c2 to
62cc0fd
Compare
|
Rebased onto Commit history:
|
4a6cbb8 to
62cc0fd
Compare
|
Force push was to drop an unnecessary helm-chart related commit. This PR doesn't affect Helm charts at all and the test is likely failing due to a rebase. |
users see findings auto-mitigated immediately after reopening via
either the UI or API. Looking at finding pghistory we see the pattern:
12:32:48 active=True is_mitigated=False source=None ← user reopens
12:32:51 active=False is_mitigated=True source=jira_webhook ← ricochet
mitigated_byis always the system "JIRA" user, set only from one place:process_resolution_from_jira's "Mitigated by default" branch.Root cause
Two independent issues compound:
Self-inflicted race in
update_jira_issue. When DefectDojopushes an update to a linked Jira issue, it does
issue.update(...)first (priority, description, labels) and thenpush_status_to_jira(...)(the transition). Each API call fires itsown
jira:issue_updatedwebhook. The first webhook, fired byissue.update, sees the pre-transition state - for a reopen, thatmeans the issue is still resolved from the previous close. Our
webhook handler then mitigates the linked finding. The second
webhook, post-transition, would try to reopen the finding, but for
grouped findings that reopen is (deliberately) gated behind
DD_JIRA_WEBHOOK_ALLOW_FINDING_GROUP_REOPEN=False, so the ricochetis irreversible.
Fragile "resolved" check in the webhook handler. The handler
treated any non-null
resolutionas "the Jira issue is closed",which also mis-fires for Jira configurations that set a default
resolution on open issues ("Unresolved"), or workflows whose Reopen
transition does not clear the resolution field.
Fix
update_jira_issueso the status transition runs beforeother field updates. Webhooks fired during our own sync now see a
consistent post-transition state.
process_resolution_from_jira, require bothresolutionANDstatusCategory.key == "done"before mitigating. Extract thestatusCategory from the webhook payload in
webhook()and pass itthrough.
Tests
Three new tests covering status categories
new,indeterminate, anddone, all with a non-null resolution value - regression-locking theguard against the "open but resolved" state.
Backward compatibility
status_category_keyis a keyword-only optional argument onprocess_resolution_from_jira. When not supplied, behavior isidentical to before the change.
resolutiontostatusCategory)issue_from_jira_is_active()on the outbound push sideThe two PRs address mirror-image failure modes of the same underlying problem (resolution is an unreliable signal; statusCategory is canonical):
The two PRs touch disjoint functions in
helper.pyand should merge without conflict in either order. Neither subsumes the other: #14611 alone leaves the webhook ricochet in this PR's summary intact; this PR alone leaves the "Jira hides resolution field" setups in #14347 still broken.