class Chelsea::TextFormatter

Produce output in text format

Public Class Methods

new(options) click to toggle source
Calls superclass method Formatter::new
# File lib/chelsea/formatters/text.rb, line 27
def initialize(options)
  super()
  @options = options
  @pastel = Pastel.new
end

Public Instance Methods

do_print(results) click to toggle source

rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize

# File lib/chelsea/formatters/text.rb, line 76
def do_print(results)
  puts results
end
fetch_results(server_response, reverse_dependencies) click to toggle source

rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize

# File lib/chelsea/formatters/text.rb, line 34
def fetch_results(server_response, reverse_dependencies) # rubocop:disable Metrics/MethodLength
  response = ''
  if @options[:verbose]
    response += "\n"\
    "Audit Results\n"\
    "=============\n"
  end

  vuln_count = server_response.count do |vuln|
    vuln['vulnerabilities'].length.positive?
  end
  server_response.sort! { |x| x['vulnerabilities'].count }
  server_response.each.with_index do |r, idx|
    name, version = r['coordinates'].sub('pkg:gem/', '').split('@')
    reverse_deps = reverse_dependencies["#{name}-#{version}"]
    if r['vulnerabilities'].length.positive?
      response += @pastel.red(
        "[#{idx}/#{server_response.count}] - #{r['coordinates']} "
      )
      response += @pastel.red.bold("Vulnerable.\n")
      response += _get_reverse_deps(reverse_deps, name) if reverse_deps
      r['vulnerabilities'].each do |k, _|
        response += _format_vuln(k)
      end
    elsif @options[:verbose]
      response += @pastel.white(
        "[#{idx}/#{server_response.count}] - #{r['coordinates']} "
      )
      response += @pastel.green.bold("No vulnerabilities found!\n")
      response += _get_reverse_deps(reverse_deps, name) if reverse_deps
    end
  end

  table = TTY::Table.new(
    ['Dependencies Audited', 'Vulnerable Dependencies'],
    [[server_response.count, vuln_count]]
  )
  response += table.render(:unicode)
  response
end

Private Instance Methods

_color_based_on_cvss_score(cvss_score) click to toggle source
# File lib/chelsea/formatters/text.rb, line 103
def _color_based_on_cvss_score(cvss_score)
  case cvss_score
  when 0..3
    @pastel.cyan.bold
  when 4..5
    @pastel.yellow.bold
  when 6..7
    @pastel.orange.bold
  else
    @pastel.red.bold
  end
end
_format_vuln(vuln) click to toggle source
# File lib/chelsea/formatters/text.rb, line 82
def _format_vuln(vuln)
  vuln_response = "\n\tVulnerability Details:\n"
  _color_method = _color_based_on_cvss_score(vuln['cvssScore'])
  _report_lines(vuln).each do |line|
    vuln_response += _color_method(line)
  end
  vuln_response
end
_get_reverse_deps(coords, name) click to toggle source
# File lib/chelsea/formatters/text.rb, line 116
def _get_reverse_deps(coords, name)
  coords.each_with_object('') do |dep, s|
    dep.each do |gran|
      s << "\tRequired by: #{gran}\n" if gran.instance_of?(String) && !gran.include?(name)
    end
  end
end
_report_lines(vuln) click to toggle source
# File lib/chelsea/formatters/text.rb, line 91
def _report_lines(vuln)
  [
    "\n\tID: #{vuln['id']}\n",
    "\n\tTitle: #{vuln['title']}\n",
    "\n\tDescription: #{vuln['description']}\n",
    "\n\tCVSS Score: #{vuln['cvssScore']}\n",
    "\n\tCVSS Vector: #{vuln['cvssVector']}\n",
    "\n\tCVE: #{vuln['cve']}\n",
    "\n\tReference: #{vuln['reference']}\n\n"
  ]
end