@@ -532,6 +532,20 @@ def get_jira_status(finding):
532
532
return None
533
533
534
534
535
+ # Used for unit testing so geting all the connections is manadatory
536
+ def get_jira_priortiy (finding ):
537
+ if finding .has_jira_issue :
538
+ j_issue = finding .jira_issue .jira_id
539
+ elif finding .finding_group and finding .finding_group .has_jira_issue :
540
+ j_issue = finding .finding_group .jira_issue .jira_id
541
+
542
+ if j_issue :
543
+ project = get_jira_project (finding )
544
+ issue = jira_get_issue (project , j_issue )
545
+ return issue .fields .priority
546
+ return None
547
+
548
+
535
549
# Used for unit testing so geting all the connections is manadatory
536
550
def get_jira_comments (finding ):
537
551
if finding .has_jira_issue :
@@ -675,15 +689,20 @@ def jira_description(obj):
675
689
def jira_priority (obj ):
676
690
if isinstance (obj , Finding ):
677
691
return get_jira_instance (obj ).get_priority (obj .severity )
692
+
678
693
if isinstance (obj , Finding_Group ):
679
- finding_group_severity_for_jira = get_finding_group_findings_above_threshold (obj )
694
+ # priority based on qualified findings, so if alls criticals get closed, the priority will gets lowered etc
695
+ active_findings = get_qualified_findings (obj )
680
696
681
- max_number_severity = max (Finding .get_number_severity (find .severity ) for find in finding_group_severity_for_jira )
682
- return Finding .get_severity (max_number_severity )
697
+ if not active_findings :
698
+ # using a string literal "Info" as we don't really have a "enum" for this anywhere
699
+ max_number_severity = Finding .get_number_severity ("Info" )
700
+ else :
701
+ max_number_severity = max (Finding .get_number_severity (find .severity ) for find in active_findings )
702
+ return get_jira_instance (obj ).get_priority (Finding .get_severity (max_number_severity ))
683
703
684
- logger .error ("unsupported object passed to push_to_jira: %s %i %s" , obj .__name__ , obj .id , obj )
685
- msg = f"Unsupported object passed to push_to_jira: { type (obj )} "
686
- raise RuntimeError (msg )
704
+ msg = f"Unsupported object type for jira_priority: { obj .__class__ .__name__ } "
705
+ raise ValueError (msg )
687
706
688
707
689
708
def jira_environment (obj ):
@@ -897,7 +916,7 @@ def failure_to_add_message(message: str, exception: Exception, _: Any) -> bool:
897
916
return failure_to_add_message (message , e , obj )
898
917
# Create a new issue in Jira with the fields set in the last step
899
918
try :
900
- logger .debug ("sending fields to JIRA: %s" , fields )
919
+ logger .debug ("Creating new JIRA issue with fields : %s" , json . dumps ( fields , indent = 4 ) )
901
920
new_issue = jira .create_issue (fields )
902
921
logger .debug ("saving JIRA_Issue for %s finding %s" , new_issue .key , obj .id )
903
922
j_issue = JIRA_Issue (jira_id = new_issue .id , jira_key = new_issue .key , jira_project = jira_project )
@@ -1000,6 +1019,14 @@ def failure_to_update_message(message: str, exception: Exception, obj: Any) -> b
1000
1019
labels = get_labels (obj ) + get_tags (obj )
1001
1020
if labels :
1002
1021
labels = list (dict .fromkeys (labels )) # de-dup
1022
+
1023
+ # Only Finding Groups will have their priority synced on updates.
1024
+ # For Findings we resepect any priority change made in JIRA
1025
+ # https://github.com/DefectDojo/django-DefectDojo/pull/9571 and https://github.com/DefectDojo/django-DefectDojo/pull/12475
1026
+ jira_priority_name = None
1027
+ if isinstance (obj , Finding_Group ):
1028
+ jira_priority_name = jira_priority (obj )
1029
+
1003
1030
# Set the fields that will compose the jira issue
1004
1031
try :
1005
1032
issuetype_fields = get_issuetype_fields (jira , jira_project .project_key , jira_instance .default_issue_type )
@@ -1011,20 +1038,18 @@ def failure_to_update_message(message: str, exception: Exception, obj: Any) -> b
1011
1038
component_name = jira_project .component if not issue .fields .components else None ,
1012
1039
labels = labels + issue .fields .labels ,
1013
1040
environment = jira_environment (obj ),
1014
- # Do not update the priority in jira after creation as this could have changed in jira, but should not change in dojo
1015
- # priority_name=jira_priority(obj),
1041
+ priority_name = jira_priority_name ,
1016
1042
issuetype_fields = issuetype_fields )
1017
1043
except Exception as e :
1018
1044
message = f"Failed to fetch fields for { jira_instance .default_issue_type } under project { jira_project .project_key } - { e } "
1019
1045
return failure_to_update_message (message , e , obj )
1046
+
1020
1047
# Update the issue in jira
1021
1048
try :
1022
- logger .debug ("sending fields to JIRA : %s" , fields )
1049
+ logger .debug ("Updating JIRA issue with fields : %s" , json . dumps ( fields , indent = 4 ) )
1023
1050
issue .update (
1024
1051
summary = fields ["summary" ],
1025
1052
description = fields ["description" ],
1026
- # Do not update the priority in jira after creation as this could have changed in jira, but should not change in dojo
1027
- # priority=fields['priority'],
1028
1053
fields = fields )
1029
1054
j_issue .jira_change = timezone .now ()
1030
1055
j_issue .save ()
@@ -1179,12 +1204,14 @@ def get_issuetype_fields(
1179
1204
try :
1180
1205
project = meta ["projects" ][0 ]
1181
1206
except Exception :
1207
+ logger .debug ("JIRA meta: %s" , json .dumps (meta , indent = 4 )) # this is None safe
1182
1208
msg = "Project misconfigured or no permissions in Jira ?"
1183
1209
raise JIRAError (msg )
1184
1210
1185
1211
try :
1186
1212
issuetype_fields = project ["issuetypes" ][0 ]["fields" ].keys ()
1187
1213
except Exception :
1214
+ logger .debug ("JIRA meta: %s" , json .dumps (meta , indent = 4 )) # this is None safe
1188
1215
msg = "Misconfigured default issue type ?"
1189
1216
raise JIRAError (msg )
1190
1217
@@ -1808,20 +1835,20 @@ def is_qualified(finding):
1808
1835
return finding .active and (finding .verified or not isenforced ) and (finding .numerical_severity <= jira_minimum_threshold )
1809
1836
1810
1837
1811
- def get_qualified_findings (findings ):
1838
+ def get_qualified_findings (finding_group ):
1812
1839
"""Filters findings to return only findings qualified to be pushed to JIRA, i.e. active, verified (unless not enforced) and severity is above the threshold"""
1813
- if not findings :
1840
+ if not finding_group . findings . all () :
1814
1841
return None
1815
1842
1816
- return [find for find in findings if is_qualified (find )]
1843
+ return [find for find in finding_group . findings . all () if is_qualified (find )]
1817
1844
1818
1845
1819
- def get_non_qualified_findings (findings ):
1846
+ def get_non_qualified_findings (finding_group ):
1820
1847
"""Filters findings to return only findings not qualified to be pushed to JIRA, i.e. inactive, not-verified (unless not enforced) and severity is below the threshold"""
1821
- if not findings :
1848
+ if not finding_group . findings . all () :
1822
1849
return None
1823
1850
1824
- return [find for find in findings if not is_qualified (find )]
1851
+ return [find for find in finding_group . findings . all () if not is_qualified (find )]
1825
1852
1826
1853
1827
1854
def get_sla_deadline (obj ):
@@ -1833,10 +1860,10 @@ def get_sla_deadline(obj):
1833
1860
return obj .sla_deadline ()
1834
1861
1835
1862
if isinstance (obj , Finding_Group ):
1836
- return min ([find .sla_deadline () for find in get_qualified_findings (obj . findings . all () ) if find .sla_deadline ()], default = None )
1863
+ return min ([find .sla_deadline () for find in get_qualified_findings (obj ) if find .sla_deadline ()], default = None )
1837
1864
1838
- logger . warning ( "get_sla_deadline: obj passed that is not a Finding or Finding_Group" )
1839
- return None
1865
+ msg = f "get_sla_deadline: obj passed that is not a Finding or Finding_Group: { type ( obj ) } "
1866
+ raise ValueError ( msg )
1840
1867
1841
1868
1842
1869
def get_severity (findings ):
0 commit comments