chelsea 0.0.14 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,47 +1,68 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  require 'pastel'
18
+ require 'tty-table'
2
19
  require_relative 'formatter'
3
20
 
4
21
  module Chelsea
5
22
  class TextFormatter < Formatter
6
- def initialize(quiet: false)
7
- @quiet = quiet
23
+ def initialize(options)
24
+ @options = options
8
25
  @pastel = Pastel.new
9
26
  end
10
27
 
11
28
  def get_results(server_response, reverse_dependencies)
12
- response = String.new
13
- if !@quiet
29
+ response = ''
30
+ if @options[:verbose]
14
31
  response += "\n"\
15
32
  "Audit Results\n"\
16
33
  "=============\n"
17
34
  end
18
35
 
19
- i = 0
20
- count = server_response.count()
21
- server_response.sort! {|x| x['vulnerabilities'].count}
22
-
23
- server_response.each do |r|
24
- i += 1
25
- package = r['coordinates']
26
- vulnerable = r['vulnerabilities'].length.positive?
27
- coord = r['coordinates'].sub('pkg:gem/', '')
28
- name = coord.split('@')[0]
29
- version = coord.split('@')[1]
36
+ vuln_count = server_response.count do |vuln|
37
+ vuln['vulnerabilities'].length.positive?
38
+ end
39
+ server_response.sort! { |x| x['vulnerabilities'].count }
40
+ server_response.each.with_index do |r, idx|
41
+ name, version = r['coordinates'].sub('pkg:gem/', '').split('@')
30
42
  reverse_deps = reverse_dependencies["#{name}-#{version}"]
31
- if vulnerable
32
- response += @pastel.red("[#{i}/#{count}] - #{package} ") + @pastel.red.bold("Vulnerable.\n")
43
+ if r['vulnerabilities'].length.positive?
44
+ response += @pastel.red(
45
+ "[#{idx}/#{server_response.count}] - #{r['coordinates']} "
46
+ )
47
+ response += @pastel.red.bold("Vulnerable.\n")
33
48
  response += _get_reverse_deps(reverse_deps, name) if reverse_deps
34
49
  r['vulnerabilities'].each do |k, _|
35
50
  response += _format_vuln(k)
36
51
  end
37
- else
38
- if !@quiet
39
- response += @pastel.white("[#{i}/#{count}] - #{package} ") + @pastel.green.bold("No vulnerabilities found!\n")
40
- response += _get_reverse_deps(reverse_deps, name) if reverse_deps
41
- end
52
+ elsif @options[:verbose]
53
+ response += @pastel.white(
54
+ "[#{idx}/#{server_response.count}] - #{r['coordinates']} "
55
+ )
56
+ response += @pastel.green.bold("No vulnerabilities found!\n")
57
+ response += _get_reverse_deps(reverse_deps, name) if reverse_deps
42
58
  end
43
59
  end
44
60
 
61
+ table = TTY::Table.new(
62
+ ['Dependencies Audited', 'Vulnerable Dependencies'],
63
+ [[server_response.count, vuln_count]]
64
+ )
65
+ response += table.render(:unicode)
45
66
  response
46
67
  end
47
68
 
@@ -49,34 +70,44 @@ module Chelsea
49
70
  puts results
50
71
  end
51
72
 
73
+ private
74
+
52
75
  def _format_vuln(vuln)
53
- cvssScore = vuln['cvssScore']
54
76
  vuln_response = "\n\tVulnerability Details:\n"
55
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tID: #{vuln['id']}\n")
56
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tTitle: #{vuln['title']}\n")
57
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tDescription: #{vuln['description']}\n")
58
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tCVSS Score: #{vuln['cvssScore']}\n")
59
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tCVSS Vector: #{vuln['cvssVector']}\n")
60
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tCVE: #{vuln['cve']}\n")
61
- vuln_response += _color_based_on_cvss_score(cvssScore, "\n\tReference: #{vuln['reference']}\n\n")
77
+ _color_method = _color_based_on_cvss_score(vuln['cvssScore'])
78
+ _report_lines(vuln).each do |line|
79
+ vuln_response += _color_method(line)
80
+ end
62
81
  vuln_response
63
82
  end
64
83
 
65
- def _color_based_on_cvss_score(cvssScore, text)
66
- case cvssScore
84
+ def _report_lines(vuln)
85
+ [
86
+ "\n\tID: #{vuln['id']}\n",
87
+ "\n\tTitle: #{vuln['title']}\n",
88
+ "\n\tDescription: #{vuln['description']}\n",
89
+ "\n\tCVSS Score: #{vuln['cvssScore']}\n",
90
+ "\n\tCVSS Vector: #{vuln['cvssVector']}\n",
91
+ "\n\tCVE: #{vuln['cve']}\n",
92
+ "\n\tReference: #{vuln['reference']}\n\n"
93
+ ]
94
+ end
95
+
96
+ def _color_based_on_cvss_score(cvss_score)
97
+ case cvss_score
67
98
  when 0..3
68
- @pastel.cyan.bold(text)
99
+ @pastel.cyan.bold
69
100
  when 4..5
70
- @pastel.yellow.bold(text)
101
+ @pastel.yellow.bold
71
102
  when 6..7
72
- @pastel.orange.bold(text)
103
+ @pastel.orange.bold
73
104
  else
74
- @pastel.red.bold(text)
105
+ @pastel.red.bold
75
106
  end
76
107
  end
77
108
 
78
109
  def _get_reverse_deps(coords, name)
79
- coords.each_with_object(String.new) do |dep, s|
110
+ coords.each_with_object('') do |dep, s|
80
111
  dep.each do |gran|
81
112
  if gran.class == String && !gran.include?(name)
82
113
  s << "\tRequired by: #{gran}\n"
@@ -1,3 +1,19 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  require 'ox'
2
18
  require_relative 'formatter'
3
19
  module Chelsea
@@ -15,8 +31,8 @@ module Chelsea
15
31
  doc << instruct
16
32
 
17
33
  testsuite = Ox::Element.new('testsuite')
18
- testsuite[:name] = "purl"
19
- testsuite[:tests] = server_response.count()
34
+ testsuite[:name] = 'purl'
35
+ testsuite[:tests] = server_response.count
20
36
  doc << testsuite
21
37
 
22
38
  server_response.each do |coord|
@@ -24,14 +40,15 @@ module Chelsea
24
40
  testcase[:classname] = coord["coordinates"]
25
41
  testcase[:name] = coord["coordinates"]
26
42
 
27
- if coord["vulnerabilities"].length() > 0
43
+ if coord['vulnerabilities'].length.positive?
28
44
  failure = Ox::Element.new('failure')
29
45
  failure[:type] = "Vulnerable Dependency"
30
46
  failure << get_vulnerability_block(coord["vulnerabilities"])
31
47
  testcase << failure
48
+ testsuite << testcase
49
+ elsif @options[:verbose]
50
+ testsuite << testcase
32
51
  end
33
-
34
- testsuite << testcase
35
52
  end
36
53
 
37
54
  doc
@@ -1,3 +1,19 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  # frozen_string_literal: true
2
18
  require 'pastel'
3
19
  require 'bundler'
@@ -15,18 +31,19 @@ module Chelsea
15
31
  # Class to collect and audit packages from a Gemfile.lock
16
32
  class Gems
17
33
  attr_accessor :deps
18
- def initialize(file:, quiet: false, options: { 'format': 'text' })
19
- @quiet = quiet
34
+ def initialize(file:, verbose:, options: { 'format': 'text' })
35
+ @verbose = verbose
20
36
  unless File.file?(file) || file.nil?
21
37
  raise 'Gemfile.lock not found, check --file path'
22
38
  end
23
39
 
24
- _silence_stderr if @quiet
40
+ _silence_stderr unless @verbose
25
41
 
26
42
  @pastel = Pastel.new
27
43
  @formatter = FormatterFactory.new.get_formatter(
28
44
  format: options[:format],
29
- quiet: @quiet)
45
+ verbose: verbose
46
+ )
30
47
  @client = Chelsea.client(options)
31
48
  @deps = Chelsea::Deps.new(path: Pathname.new(file))
32
49
  @spinner = Chelsea::Spinner.new
@@ -42,7 +59,7 @@ module Chelsea
42
59
  return
43
60
  end
44
61
  if server_response.nil?
45
- _print_err 'No vulnerability data retrieved from server. Exiting.'
62
+ _print_success 'No vulnerability data retrieved from server. Exiting.'
46
63
  return
47
64
  end
48
65
  results = @formatter.get_results(server_response, reverse_dependencies)
@@ -78,6 +95,7 @@ module Chelsea
78
95
  coordinates = @deps.coordinates
79
96
  spin.success('...done.')
80
97
  spin = @spinner.spin_msg 'Making request to OSS Index server'
98
+ spin.stop
81
99
 
82
100
  begin
83
101
  server_response = @client.get_vulns(coordinates)
@@ -94,9 +112,6 @@ module Chelsea
94
112
  rescue Errno::ECONNREFUSED => e
95
113
  spin.stop('...request failed.')
96
114
  _print_err 'Error getting data from OSS Index server. Connection refused.'
97
- rescue StandardError => e
98
- spin.stop('...request failed.')
99
- _print_err 'UNKNOWN Error getting data from OSS Index server.'
100
115
  end
101
116
  [server_response, dependencies, reverse_dependencies]
102
117
  end
@@ -1,3 +1,19 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  require 'rest-client'
2
18
  require 'json'
3
19
  require 'pastel'
@@ -1,3 +1,19 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  # frozen_string_literal: true
2
18
 
3
19
  require_relative 'config'
@@ -26,7 +42,7 @@ module Chelsea
26
42
  end
27
43
 
28
44
  remaining_coordinates['coordinates'].each_slice(128).to_a.each do |coords|
29
- res_json = call_oss_index({ 'coordinates' => coords })
45
+ res_json = JSON.parse(call_oss_index({ 'coordinates' => coords }))
30
46
  cached_server_response = cached_server_response.concat(res_json)
31
47
  @db.save_values_to_db(res_json)
32
48
  end
@@ -36,7 +52,7 @@ module Chelsea
36
52
 
37
53
  def call_oss_index(coords)
38
54
  r = _resource.post coords.to_json, _headers
39
- r.code == 200 ? JSON.parse(r.body) : {}
55
+ r.code == 200 ? r.body : {}
40
56
  end
41
57
 
42
58
  private
@@ -67,7 +83,7 @@ module Chelsea
67
83
  password: @oss_index_user_token
68
84
  )
69
85
  else
70
- RestClient::Resource.new _api_url
86
+ RestClient::Resource.new(_api_url)
71
87
  end
72
88
  end
73
89
 
@@ -1,3 +1,19 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  require 'tty-spinner'
2
18
  require 'pastel'
3
19
 
@@ -1,3 +1,19 @@
1
+ #
2
+ # Copyright 2019-Present Sonatype Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
1
17
  module Chelsea
2
- VERSION = '0.0.14'.freeze
18
+ VERSION = '0.0.19'.freeze
3
19
  end
@@ -0,0 +1,12 @@
1
+ <excludes>
2
+ <exclude>src/.circleci/circleci-readme.md</exclude>
3
+ <exclude>src/.github/**</exclude>
4
+ <exclude>src/.vscode/**</exclude>
5
+ <exclude>src/Gemfile</exclude>
6
+ <exclude>src/Gemfile.lock</exclude>
7
+ <exclude>src/.rspec</exclude>
8
+ <exclude>src/spec/testdata/**</exclude>
9
+ <exclude>src/chelsea.gemspec</exclude>
10
+ <exclude>src/CODE_OF_CONDUCT.md</exclude>
11
+ <exclude>src/CONTRIBUTORS.md</exclude>
12
+ </excludes>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chelsea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allister Beharry
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-22 00:00:00.000000000 Z
11
+ date: 2020-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-font
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: 2.13.2
117
+ - !ruby/object:Gem::Dependency
118
+ name: tty-table
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 0.11.0
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 0.11.0
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: rake
119
133
  requirement: !ruby/object:Gem::Requirement
@@ -184,6 +198,20 @@ dependencies:
184
198
  - - "~>"
185
199
  - !ruby/object:Gem::Version
186
200
  version: 11.1.2
201
+ - !ruby/object:Gem::Dependency
202
+ name: pry
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
187
215
  description:
188
216
  email:
189
217
  - allister.beharry@gmail.com
@@ -206,9 +234,11 @@ files:
206
234
  - ".vscode/launch.json"
207
235
  - CODE_OF_CONDUCT.md
208
236
  - CONTRIBUTORS.md
237
+ - Dockerfile
209
238
  - Gemfile
210
239
  - Gemfile.lock
211
- - LICENSE.txt
240
+ - Jenkinsfile
241
+ - LICENSE
212
242
  - README.md
213
243
  - Rakefile
214
244
  - bin/chelsea
@@ -217,6 +247,7 @@ files:
217
247
  - chelsea
218
248
  - chelsea.gemspec
219
249
  - docs/images/chelsea.png
250
+ - header.txt
220
251
  - lib/chelsea.rb
221
252
  - lib/chelsea/bom.rb
222
253
  - lib/chelsea/cli.rb
@@ -234,9 +265,10 @@ files:
234
265
  - lib/chelsea/oss_index.rb
235
266
  - lib/chelsea/spinner.rb
236
267
  - lib/chelsea/version.rb
268
+ - license-excludes.xml
237
269
  homepage: https://github.com/sonatype-nexus-community/chelsea
238
270
  licenses:
239
- - MIT
271
+ - Apache-2.0
240
272
  metadata:
241
273
  homepage_uri: https://github.com/sonatype-nexus-community/chelsea
242
274
  source_code_uri: https://github.com/sonatype-nexus-community/chelsea