Ejemplo n.º 1
0
def _fill_current_value(issue_params, assessment, initial_info):
  """Fills unchanged props with current values."""
  current_issue_params = {}
  for name, api_name in _ISSUE_TRACKER_UPDATE_FIELDS:
    current_issue_params[api_name] = initial_info.get(name)
  issue_params = dict(current_issue_params, **issue_params)

  if 'status' not in issue_params:
    # Resend status on any change.
    status_value = ASSESSMENT_STATUSES_MAPPING.get(assessment.status)
    if status_value:
      issue_params['status'] = status_value

  if 'hotlist_ids' not in issue_params:
    # Resend hotlists on any change.
    current_hotlist_id = initial_info.get('hotlist_id')
    issue_params['hotlist_ids'] = [current_hotlist_id] if (
        current_hotlist_id) else []

  if 'ccs' not in issue_params:
    current_cc_list = initial_info.get('cc_list')
    if current_cc_list:
      issue_params['ccs'] = current_cc_list

  return issue_params
Ejemplo n.º 2
0
def _create_issuetracker_info(assessment, issue_tracker_info):
  """Creates an entry for IssueTracker model."""
  if not issue_tracker_info.get('title'):
    issue_tracker_info['title'] = assessment.title
  issue_tracker_info['status'] = ASSESSMENT_STATUSES_MAPPING.get(
      assessment.status
  )

  if (issue_tracker_info.get('enabled') and
          _is_issue_tracker_enabled(audit=assessment.audit)):

    assignee_email, cc_list = _collect_issue_emails(assessment)
    if assignee_email is not None:
      issue_tracker_info['assignee'] = assignee_email
      issue_tracker_info['cc_list'] = cc_list

    try:
      issue_id = _create_issuetracker_issue(assessment, issue_tracker_info)
    except integrations_errors.Error as error:
      logger.error(
          'Unable to create a ticket while creating assessment ID=%d: %s',
          assessment.id, error)
      issue_tracker_info = {
          'enabled': False,
      }
      assessment.add_warning('Unable to create a ticket.')
    else:
      issue_tracker_info['issue_id'] = issue_id
      issue_tracker_info['issue_url'] = _ISSUE_URL_TMPL % issue_id
  else:
    issue_tracker_info = {
        'enabled': False,
    }

  all_models.IssuetrackerIssue.create_or_update_from_dict(
      assessment, issue_tracker_info)
Ejemplo n.º 3
0
def prepare_issue_json(assessment,
                       issue_tracker_info=None,
                       create_issuetracker=False):
    """Create json that will be sent to IssueTracker.

  Args:
      assessment: Instance of Assessment.
      issue_tracker_info: Dict with IssueTracker info.
      create_issuetracker: Bool indicator for crate issuetracker state.

  Returns:
      Dict with IssueTracker issue info.
  """
    if not issue_tracker_info:
        issue_tracker_info = assessment.audit.issuetracker_issue.to_dict()
        issue_tracker_info['title'] = assessment.title
        issue_tracker_info['status'] = ASSESSMENT_STATUSES_MAPPING.get(
            assessment.status)

    integration_utils.normalize_issue_tracker_info(issue_tracker_info)
    integration_utils.set_values_for_missed_fields(assessment,
                                                   issue_tracker_info)
    assignee_email, cc_list = _collect_assessment_emails(assessment)
    if assignee_email is not None:
        issue_tracker_info['assignee'] = assignee_email
        issue_tracker_info['cc_list'] = cc_list

    hotlist_id = issue_tracker_info.get('hotlist_id')
    issue_id = issue_tracker_info.get(
        'issue_id') if issue_tracker_info else None
    issue_params = {
        'component_id': issue_tracker_info['component_id'],
        'hotlist_ids': [hotlist_id] if hotlist_id else [],
        'title': issue_tracker_info['title'],
        'type': issue_tracker_info['issue_type'],
        'priority': issue_tracker_info['issue_priority'],
        'severity': issue_tracker_info['issue_severity'],
        'reporter': get_reporter_email(assessment),
        'assignee': '',
        'verifier': '',
        'status': issue_tracker_info['status'],
        'comment': create_asmnt_comment(assessment, issue_id),
    }
    custom_fields = []

    due_date = issue_tracker_info.get('due_date')
    if due_date:
        custom_fields.append({
            "name": constants.CUSTOM_FIELDS_DUE_DATE,
            "value": due_date.strftime("%Y-%m-%d"),
            "type": "DATE",
            "display_string": constants.CUSTOM_FIELDS_DUE_DATE
        })

    if custom_fields:
        issue_params['custom_fields'] = custom_fields

    assignee = issue_tracker_info.get('assignee')
    if assignee:
        if not issue_tracker_info['status']:
            issue_params['status'] = 'ASSIGNED'
        issue_params['assignee'] = assignee
        issue_params['verifier'] = assignee

    if create_issuetracker:
        cc_list = issue_tracker_info.get('cc_list', [])
        audit_ccs = get_audit_ccs(assessment)
        grouped_ccs = group_cc_emails(audit_ccs, cc_list)
        if grouped_ccs:
            issue_params['ccs'] = grouped_ccs
        else:
            issue_params['ccs'] = []

    return issue_params
Ejemplo n.º 4
0
def _handle_issuetracker(sender, obj=None, src=None, **kwargs):  # noqa
    """Handles IssueTracker information during assessment update event."""
    del sender  # Unused

    if not common_handlers.global_synchronization_enabled():
        return

    if not _is_issue_tracker_enabled(audit=obj.audit):
        # Skip updating issue and info if feature is disabled on Audit level.
        return

    issue_obj = all_models.IssuetrackerIssue.get_issue(_ASSESSMENT_MODEL_NAME,
                                                       obj.id)

    initial_info = issue_obj.to_dict(
        include_issue=True,
        include_private=True) if issue_obj is not None else {}
    new_info = src.get('issue_tracker') or {}

    issue_tracker_info = dict(initial_info, **new_info)

    initial_issue_id = initial_info.get('issue_id')
    old_ticket_id = int(initial_issue_id) if initial_issue_id else None
    get_ticket_id = issue_tracker_info.get('issue_id', None)
    ticket_id = int(get_ticket_id) if get_ticket_id else None

    needs_creation = (not issue_obj) or (not old_ticket_id) or (not ticket_id)

    if issue_tracker_info.get('enabled'):
        if needs_creation:
            _create_issuetracker_info(obj, issue_tracker_info)
            if not obj.warnings:
                it_issue = all_models.IssuetrackerIssue.get_issue(
                    obj.__class__.__name__, obj.id)
                new_ticket_id = it_issue.issue_id if it_issue else None
                if old_ticket_id and new_ticket_id and old_ticket_id != new_ticket_id:
                    _detach_assessment(new_ticket_id, old_ticket_id)
            return

        _, issue_tracker_info['cc_list'] = _collect_assessment_emails(obj)

    else:
        issue_tracker_info['enabled'] = False

    initial_assessment = kwargs.pop('initial_state', None)

    issue_tracker_info['title'] = obj.title
    if not issue_tracker_info.get('due_date'):
        issue_tracker_info['due_date'] = obj.start_date
    issue_tracker_info['status'] = ASSESSMENT_STATUSES_MAPPING.get(obj.status)

    if ticket_id != old_ticket_id and issue_tracker_info['enabled']:
        _link_assessment(obj, issue_tracker_info)
        if not obj.warnings:
            _detach_assessment(ticket_id, old_ticket_id)
        return

    try:
        _update_issuetracker_issue(obj, issue_tracker_info, initial_assessment,
                                   initial_info, src)
    except integrations_errors.Error as error:
        if error.status == 429:
            logger.error(
                'The request updating ticket ID=%d for assessment ID=%d was '
                'rate limited: %s', ticket_id, obj.id, error)
        else:
            logger.error(
                'Unable to update a ticket ID=%d while updating '
                'assessment ID=%d: %s', ticket_id, obj.id, error)
        obj.add_warning('Unable to update a ticket.')

    _update_issuetracker_info(obj, issue_tracker_info)