def add_issue(find, push_to_jira): eng = Engagement.objects.get(test=find.test) prod = Product.objects.get(engagement=eng) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if push_to_jira: if 'Active' in find.status() and 'Verified' in find.status(): jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) new_issue = jira.create_issue( project=jpkey.project_key, summary=find.title, components=[ { 'name': jpkey.component }, ], description=jira_long_description(find.long_desc(), find.id, jira_conf.finding_text), issuetype={'name': jira_conf.default_issue_type}, priority={'name': jira_conf.get_priority(find.severity)}) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue, finding=find) j_issue.save() issue = jira.issue(new_issue.id) #Add labels (security & product) add_labels(find, new_issue) #Upload dojo finding screenshots to Jira for pic in find.images.all(): jira_attachment(jira, issue, settings.MEDIA_ROOT + pic.image_large.name)
def add_issue(find, push_to_jira): eng = Engagement.objects.get(test=find.test) prod = Product.objects.get(engagement=eng) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if push_to_jira: if 'Active' in find.status() and 'Verified' in find.status(): try: JIRAError.log_to_tempfile = False jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) if jpkey.component: new_issue = jira.create_issue( project=jpkey.project_key, summary=find.title, components=[ { 'name': jpkey.component }, ], description=jira_long_description( find.long_desc(), find.id, jira_conf.finding_text), issuetype={'name': jira_conf.default_issue_type}, priority={ 'name': jira_conf.get_priority(find.severity) }) else: new_issue = jira.create_issue( project=jpkey.project_key, summary=find.title, description=jira_long_description( find.long_desc(), find.id, jira_conf.finding_text), issuetype={'name': jira_conf.default_issue_type}, priority={ 'name': jira_conf.get_priority(find.severity) }) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue, finding=find) j_issue.save() issue = jira.issue(new_issue.id) #Add labels (security & product) add_labels(find, new_issue) #Upload dojo finding screenshots to Jira for pic in find.images.all(): jira_attachment(jira, issue, settings.MEDIA_ROOT + pic.image_large.name) #if jpkey.enable_engagement_epic_mapping: # epic = JIRA_Issue.objects.get(engagement=eng) # issue_list = [j_issue.jira_id,] # jira.add_issues_to_epic(epic_id=epic.jira_id, issue_keys=[str(j_issue.jira_id)], ignore_epics=True) except JIRAError as e: log_jira_alert(e.text, find) else: log_jira_alert("Finding not active or verified.", find)
def add_epic(engagement): logger.info('trying to create a new jira EPIC for %d:%s', engagement.id, engagement.name) if not is_jira_configured_and_enabled(engagement): return False logger.debug('config found') jira_project = get_jira_project(engagement) jira_instance = get_jira_instance(engagement) if jira_project.enable_engagement_epic_mapping: issue_dict = { 'project': { 'key': jira_project.project_key }, 'summary': engagement.name, 'description': engagement.name, 'issuetype': { 'name': 'Epic' }, 'customfield_' + str(jira_instance.epic_name_id): engagement.name, } try: jira = get_jira_connection(jira_instance) logger.debug('add_epic: %s', issue_dict) new_issue = jira.create_issue(fields=issue_dict) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue.key, engagement=engagement, jira_project=jira_project) j_issue.save() return True except JIRAError as e: # should we try to parse the errors as JIRA is very strange in how it responds. # for example a non existent project_key leads to "project key is required" which sounds like something is missing # but it's just a non-existent project (or maybe a project for which the account has no create permission?) # # {"errorMessages":[],"errors":{"project":"project is required"}} logger.exception(e) error = str(e) message = "" if "customfield" in error: message = "The 'Epic name id' in your DefectDojo Jira Configuration does not appear to be correct. Please visit, " + jira_instance.url + \ "/rest/api/2/field and search for Epic Name. Copy the number out of cf[number] and place in your DefectDojo settings for Jira and try again. For example, if your results are cf[100001] then copy 100001 and place it in 'Epic name id'. (Your Epic Id will be different.) \n\n" log_jira_generic_alert('Jira Engagement/Epic Creation Error', message + error) return False else: messages.add_message( get_current_request(), messages.ERROR, 'Push to JIRA for Epic skipped because enable_engagement_epic_mapping is not checked for this engagement', extra_tags='alert-danger') return False
def add_issue(find, push_to_jira): eng = Engagement.objects.get(test=find.test) prod = Product.objects.get(engagement= eng) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if push_to_jira: if 'Active' in find.status() and 'Verified' in find.status(): jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) new_issue = jira.create_issue(project=jpkey.project_key, summary=find.title, description=find.long_desc(), issuetype={'name': 'Bug'}, priority={'name': jira_conf.get_priority(find.severity)}) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue, finding = find) j_issue.save() if jpkey.enable_engagement_epic_mapping: epic = JIRA_Issue.objects.get(engagement=eng) issue_list = [j_issue.jira_id,] jira.add_issues_to_epic(epic_id=epic.jira_id, issue_keys=[str(j_issue.jira_id)], ignore_epics=True)
def add_epic(eng, push_to_jira): engagement = eng prod = Product.objects.get(engagement=engagement) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if jpkey.enable_engagement_epic_mapping and push_to_jira: issue_dict = { 'project': {'key': jpkey.project_key}, 'summary': engagement.name, 'description' : engagement.name, 'issuetype': {'name': 'Epic'}, 'customfield_' + str(jira_conf.epic_name_id) : engagement.name, } jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) new_issue = jira.create_issue(fields=issue_dict) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue, engagement=engagement) j_issue.save()
def finding_link_jira(request, finding, new_jira_issue_key): logger.debug('linking existing jira issue %s for finding %i', new_jira_issue_key, finding.id) existing_jira_issue = jira_get_issue(get_jira_project(finding), new_jira_issue_key) jira_project = get_jira_project(finding) if not existing_jira_issue: raise ValueError('JIRA issue not found or cannot be retrieved: ' + new_jira_issue_key) jira_issue = JIRA_Issue(jira_id=existing_jira_issue.id, jira_key=existing_jira_issue.key, finding=finding, jira_project=jira_project) jira_issue.jira_key = new_jira_issue_key # jira timestampe are in iso format: 'updated': '2020-07-17T09:49:51.447+0200' # seems to be a pain to parse these in python < 3.7, so for now just record the curent time as # as the timestamp the jira link was created / updated in DD jira_issue.jira_creation = timezone.now() jira_issue.jira_change = timezone.now() jira_issue.save() finding.save(push_to_jira=False, dedupe_option=False, issue_updater_option=False) jira_issue_url = get_jira_url(finding) return True
def add_issue(find, push_to_jira): eng = Engagement.objects.get(test=find.test) prod = Product.objects.get(engagement= eng) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if push_to_jira: if 'Active' in find.status() and 'Verified' in find.status(): try: JIRAError.log_to_tempfile=False jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) if jpkey.component: new_issue = jira.create_issue(project=jpkey.project_key, summary=find.title, components=[{'name': jpkey.component}, ], description=jira_long_description(find.long_desc(), find.id, jira_conf.finding_text), issuetype={'name': jira_conf.default_issue_type}, priority={'name': jira_conf.get_priority(find.severity)}) else: new_issue = jira.create_issue(project=jpkey.project_key, summary=find.title, description=jira_long_description(find.long_desc(), find.id, jira_conf.finding_text), issuetype={'name': jira_conf.default_issue_type}, priority={'name': jira_conf.get_priority(find.severity)}) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue, finding=find) j_issue.save() issue = jira.issue(new_issue.id) #Add labels (security & product) add_labels(find, new_issue) #Upload dojo finding screenshots to Jira for pic in find.images.all(): jira_attachment(jira, issue, settings.MEDIA_ROOT + pic.image_large.name) #if jpkey.enable_engagement_epic_mapping: # epic = JIRA_Issue.objects.get(engagement=eng) # issue_list = [j_issue.jira_id,] # jira.add_issues_to_epic(epic_id=epic.jira_id, issue_keys=[str(j_issue.jira_id)], ignore_epics=True) except JIRAError as e: log_jira_alert(e.text, find) else: log_jira_alert("Finding not active or verified.", find)
def add_issue(find, push_to_jira): eng = Engagement.objects.get(test=find.test) prod = Product.objects.get(engagement=eng) jpkey = JIRA_PKey.objects.get(product=prod) jira_conf = jpkey.conf if push_to_jira: if 'Active' in find.status() and 'Verified' in find.status(): jira = JIRA(server=jira_conf.url, basic_auth=(jira_conf.username, jira_conf.password)) new_issue = jira.create_issue( project=jpkey.project_key, summary=find.title, description=jira_long_description(find.long_desc(), find.id, jira_conf.finding_text), issuetype={'name': jira_conf.default_issue_type}, priority={'name': jira_conf.get_priority(find.severity)}) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue, finding=find) j_issue.save() issue = jira.issue(new_issue.id) #Add labels (security & product) add_labels(find, new_issue)
def add_jira_issue(find): logger.info('trying to create a new jira issue for %d:%s', find.id, find.title) if not is_jira_enabled(): return False if not is_jira_configured_and_enabled(find): logger.error( "Finding {} cannot be pushed to JIRA as there is no JIRA configuration for this product." .format(find.id)) log_jira_alert( 'Finding cannot be pushed to JIRA as there is no JIRA configuration for this product.', find) return False jira_project = get_jira_project(find) jira_instance = get_jira_instance(find) can_be_pushed_to_jira, error_message, error_code = finding_can_be_pushed_to_jira( find) if not can_be_pushed_to_jira: log_jira_alert(error_message, find) logger.warn("Finding %s cannot be pushed to JIRA: %s.", find.id, error_message) logger.warn("The JIRA issue will NOT be created.") return False logger.debug('Trying to create a new JIRA issue for finding {}...'.format( find.id)) meta = None try: JIRAError.log_to_tempfile = False jira = get_jira_connection(jira_instance) fields = { 'project': { 'key': jira_project.project_key }, 'summary': find.title, 'description': jira_description(find), 'issuetype': { 'name': jira_instance.default_issue_type } } #CUSTOM HS Code fields['customfield_11542'] = [{"value": find.customfield_11542}] if jira_project.component: fields['components'] = [ { 'name': jira_project.component }, ] # populate duedate field, but only if it's available for this project + issuetype if not meta: meta = get_jira_meta(jira, jira_project) epic_name_field = get_epic_name_field_name(jira_instance) if epic_name_field in meta['projects'][0]['issuetypes'][0]['fields']: # epic name is present in this issuetype # epic name is always mandatory in jira, so we populate it fields[epic_name_field] = fields['summary'] if 'priority' in meta['projects'][0]['issuetypes'][0]['fields']: fields['priority'] = { 'name': jira_instance.get_priority(find.severity) } labels = get_labels(find) if labels: if 'labels' in meta['projects'][0]['issuetypes'][0]['fields']: fields['labels'] = labels if System_Settings.objects.get().enable_finding_sla: if 'duedate' in meta['projects'][0]['issuetypes'][0]['fields']: # jira wants YYYY-MM-DD duedate = find.sla_deadline() if duedate: fields['duedate'] = duedate.strftime('%Y-%m-%d') if len(find.endpoints.all()) > 0: if not meta: meta = get_jira_meta(jira, jira_project) if 'environment' in meta['projects'][0]['issuetypes'][0]['fields']: environment = "\n".join( [str(endpoint) for endpoint in find.endpoints.all()]) fields['environment'] = environment logger.debug('sending fields to JIRA: %s', fields) new_issue = jira.create_issue(fields) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue.key, finding=find, jira_project=jira_project) j_issue.jira_creation = timezone.now() j_issue.jira_change = timezone.now() j_issue.save() issue = jira.issue(new_issue.id) find.save(push_to_jira=False, dedupe_option=False, issue_updater_option=False) # Upload dojo finding screenshots to Jira for pic in find.images.all(): jira_attachment(find, jira, issue, settings.MEDIA_ROOT + pic.image_large.name) if jira_project.enable_engagement_epic_mapping: eng = find.test.engagement logger.debug('Adding to EPIC Map: %s', eng.name) epic = get_jira_issue(eng) if epic: jira.add_issues_to_epic(epic_id=epic.jira_id, issue_keys=[str(j_issue.jira_id)], ignore_epics=True) else: logger.info('The following EPIC does not exist: %s', eng.name) logger.info('Created the following jira issue for %d:%s', find.id, find.title) return True except JIRAError as e: logger.exception(e) logger.error("jira_meta for project: %s and url: %s meta: %s", jira_project.project_key, jira_project.jira_instance.url, json.dumps(meta, indent=4)) # this is None safe log_jira_alert(e.text, find) return False
def add_jira_issue(find): logger.info('trying to create a new jira issue for %d:%s', find.id, find.title) if not is_jira_enabled(): return if not is_jira_configured_and_enabled(find): logger.error( "Finding {} cannot be pushed to JIRA as there is no JIRA configuration for this product." .format(find.id)) log_jira_alert( 'Finding cannot be pushed to JIRA as there is no JIRA configuration for this product.', find) return jira_minimum_threshold = None if System_Settings.objects.get().jira_minimum_severity: jira_minimum_threshold = Finding.get_number_severity( System_Settings.objects.get().jira_minimum_severity) jira_project = get_jira_project(find) jira_instance = get_jira_instance(find) if 'Active' in find.status() and 'Verified' in find.status(): if jira_minimum_threshold and jira_minimum_threshold > Finding.get_number_severity( find.severity): log_jira_alert( 'Finding below the minimum JIRA severity threshold.', find) logger.warn( "Finding {} is below the minimum JIRA severity threshold.". format(find.id)) logger.warn("The JIRA issue will NOT be created.") return logger.debug( 'Trying to create a new JIRA issue for finding {}...'.format( find.id)) meta = None try: JIRAError.log_to_tempfile = False jira = get_jira_connection(jira_instance) fields = { 'project': { 'key': jira_project.project_key }, 'summary': find.title, 'description': jira_description(find), 'issuetype': { 'name': jira_instance.default_issue_type }, } if jira_project.component: fields['components'] = [ { 'name': jira_project.component }, ] # populate duedate field, but only if it's available for this project + issuetype if not meta: meta = get_jira_meta(jira, jira_project) if 'priority' in meta['projects'][0]['issuetypes'][0]['fields']: fields['priority'] = { 'name': jira_instance.get_priority(find.severity) } labels = get_labels(find) if labels: if 'labels' in meta['projects'][0]['issuetypes'][0]['fields']: fields['labels'] = labels if System_Settings.objects.get().enable_finding_sla: if 'duedate' in meta['projects'][0]['issuetypes'][0]['fields']: # jira wants YYYY-MM-DD duedate = find.sla_deadline() if duedate: fields['duedate'] = duedate.strftime('%Y-%m-%d') if len(find.endpoints.all()) > 0: if not meta: meta = get_jira_meta(jira, jira_project) if 'environment' in meta['projects'][0]['issuetypes'][0][ 'fields']: environment = "\n".join( [str(endpoint) for endpoint in find.endpoints.all()]) fields['environment'] = environment logger.debug('sending fields to JIRA: %s', fields) new_issue = jira.create_issue(fields) j_issue = JIRA_Issue(jira_id=new_issue.id, jira_key=new_issue.key, finding=find, jira_project=jira_project) j_issue.jira_creation = timezone.now() j_issue.jira_change = timezone.now() j_issue.save() issue = jira.issue(new_issue.id) find.save(push_to_jira=False, dedupe_option=False, issue_updater_option=False) # Upload dojo finding screenshots to Jira for pic in find.images.all(): jira_attachment(find, jira, issue, settings.MEDIA_ROOT + pic.image_large.name) # if jira_project.enable_engagement_epic_mapping: # epic = get_jira_issue(eng) # issue_list = [j_issue.jira_id,] # jira.add_jira_issues_to_epic(epic_id=epic.jira_id, issue_keys=[str(j_issue.jira_id)], ignore_epics=True) return True except JIRAError as e: logger.exception(e) logger.error("jira_meta for project: %s and url: %s meta: %s", jira_project.project_key, jira_project.jira_instance.url, json.dumps(meta, indent=4)) # this is None safe log_jira_alert(e.text, find) return False else: log_jira_alert( "A Finding needs to be both Active and Verified to be pushed to JIRA.", find) logger.warning( "A Finding needs to be both Active and Verified to be pushed to JIRA: %s", find) return False