Ejemplo n.º 1
0
def update_epic(engagement):
    logger.info('trying to update 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:
        try:
            jira = get_jira_connection(jira_instance)
            j_issue = get_jira_issue(engagement)
            issue = jira.issue(j_issue.jira_id)
            issue.update(summary=engagement.name, description=engagement.name)
            return True
        except JIRAError as e:
            logger.exception(e)
            log_jira_generic_alert('Jira Engagement/Epic Update Error', str(e))
            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
Ejemplo n.º 2
0
def get_jira_meta(jira, jira_project):
    meta = jira.createmeta(
        projectKeys=jira_project.project_key,
        issuetypeNames=jira_project.jira_instance.default_issue_type,
        expand="projects.issuetypes.fields")
    # logger.debug("get_jira_meta: %s", json.dumps(meta, indent=4))  # this is None safe
    # meta['projects'][0]['issuetypes'][0]['fields']:

    meta_data_error = False
    if len(meta['projects']) == 0:
        # non-existent project, or no permissions
        # [09/Nov/2020 21:04:22] DEBUG [dojo.jira_link.helper:595] get_jira_meta: {
        #     "expand": "projects",
        #     "projects": []
        # }
        meta_data_error = True
        message = 'unable to retrieve metadata from JIRA %s for project %s. Invalid project key or no permissions to this project?' % (
            jira_project.jira_instance, jira_project.project_key)

    elif len(meta['projects'][0]['issuetypes']) == 0:
        # default issue type doesn't exist in project
        # [09/Nov/2020 21:09:03] DEBUG [dojo.jira_link.helper:595] get_jira_meta: {
        #     "expand": "projects",
        #     "projects": [
        #         {
        #             "expand": "issuetypes",
        #             "self": "https://jira-uat.com/rest/api/2/project/1212",
        #             "id": "1212",
        #             "key": "ISO",
        #             "name": "ISO ISMS",
        #             "avatarUrls": {
        #                 "48x48": "https://jira-uat.com/secure/projectavatar?pid=14431&avatarId=17200",
        #                 "24x24": "https://jira-uat.com/secure/projectavatar?size=small&pid=14431&avatarId=17200",
        #                 "16x16": "https://jira-uat.com/secure/projectavatar?size=xsmall&pid=14431&avatarId=17200",
        #                 "32x32": "https://jira-uat.com/secure/projectavatar?size=medium&pid=14431&avatarId=17200"
        #             },
        #             "issuetypes": []
        #         }
        #     ]
        # }
        meta_data_error = True
        message = 'unable to retrieve metadata from JIRA %s for issuetype %s in project %s. Invalid default issue type configured in Defect Dojo?' % (
            jira_project.jira_instance,
            jira_project.jira_instance.default_issue_type,
            jira_project.project_key)

    if meta_data_error:
        logger.warn(message)
        logger.warn("get_jira_meta: %s",
                    json.dumps(meta, indent=4))  # this is None safe

        messages.add_message(get_current_request(),
                             messages.ERROR,
                             message,
                             extra_tags='alert-danger')
        raise JIRAError(text=message)
    else:
        return meta
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
def get_jira_connection_raw(jira_server, jira_username, jira_password):
    try:
        jira = JIRA(server=jira_server,
                    basic_auth=(jira_username, jira_password),
                    options={"verify": settings.JIRA_SSL_VERIFY},
                    max_retries=0)

        logger.debug('logged in to JIRA ' '%s' ' successfully', jira_server)

        return jira
    except JIRAError as e:
        logger.exception(e)

        if e.status_code in [401, 403]:
            log_jira_generic_alert('JIRA Authentication Error', e)
        else:
            log_jira_generic_alert('Unknown JIRA Connection Error', e)

        messages.add_message(
            get_current_request(),
            messages.ERROR,
            'Unable to authenticate. Please check the URL, username, password, captcha challenge, Network connection. Details in alert on top right. '
            + e.text,
            extra_tags='alert-danger')
        raise e

    except requests.exceptions.RequestException as re:
        logger.exception(re)
        log_jira_generic_alert('Unknown JIRA Connection Error', re)

        messages.add_message(
            get_current_request(),
            messages.ERROR,
            'Unable to authenticate. Please check the URL, username, password, IP whitelist, Network connection. Details in alert on top right.',
            extra_tags='alert-danger')
        raise re
Ejemplo n.º 5
0
def close_epic(eng, push_to_jira):
    engagement = eng
    if not is_jira_enabled():
        return False

    if not is_jira_configured_and_enabled(engagement):
        return False

    jira_project = get_jira_project(engagement)
    jira_instance = get_jira_instance(engagement)
    if jira_project.enable_engagement_epic_mapping:
        if push_to_jira:
            try:
                jissue = get_jira_issue(eng)
                if jissue is None:
                    logger.warn("JIRA close epic failed: no issue found")
                    return False

                req_url = jira_instance.url + '/rest/api/latest/issue/' + \
                    jissue.jira_id + '/transitions'
                json_data = {
                    'transition': {
                        'id': jira_instance.close_status_key
                    }
                }
                r = requests.post(url=req_url,
                                  auth=HTTPBasicAuth(jira_instance.username,
                                                     jira_instance.password),
                                  json=json_data)
                if r.status_code != 204:
                    logger.warn("JIRA close epic failed with error: {}".format(
                        r.text))
                    return False
                return True
            except JIRAError as e:
                logger.exception(e)
                log_jira_generic_alert('Jira Engagement/Epic Close Error',
                                       str(e))
                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
Ejemplo n.º 6
0
def add_error_message_to_response(message):
    if get_current_request():
        messages.add_message(get_current_request(),
                             messages.ERROR,
                             message,
                             extra_tags='alert-danger')