@@ -1122,6 +1122,54 @@ def normalize_datetime(value):
11221122 return value
11231123
11241124
1125+ def _create_note_if_provided (
1126+ finding ,
1127+ note_entry ,
1128+ * ,
1129+ user = None ,
1130+ note_type = None ,
1131+ note_date = None ,
1132+ ):
1133+ """
1134+ Create a note for the finding when content is provided. Returns the note or None.
1135+ Note author defaults to finding.last_reviewed_by
1136+ """
1137+ if not note_entry :
1138+ return None
1139+
1140+ new_note = Notes .objects .create (
1141+ entry = note_entry ,
1142+ author = user or finding .last_reviewed_by ,
1143+ note_type = note_type ,
1144+ date = note_date ,
1145+ )
1146+ finding .notes .add (new_note )
1147+ return new_note
1148+
1149+
1150+ def _save_finding_with_jira_sync (finding , * , new_note = None ):
1151+ """Persist finding and apply JIRA sync behavior used by finding status actions."""
1152+ push_to_jira = False
1153+ finding_in_group = finding .has_finding_group
1154+ jira_issue_exists = finding .has_jira_issue or (
1155+ finding .finding_group and finding .finding_group .has_jira_issue
1156+ )
1157+ jira_instance = jira_helper .get_jira_instance (finding )
1158+ jira_project = jira_helper .get_jira_project (finding )
1159+
1160+ if jira_issue_exists :
1161+ push_to_jira = (
1162+ jira_helper .is_push_all_issues (finding )
1163+ or (jira_instance and jira_instance .finding_jira_sync )
1164+ )
1165+ if new_note and (getattr (jira_project , "push_notes" , False ) or push_to_jira ) and not finding_in_group :
1166+ jira_helper .add_comment (finding , new_note , force_push = True )
1167+
1168+ finding .save (push_to_jira = (push_to_jira and not finding_in_group ))
1169+ if push_to_jira and finding_in_group :
1170+ jira_helper .push_to_jira (finding .finding_group )
1171+
1172+
11251173def close_finding (
11261174 * ,
11271175 finding ,
@@ -1156,15 +1204,12 @@ def close_finding(
11561204 finding .last_reviewed_by = user
11571205
11581206 # Create note if provided
1159- new_note = None
1160- if note_entry :
1161- new_note = Notes .objects .create (
1162- entry = note_entry ,
1163- author = user ,
1164- note_type = note_type ,
1165- date = mitigated_date ,
1166- )
1167- finding .notes .add (new_note )
1207+ new_note = _create_note_if_provided (
1208+ finding ,
1209+ note_entry ,
1210+ note_type = note_type ,
1211+ note_date = mitigated_date ,
1212+ )
11681213
11691214 if settings .V3_FEATURE_LOCATIONS :
11701215 # Related locations
@@ -1186,26 +1231,7 @@ def close_finding(
11861231 # External issues (best effort)
11871232 close_external_issue (finding .id , "Closed by defectdojo" , "github" )
11881233
1189- # JIRA sync
1190- push_to_jira = False
1191- finding_in_group = finding .has_finding_group
1192- jira_issue_exists = finding .has_jira_issue or (
1193- finding .finding_group and finding .finding_group .has_jira_issue
1194- )
1195- jira_instance = jira_helper .get_jira_instance (finding )
1196- jira_project = jira_helper .get_jira_project (finding )
1197- if jira_issue_exists :
1198- push_to_jira = (
1199- jira_helper .is_push_all_issues (finding )
1200- or (jira_instance and jira_instance .finding_jira_sync )
1201- )
1202- if new_note and (getattr (jira_project , "push_notes" , False ) or push_to_jira ) and not finding_in_group :
1203- jira_helper .add_comment (finding , new_note , force_push = True )
1204-
1205- # Persist and push JIRA if applicable
1206- finding .save (push_to_jira = (push_to_jira and not finding_in_group ))
1207- if push_to_jira and finding_in_group :
1208- jira_helper .push_to_jira (finding .finding_group )
1234+ _save_finding_with_jira_sync (finding , new_note = new_note )
12091235
12101236 # Notification
12111237 create_notification (
@@ -1215,3 +1241,28 @@ def close_finding(
12151241 description = f'The finding "{ finding .title } " was closed by { user } ' ,
12161242 url = reverse ("view_finding" , args = (finding .id ,)),
12171243 )
1244+
1245+
1246+ def verify_finding (
1247+ * ,
1248+ finding ,
1249+ user ,
1250+ note_entry = None ,
1251+ note_type = None ,
1252+ ) -> None :
1253+ """Shared verify logic used by UI and API."""
1254+ verification_time = now ()
1255+
1256+ finding .verified = True
1257+ finding .last_reviewed = verification_time
1258+ finding .last_reviewed_by = user
1259+ finding .last_status_update = verification_time
1260+
1261+ new_note = _create_note_if_provided (
1262+ finding ,
1263+ note_entry ,
1264+ note_type = note_type ,
1265+ note_date = verification_time ,
1266+ )
1267+
1268+ _save_finding_with_jira_sync (finding , new_note = new_note )
0 commit comments