Class: Chelsea::Gems

Inherits:
Object
  • Object
show all
Defined in:
lib/chelsea/gems.rb

Overview

Class to collect and audit packages from a Gemfile.lock

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file:, verbose:, options: { format: 'text' }) ⇒ Gems

rubocop:disable Metrics/MethodLength



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/chelsea/gems.rb', line 36

def initialize(file:, verbose:, options: { format: 'text' }) # rubocop:disable Metrics/MethodLength
  @verbose = verbose
  raise 'Gemfile.lock not found, check --file path' unless File.file?(file) || file.nil?

  _silence_stderr unless @verbose

  @pastel = Pastel.new
  @formatter = FormatterFactory.new.get_formatter(
    format: options[:format],
    verbose: verbose
  )
  @client = Chelsea.client(options)
  @deps = Chelsea::Deps.new(path: Pathname.new(file))
  @spinner = Chelsea::Spinner.new
end

Instance Attribute Details

#depsObject

Returns the value of attribute deps.



34
35
36
# File 'lib/chelsea/gems.rb', line 34

def deps
  @deps
end

Instance Method Details

#auditObject

Runs through auditing algorithm, raising exceptions on REST calls made by @deps.get_vulns



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/chelsea/gems.rb', line 77

def audit # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
  # This spinner management is out of control
  # we should wrap a block with start and stop messages,
  # or use a stack to ensure all spinners stop.
  spin = @spinner.spin_msg 'Parsing dependencies'

  begin
    dependencies = @deps.dependencies
    spin.success('...done.')
  rescue StandardError
    spin.stop
    _print_err "Parsing dependency line #{gem} failed."
  end

  reverse_dependencies = @deps.reverse_dependencies

  spin = @spinner.spin_msg 'Parsing Versions'
  coordinates = @deps.coordinates
  spin.success('...done.')
  spin = @spinner.spin_msg 'Making request to OSS Index server'
  spin.stop

  begin
    server_response = @client.get_vulns(coordinates)
    spin.success('...done.')
  rescue SocketError
    spin.stop('...request failed.')
    _print_err 'Socket error getting data from OSS Index server.'
  rescue RestClient::RequestFailed => e
    spin.stop('...request failed.')
    _print_err "Error getting data from OSS Index server:#{e.response}."
  rescue RestClient::ResourceNotFound
    spin.stop('...request failed.')
    _print_err 'Error getting data from OSS Index server. Resource not found.'
  rescue Errno::ECONNREFUSED
    spin.stop('...request failed.')
    _print_err 'Error getting data from OSS Index server. Connection refused.'
  end
  [server_response, dependencies, reverse_dependencies]
end

#collect_iqObject



71
72
73
# File 'lib/chelsea/gems.rb', line 71

def collect_iq
  @deps.dependencies
end

#executeObject

Audits depenencies using deps library and prints results using formatter library



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/chelsea/gems.rb', line 55

def execute # rubocop:disable Metrics/MethodLength
  server_response, dependencies, reverse_dependencies = audit
  if dependencies.nil?
    _print_err 'No dependencies retrieved. Exiting.'
    return
  end
  if server_response.nil?
    _print_success 'No vulnerability data retrieved from server. Exiting.'
    return
  end
  results = @formatter.fetch_results(server_response, reverse_dependencies)
  @formatter.do_print(results)

  server_response.map { |r| r['vulnerabilities'].length.positive? }.any?
end