Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update JIRA for Finding Group When Risk Acceptance Expires #11401

Merged
merged 9 commits into from
Jan 2, 2025
20 changes: 1 addition & 19 deletions dojo/finding/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1438,25 +1438,7 @@ def reopen_finding(request, fid):
status.save()
# Clear the risk acceptance, if present
ra_helper.risk_unaccept(request.user, finding)

# Manage the jira status changes
push_to_jira = False
# Determine if the finding is in a group. if so, not push to jira
finding_in_group = finding.has_finding_group
# Check if there is a jira issue that needs to be updated
jira_issue_exists = finding.has_jira_issue or (finding.finding_group and finding.finding_group.has_jira_issue)
# Only push if the finding is not in a group
if jira_issue_exists:
# Determine if any automatic sync should occur
push_to_jira = jira_helper.is_push_all_issues(finding) \
or jira_helper.get_jira_instance(finding).finding_jira_sync
# Save the finding
finding.save(push_to_jira=(push_to_jira and not finding_in_group))

# we only push the group after saving the finding to make sure
# the updated data of the finding is pushed as part of the group
if push_to_jira and finding_in_group:
jira_helper.push_to_jira(finding.finding_group)
ra_helper.update_risk_acceptance_jira(finding)

reopen_external_issue(finding, "re-opened by defectdojo", "github")

Expand Down
66 changes: 47 additions & 19 deletions dojo/risk_acceptance/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,19 @@ def expire_now(risk_acceptance):
reactivated_findings = []
if risk_acceptance.reactivate_expired:
for finding in risk_acceptance.accepted_findings.all():
if not finding.active:
logger.debug("%i:%s: unaccepting a.k.a reactivating finding.", finding.id, finding)
finding.active = True
finding.risk_accepted = False
if not finding.active: # not sure why this is important
logger.debug("%i:%s: unaccepting/reactivating finding.", finding.id, finding)

# Update any endpoint statuses on each of the findings
update_endpoint_statuses(finding, accept_risk=False)

if risk_acceptance.restart_sla_expired:
finding.sla_start_date = timezone.now().date()

finding.save(dedupe_option=False)
risk_unaccept(None, finding, post_comments=False) # comments will be posted at end
reactivated_findings.append(finding)
# findings remain in this risk acceptance for reporting / metrics purposes
else:
logger.debug("%i:%s already active, no changes made.", finding.id, finding)

# best effort JIRA integration, no status changes
post_jira_comments(risk_acceptance, risk_acceptance.accepted_findings.all(), expiration_message_creator)

risk_acceptance.expiration_date = timezone.now()
Expand Down Expand Up @@ -189,7 +185,7 @@ def expiration_handler(*args, **kwargs):
product=risk_acceptance.engagement.product,
url=reverse("view_risk_acceptance", args=(risk_acceptance.engagement.id, risk_acceptance.id)))

post_jira_comments(risk_acceptance, expiration_warning_message_creator, heads_up_days)
post_jira_comments(risk_acceptance, risk_acceptance.accepted_findings.all(), expiration_warning_message_creator, heads_up_days)

risk_acceptance.expiration_date_warned = timezone.now()
risk_acceptance.save()
Expand Down Expand Up @@ -243,20 +239,22 @@ def unaccepted_message_creator(risk_acceptance, heads_up_days=0):


def post_jira_comment(finding, message_factory, heads_up_days=0):
if not finding or not finding.has_jira_issue:
if not finding or (not finding.has_jira_issue and not finding.has_jira_group_issue):
return

jira_project = jira_helper.get_jira_project(finding)

if jira_project and jira_project.risk_acceptance_expiration_notification:
jira_instance = jira_helper.get_jira_instance(finding)

if jira_instance:

jira_comment = message_factory(None, heads_up_days)

logger.debug("Creating JIRA comment for something risk acceptance related")
jira_helper.add_simple_jira_comment(jira_instance, finding.jira_issue, jira_comment)
jira_issue = None
if finding.has_jira_issue:
jira_issue = finding.jira_issue
elif finding.has_jira_group_issue:
jira_issue = finding.finding_group.jira_issue
jira_helper.add_simple_jira_comment(jira_instance, jira_issue, jira_comment)


def post_jira_comments(risk_acceptance, findings, message_factory, heads_up_days=0):
Expand All @@ -270,11 +268,15 @@ def post_jira_comments(risk_acceptance, findings, message_factory, heads_up_days

if jira_instance:
jira_comment = message_factory(risk_acceptance, heads_up_days)

for finding in findings:
jira_issue = None
if finding.has_jira_issue:
logger.debug("Creating JIRA comment for something risk acceptance related")
jira_helper.add_simple_jira_comment(jira_instance, finding.jira_issue, jira_comment)
jira_issue = finding.jira_issue
elif finding.has_jira_group_issue:
jira_issue = finding.finding_group.jira_issue

if jira_issue:
jira_helper.add_simple_jira_comment(jira_instance, jira_issue, jira_comment)


def get_expired_risk_acceptances_to_handle():
Expand Down Expand Up @@ -319,7 +321,7 @@ def simple_risk_accept(user: Dojo_User, finding: Finding, perform_save=True) ->
))


def risk_unaccept(user: Dojo_User, finding: Finding, perform_save=True) -> None:
def risk_unaccept(user: Dojo_User, finding: Finding, perform_save=True, post_comments=True) -> None:
logger.debug("unaccepting finding %i:%s if it is currently risk accepted", finding.id, finding)
if finding.risk_accepted:
logger.debug("unaccepting finding %i:%s", finding.id, finding)
Expand All @@ -336,7 +338,12 @@ def risk_unaccept(user: Dojo_User, finding: Finding, perform_save=True) -> None:

# post_jira_comment might reload from database so see unaccepted finding. but the comment
# only contains some text so that's ok
post_jira_comment(finding, unaccepted_message_creator)
if post_comments:
post_jira_comment(finding, unaccepted_message_creator)

# Update the JIRA obect for this finding
update_risk_acceptance_jira(finding)

# Add a note to reflect that the finding was removed from the risk acceptance
if user is not None:
finding.notes.add(Notes.objects.create(
Expand All @@ -362,3 +369,24 @@ def update_endpoint_statuses(finding: Finding, *, accept_risk: bool) -> None:
status.risk_accepted = False
status.last_modified = timezone.now()
status.save()


def update_risk_acceptance_jira(finding):
# Manage the jira status changes
push_to_jira = False
# Determine if the finding is in a group. if so, not push to jira yet
finding_in_group = finding.has_finding_group
# Check if there is a jira issue that needs to be updated
jira_issue_exists = finding.has_jira_issue or (finding.finding_group and finding.finding_group.has_jira_issue)
# Only push if the finding is not in a group
if jira_issue_exists:
# Determine if any automatic sync should occur
push_to_jira = jira_helper.is_push_all_issues(finding) \
or jira_helper.get_jira_instance(finding).finding_jira_sync
# Save the finding
finding.save(push_to_jira=(push_to_jira and not finding_in_group))

# we only push the group after saving the finding to make sure
# the updated data of the finding is pushed as part of the group
if push_to_jira and finding_in_group:
jira_helper.push_to_jira(finding.finding_group)
Maffooch marked this conversation as resolved.
Show resolved Hide resolved
Loading