chelsea 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +3 -0
- data/.gitignore +1 -0
- data/Gemfile.lock +5 -3
- data/bin/chelsea +1 -0
- data/chelsea.gemspec +2 -1
- data/lib/chelsea/bom.rb +11 -4
- data/lib/chelsea/cli.rb +26 -6
- data/lib/chelsea/config.rb +5 -3
- data/lib/chelsea/db.rb +9 -0
- data/lib/chelsea/deps.rb +10 -7
- data/lib/chelsea/formatters/text.rb +27 -3
- data/lib/chelsea/gems.rb +27 -26
- data/lib/chelsea/iq_client.rb +95 -9
- data/lib/chelsea/oss_index.rb +8 -3
- data/lib/chelsea/spinner.rb +21 -0
- data/lib/chelsea/version.rb +1 -1
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51aa180ab06d876ef21c119a2127745fb903c219c812e314cb526cc686b765fd
|
4
|
+
data.tar.gz: 279d57c44b27fefb84815357e31db7b0ff2cbdbb0a65ffcd8c1332dc8bacd60e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4839db5a475789889a93a0e0f7e3e9ef79800dbdfee4b04001e0054607fa85127ebec6eadbb23d8870b217437559cc2c756c764a0f4993eb62831619c71002f2
|
7
|
+
data.tar.gz: 8905197d67b7909227c64fb943425e1493287bf60568a78aa4a0124c0e05e7bb1433744defde88934608e6476c781669567bb84166c558a59f38e67c95def91b
|
data/.circleci/config.yml
CHANGED
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
chelsea (0.0.
|
4
|
+
chelsea (0.0.11)
|
5
5
|
bundler (>= 1.2.0, < 3)
|
6
6
|
ox (~> 2.13.2)
|
7
7
|
pastel (~> 0.7.2)
|
@@ -15,6 +15,7 @@ GEM
|
|
15
15
|
specs:
|
16
16
|
addressable (2.7.0)
|
17
17
|
public_suffix (>= 2.0.2, < 5.0)
|
18
|
+
byebug (11.1.2)
|
18
19
|
crack (0.4.3)
|
19
20
|
safe_yaml (~> 1.0.0)
|
20
21
|
diff-lcs (1.3)
|
@@ -33,7 +34,7 @@ GEM
|
|
33
34
|
equatable (~> 0.6)
|
34
35
|
tty-color (~> 0.5)
|
35
36
|
public_suffix (4.0.3)
|
36
|
-
rake (
|
37
|
+
rake (12.3.3)
|
37
38
|
rest-client (2.0.2)
|
38
39
|
http-cookie (>= 1.0.2, < 2.0)
|
39
40
|
mime-types (>= 1.16, < 4.0)
|
@@ -72,8 +73,9 @@ PLATFORMS
|
|
72
73
|
ruby
|
73
74
|
|
74
75
|
DEPENDENCIES
|
76
|
+
byebug (~> 11.1.2)
|
75
77
|
chelsea!
|
76
|
-
rake (~>
|
78
|
+
rake (~> 12.3)
|
77
79
|
rspec (~> 3.0)
|
78
80
|
rspec_junit_formatter (~> 0.4.1)
|
79
81
|
webmock (~> 3.8.3)
|
data/bin/chelsea
CHANGED
@@ -6,6 +6,7 @@ opts =
|
|
6
6
|
begin
|
7
7
|
Slop.parse do |o|
|
8
8
|
o.string '-f', '--file', 'Path to your Gemfile.lock'
|
9
|
+
o.bool '-x', '--clear', 'Clear OSS Index cache'
|
9
10
|
o.bool '-c', '--config', 'Set persistent config for OSS Index'
|
10
11
|
o.string '-u', '--user', 'Specify OSS Index Username'
|
11
12
|
o.string '-p', '--token', 'Specify OSS Index API Token'
|
data/chelsea.gemspec
CHANGED
@@ -43,8 +43,9 @@ Gem::Specification.new do |spec|
|
|
43
43
|
spec.add_dependency "bundler", ">= 1.2.0", "< 3"
|
44
44
|
spec.add_dependency "ox", "~> 2.13.2"
|
45
45
|
|
46
|
-
spec.add_development_dependency "rake", "~>
|
46
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
47
47
|
spec.add_development_dependency "rspec", "~> 3.0"
|
48
48
|
spec.add_development_dependency "rspec_junit_formatter", "~> 0.4.1"
|
49
49
|
spec.add_development_dependency "webmock", "~> 3.8.3"
|
50
|
+
spec.add_development_dependency "byebug", "~> 11.1.2"
|
50
51
|
end
|
data/lib/chelsea/bom.rb
CHANGED
@@ -4,16 +4,23 @@ require 'securerandom'
|
|
4
4
|
require 'ox'
|
5
5
|
|
6
6
|
module Chelsea
|
7
|
-
# Class to
|
7
|
+
# Class to convert dependencies to SBOM xml
|
8
8
|
class Bom
|
9
|
-
attr_accessor :xml
|
10
9
|
def initialize(dependencies)
|
11
10
|
@dependencies = dependencies
|
12
|
-
|
11
|
+
end
|
12
|
+
|
13
|
+
def collect
|
14
|
+
xml
|
15
|
+
to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def xml
|
19
|
+
@xml ||= _get_xml
|
13
20
|
end
|
14
21
|
|
15
22
|
def to_s
|
16
|
-
Ox.dump(@xml)
|
23
|
+
Ox.dump(@xml)
|
17
24
|
end
|
18
25
|
|
19
26
|
def random_urn_uuid
|
data/lib/chelsea/cli.rb
CHANGED
@@ -21,9 +21,15 @@ module Chelsea
|
|
21
21
|
def process!
|
22
22
|
if @opts.config?
|
23
23
|
_set_config # move to init
|
24
|
-
elsif @opts.
|
25
|
-
|
26
|
-
|
24
|
+
elsif @opts.clear?
|
25
|
+
require_relative 'db'
|
26
|
+
Chelsea::DB.new().clear_cache
|
27
|
+
puts "OSS Index cache cleared"
|
28
|
+
elsif @opts.file? && @opts.iq?
|
29
|
+
dependencies = _process_file_iq
|
30
|
+
_submit_sbom(dependencies)
|
31
|
+
elsif @opts.file?
|
32
|
+
_process_file
|
27
33
|
elsif @opts.help? # quit on opts.help earlier
|
28
34
|
puts _cli_flags # this doesn't exist
|
29
35
|
end
|
@@ -44,8 +50,13 @@ module Chelsea
|
|
44
50
|
auth_token: @opts[:iqpass]
|
45
51
|
}
|
46
52
|
)
|
47
|
-
bom = Chelsea::Bom.new(gems.deps.dependencies)
|
48
|
-
|
53
|
+
bom = Chelsea::Bom.new(gems.deps.dependencies).collect
|
54
|
+
|
55
|
+
status_url = iq.post_sbom(bom)
|
56
|
+
|
57
|
+
return unless status_url
|
58
|
+
|
59
|
+
iq.poll_status(status_url)
|
49
60
|
end
|
50
61
|
|
51
62
|
def _process_file
|
@@ -54,7 +65,16 @@ module Chelsea
|
|
54
65
|
quiet: @opts[:quiet],
|
55
66
|
options: @opts
|
56
67
|
)
|
57
|
-
gems.execute
|
68
|
+
gems.execute ? (exit 1) : (exit 0)
|
69
|
+
end
|
70
|
+
|
71
|
+
def _process_file_iq
|
72
|
+
gems = Chelsea::Gems.new(
|
73
|
+
file: @opts[:file],
|
74
|
+
quiet: @opts[:quiet],
|
75
|
+
options: @opts
|
76
|
+
)
|
77
|
+
gems.collect_iq
|
58
78
|
gems
|
59
79
|
end
|
60
80
|
|
data/lib/chelsea/config.rb
CHANGED
@@ -12,11 +12,13 @@ module Chelsea
|
|
12
12
|
def self.config(options = {})
|
13
13
|
if !options[:user].nil? && !options[:token].nil?
|
14
14
|
Chelsea::OSSIndex.new(
|
15
|
-
|
16
|
-
|
15
|
+
options: {
|
16
|
+
oss_index_user_name: options[:user],
|
17
|
+
oss_index_user_token: options[:token]
|
18
|
+
}
|
17
19
|
)
|
18
20
|
else
|
19
|
-
Chelsea::OSSIndex.new(oss_index_config)
|
21
|
+
Chelsea::OSSIndex.new(options: oss_index_config)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
data/lib/chelsea/db.rb
CHANGED
@@ -20,6 +20,15 @@ module Chelsea
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
# This method will delete all values in the pstore db
|
24
|
+
def clear_cache
|
25
|
+
@store.transaction do
|
26
|
+
@store.roots.each do |root|
|
27
|
+
@store.delete(root)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
23
32
|
def _get_db_store_location()
|
24
33
|
initial_path = File.join(Dir.home.to_s, '.ossindex')
|
25
34
|
Dir.mkdir(initial_path) unless File.exist? initial_path
|
data/lib/chelsea/deps.rb
CHANGED
@@ -5,9 +5,6 @@ require 'rubygems/commands/dependency_command'
|
|
5
5
|
require 'json'
|
6
6
|
require 'rest-client'
|
7
7
|
|
8
|
-
require_relative 'dependency_exception'
|
9
|
-
require_relative 'oss_index'
|
10
|
-
|
11
8
|
module Chelsea
|
12
9
|
class Deps
|
13
10
|
def initialize(path:, quiet: false)
|
@@ -38,11 +35,17 @@ module Chelsea
|
|
38
35
|
reverse = Gem::Commands::DependencyCommand.new
|
39
36
|
reverse.options[:reverse_dependencies] = true
|
40
37
|
# We want to filter the reverses dependencies by specs in lockfile
|
41
|
-
spec_names = @lockfile.specs.map { |i| i.to_s.split }.map
|
42
|
-
|
43
|
-
# Add filtering if version meets range
|
44
|
-
reverse_dep.select { |name, dep, req, _| spec_names.include?(name.split("-")[0]) }
|
38
|
+
spec_names = @lockfile.specs.map { |i| i.to_s.split }.map do |n, _v|
|
39
|
+
n.to_s
|
45
40
|
end
|
41
|
+
reverse
|
42
|
+
.reverse_dependencies(@lockfile.specs)
|
43
|
+
.to_h
|
44
|
+
.transform_values do |reverse_dep|
|
45
|
+
reverse_dep.select do |name, _dep, _req, _|
|
46
|
+
spec_names.include?(name.split('-')[0])
|
47
|
+
end
|
48
|
+
end
|
46
49
|
end
|
47
50
|
|
48
51
|
# Iterates over all dependencies and stores them
|
@@ -18,6 +18,8 @@ module Chelsea
|
|
18
18
|
|
19
19
|
i = 0
|
20
20
|
count = server_response.count()
|
21
|
+
server_response.sort! {|x| x['vulnerabilities'].count}
|
22
|
+
|
21
23
|
server_response.each do |r|
|
22
24
|
i += 1
|
23
25
|
package = r['coordinates']
|
@@ -29,8 +31,8 @@ module Chelsea
|
|
29
31
|
if vulnerable
|
30
32
|
response += @pastel.red("[#{i}/#{count}] - #{package} ") + @pastel.red.bold("Vulnerable.\n")
|
31
33
|
response += _get_reverse_deps(reverse_deps, name) if reverse_deps
|
32
|
-
r['vulnerabilities'].each do |k,
|
33
|
-
response += _format_vuln(
|
34
|
+
r['vulnerabilities'].each do |k, _|
|
35
|
+
response += _format_vuln(k)
|
34
36
|
end
|
35
37
|
else
|
36
38
|
if !@quiet
|
@@ -48,7 +50,29 @@ module Chelsea
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def _format_vuln(vuln)
|
51
|
-
|
53
|
+
cvssScore = vuln['cvssScore']
|
54
|
+
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")
|
62
|
+
vuln_response
|
63
|
+
end
|
64
|
+
|
65
|
+
def _color_based_on_cvss_score(cvssScore, text)
|
66
|
+
case cvssScore
|
67
|
+
when 0..3
|
68
|
+
@pastel.cyan.bold(text)
|
69
|
+
when 4..5
|
70
|
+
@pastel.yellow.bold(text)
|
71
|
+
when 6..7
|
72
|
+
@pastel.orange.bold(text)
|
73
|
+
else
|
74
|
+
@pastel.red.bold(text)
|
75
|
+
end
|
52
76
|
end
|
53
77
|
|
54
78
|
def _get_reverse_deps(coords, name)
|
data/lib/chelsea/gems.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'pastel'
|
3
|
-
require 'tty-spinner'
|
4
3
|
require 'bundler'
|
5
4
|
require 'bundler/lockfile_parser'
|
6
5
|
require 'rubygems'
|
@@ -10,21 +9,27 @@ require_relative 'version'
|
|
10
9
|
require_relative 'formatters/factory'
|
11
10
|
require_relative 'deps'
|
12
11
|
require_relative 'bom'
|
12
|
+
require_relative 'spinner'
|
13
13
|
|
14
14
|
module Chelsea
|
15
|
+
# Class to collect and audit packages from a Gemfile.lock
|
15
16
|
class Gems
|
16
17
|
attr_accessor :deps
|
17
|
-
def initialize(file:, quiet: false, options: {'format': 'text'})
|
18
|
+
def initialize(file:, quiet: false, options: { 'format': 'text' })
|
18
19
|
@quiet = quiet
|
19
20
|
unless File.file?(file) || file.nil?
|
20
21
|
raise 'Gemfile.lock not found, check --file path'
|
21
22
|
end
|
23
|
+
|
22
24
|
_silence_stderr if @quiet
|
23
25
|
|
24
26
|
@pastel = Pastel.new
|
25
|
-
@formatter = FormatterFactory.new.get_formatter(
|
27
|
+
@formatter = FormatterFactory.new.get_formatter(
|
28
|
+
format: options[:format],
|
29
|
+
quiet: @quiet)
|
26
30
|
@client = Chelsea.client(options)
|
27
31
|
@deps = Chelsea::Deps.new(path: Pathname.new(file))
|
32
|
+
@spinner = Chelsea::Spinner.new
|
28
33
|
end
|
29
34
|
|
30
35
|
# Audits depenencies using deps library and prints results
|
@@ -42,6 +47,13 @@ module Chelsea
|
|
42
47
|
end
|
43
48
|
results = @formatter.get_results(server_response, reverse_dependencies)
|
44
49
|
@formatter.do_print(results)
|
50
|
+
|
51
|
+
server_response.map { |r| r['vulnerabilities'].length.positive? }.any?
|
52
|
+
end
|
53
|
+
|
54
|
+
def collect_iq
|
55
|
+
dependencies = @deps.dependencies
|
56
|
+
dependencies
|
45
57
|
end
|
46
58
|
|
47
59
|
# Runs through auditing algorithm, raising exceptions
|
@@ -50,40 +62,40 @@ module Chelsea
|
|
50
62
|
# This spinner management is out of control
|
51
63
|
# we should wrap a block with start and stop messages,
|
52
64
|
# or use a stack to ensure all spinners stop.
|
53
|
-
|
65
|
+
spin = @spinner.spin_msg 'Parsing dependencies'
|
54
66
|
|
55
67
|
begin
|
56
68
|
dependencies = @deps.dependencies
|
57
|
-
|
69
|
+
spin.success('...done.')
|
58
70
|
rescue StandardError => e
|
59
|
-
|
71
|
+
spin.stop
|
60
72
|
_print_err "Parsing dependency line #{gem} failed."
|
61
73
|
end
|
62
74
|
|
63
75
|
reverse_dependencies = @deps.reverse_dependencies
|
64
76
|
|
65
|
-
|
77
|
+
spin = @spinner.spin_msg 'Parsing Versions'
|
66
78
|
coordinates = @deps.coordinates
|
67
|
-
|
68
|
-
|
79
|
+
spin.success('...done.')
|
80
|
+
spin = @spinner.spin_msg 'Making request to OSS Index server'
|
69
81
|
|
70
82
|
begin
|
71
83
|
server_response = @client.get_vulns(coordinates)
|
72
|
-
|
84
|
+
spin.success('...done.')
|
73
85
|
rescue SocketError => e
|
74
|
-
|
86
|
+
spin.stop('...request failed.')
|
75
87
|
_print_err 'Socket error getting data from OSS Index server.'
|
76
88
|
rescue RestClient::RequestFailed => e
|
77
|
-
|
89
|
+
spin.stop('...request failed.')
|
78
90
|
_print_err "Error getting data from OSS Index server:#{e.response}."
|
79
91
|
rescue RestClient::ResourceNotFound => e
|
80
|
-
|
92
|
+
spin.stop('...request failed.')
|
81
93
|
_print_err 'Error getting data from OSS Index server. Resource not found.'
|
82
94
|
rescue Errno::ECONNREFUSED => e
|
83
|
-
|
95
|
+
spin.stop('...request failed.')
|
84
96
|
_print_err 'Error getting data from OSS Index server. Connection refused.'
|
85
97
|
rescue StandardError => e
|
86
|
-
|
98
|
+
spin.stop('...request failed.')
|
87
99
|
_print_err 'UNKNOWN Error getting data from OSS Index server.'
|
88
100
|
end
|
89
101
|
[server_response, dependencies, reverse_dependencies]
|
@@ -95,17 +107,6 @@ module Chelsea
|
|
95
107
|
$stderr.reopen('/dev/null', 'w')
|
96
108
|
end
|
97
109
|
|
98
|
-
def _spin_msg(msg)
|
99
|
-
format = "[#{@pastel.green(':spinner')}] " + @pastel.white(msg)
|
100
|
-
spinner = TTY::Spinner.new(
|
101
|
-
format,
|
102
|
-
success_mark: @pastel.green('+'),
|
103
|
-
hide_cursor: true
|
104
|
-
)
|
105
|
-
spinner.auto_spin
|
106
|
-
spinner
|
107
|
-
end
|
108
|
-
|
109
110
|
def _print_err(s)
|
110
111
|
puts @pastel.red.bold(s)
|
111
112
|
end
|
data/lib/chelsea/iq_client.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'rest-client'
|
2
2
|
require 'json'
|
3
|
+
require 'pastel'
|
4
|
+
|
5
|
+
require_relative 'spinner'
|
3
6
|
|
4
7
|
module Chelsea
|
5
8
|
class IQClient
|
9
|
+
|
6
10
|
DEFAULT_OPTIONS = {
|
7
11
|
public_application_id: 'testapp',
|
8
12
|
server_url: 'http://localhost:8070',
|
@@ -12,17 +16,26 @@ module Chelsea
|
|
12
16
|
}
|
13
17
|
def initialize(options: DEFAULT_OPTIONS)
|
14
18
|
@options = options
|
19
|
+
@pastel = Pastel.new
|
20
|
+
@spinner = Chelsea::Spinner.new
|
15
21
|
end
|
16
22
|
|
17
|
-
def
|
18
|
-
|
23
|
+
def post_sbom(sbom)
|
24
|
+
spin = @spinner.spin_msg "Submitting sbom to Nexus IQ Server"
|
25
|
+
@internal_application_id = _get_internal_application_id
|
19
26
|
resource = RestClient::Resource.new(
|
20
27
|
_api_url,
|
21
28
|
user: @options[:username],
|
22
29
|
password: @options[:auth_token]
|
23
30
|
)
|
24
|
-
|
25
|
-
|
31
|
+
res = resource.post sbom.to_s, _headers.merge(content_type: 'application/xml')
|
32
|
+
unless res.code != 202
|
33
|
+
spin.success("...done.")
|
34
|
+
status_url(res)
|
35
|
+
else
|
36
|
+
spin.stop('...request failed.')
|
37
|
+
nil
|
38
|
+
end
|
26
39
|
end
|
27
40
|
|
28
41
|
def status_url(res)
|
@@ -30,16 +43,89 @@ module Chelsea
|
|
30
43
|
res['statusUrl']
|
31
44
|
end
|
32
45
|
|
46
|
+
def poll_status(url)
|
47
|
+
spin = @spinner.spin_msg "Polling Nexus IQ Server for results"
|
48
|
+
loop do
|
49
|
+
begin
|
50
|
+
res = _poll_iq_server(url)
|
51
|
+
if res.code == 200
|
52
|
+
spin.success("...done.")
|
53
|
+
_handle_response(res)
|
54
|
+
break
|
55
|
+
end
|
56
|
+
rescue
|
57
|
+
sleep(1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
33
62
|
private
|
34
63
|
|
64
|
+
def _handle_response(res)
|
65
|
+
res = JSON.parse(res.body)
|
66
|
+
unless res['policyAction'] == 'Failure'
|
67
|
+
puts @pastel.white.bold("Hi! Chelsea here, no policy violations for this audit!")
|
68
|
+
puts @pastel.white.bold("Report URL: #{res['reportHtmlUrl']}")
|
69
|
+
exit 0
|
70
|
+
else
|
71
|
+
puts @pastel.red.bold("Hi! Chelsea here, you have some policy violations to clean up!")
|
72
|
+
puts @pastel.red.bold("Report URL: #{res['reportHtmlUrl']}")
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def _poll_iq_server(status_url)
|
78
|
+
resource = RestClient::Resource.new(
|
79
|
+
"#{@options[:server_url]}/#{status_url}",
|
80
|
+
user: @options[:username],
|
81
|
+
password: @options[:auth_token]
|
82
|
+
)
|
83
|
+
|
84
|
+
resource.get _headers
|
85
|
+
end
|
86
|
+
|
87
|
+
def status(status_url)
|
88
|
+
resource = RestClient::Resource.new(
|
89
|
+
"#{@options[:server_url]}/#{status_url}",
|
90
|
+
user: @options[:username],
|
91
|
+
password: @options[:auth_token]
|
92
|
+
)
|
93
|
+
resource.get _headers
|
94
|
+
end
|
95
|
+
|
96
|
+
def _status_url(res)
|
97
|
+
res = JSON.parse(res.body)
|
98
|
+
res['statusUrl']
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def _poll_status
|
104
|
+
return unless @status_url
|
105
|
+
|
106
|
+
loop do
|
107
|
+
begin
|
108
|
+
res = check_status(@status_url)
|
109
|
+
if res.code == 200
|
110
|
+
puts JSON.parse(res.body)
|
111
|
+
break
|
112
|
+
end
|
113
|
+
rescue RestClient::ResourceNotFound => _e
|
114
|
+
print '.'
|
115
|
+
sleep(1)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
35
120
|
def _get_internal_application_id
|
36
121
|
resource = RestClient::Resource.new(
|
37
122
|
_internal_application_id_api_url,
|
38
|
-
user: @username,
|
39
|
-
password: @auth_token
|
123
|
+
user: @options[:username],
|
124
|
+
password: @options[:auth_token]
|
40
125
|
)
|
41
|
-
res =
|
42
|
-
res
|
126
|
+
res = resource.get _headers
|
127
|
+
body = JSON.parse(res)
|
128
|
+
body['applications'][0]['id']
|
43
129
|
end
|
44
130
|
|
45
131
|
def _headers
|
@@ -47,7 +133,7 @@ module Chelsea
|
|
47
133
|
end
|
48
134
|
|
49
135
|
def _api_url
|
50
|
-
"#{@options[:server_url]}/api/v2/scan/applications/#{
|
136
|
+
"#{@options[:server_url]}/api/v2/scan/applications/#{@internal_application_id}/sources/chelsea"
|
51
137
|
end
|
52
138
|
|
53
139
|
def _internal_application_id_api_url
|
data/lib/chelsea/oss_index.rb
CHANGED
@@ -6,9 +6,13 @@ require_relative 'db'
|
|
6
6
|
|
7
7
|
module Chelsea
|
8
8
|
class OSSIndex
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
oss_index_username: '',
|
11
|
+
oss_index_user_token: ''
|
12
|
+
}
|
13
|
+
def initialize(options: DEFAULT_OPTIONS)
|
14
|
+
@oss_index_user_name = options[:oss_index_user_name]
|
15
|
+
@oss_index_user_token = options[:oss_index_user_token]
|
12
16
|
@db = DB.new
|
13
17
|
end
|
14
18
|
|
@@ -26,6 +30,7 @@ module Chelsea
|
|
26
30
|
cached_server_response = cached_server_response.concat(res_json)
|
27
31
|
@db.save_values_to_db(res_json)
|
28
32
|
end
|
33
|
+
|
29
34
|
cached_server_response
|
30
35
|
end
|
31
36
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'tty-spinner'
|
2
|
+
require 'pastel'
|
3
|
+
|
4
|
+
module Chelsea
|
5
|
+
class Spinner
|
6
|
+
def initialize()
|
7
|
+
@pastel = Pastel.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def spin_msg(msg)
|
11
|
+
format = "[#{@pastel.green(':spinner')}] " + @pastel.white(msg)
|
12
|
+
spinner = TTY::Spinner.new(
|
13
|
+
format,
|
14
|
+
success_mark: @pastel.green('+'),
|
15
|
+
hide_cursor: true
|
16
|
+
)
|
17
|
+
spinner.auto_spin
|
18
|
+
spinner
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/chelsea/version.rb
CHANGED
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.
|
4
|
+
version: 0.0.12
|
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-
|
11
|
+
date: 2020-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-font
|
@@ -120,14 +120,14 @@ dependencies:
|
|
120
120
|
requirements:
|
121
121
|
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version: '
|
123
|
+
version: '12.3'
|
124
124
|
type: :development
|
125
125
|
prerelease: false
|
126
126
|
version_requirements: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
128
|
- - "~>"
|
129
129
|
- !ruby/object:Gem::Version
|
130
|
-
version: '
|
130
|
+
version: '12.3'
|
131
131
|
- !ruby/object:Gem::Dependency
|
132
132
|
name: rspec
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,6 +170,20 @@ dependencies:
|
|
170
170
|
- - "~>"
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: 3.8.3
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: byebug
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - "~>"
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: 11.1.2
|
180
|
+
type: :development
|
181
|
+
prerelease: false
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - "~>"
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 11.1.2
|
173
187
|
description:
|
174
188
|
email:
|
175
189
|
- allister.beharry@gmail.com
|
@@ -217,6 +231,7 @@ files:
|
|
217
231
|
- lib/chelsea/gems.rb
|
218
232
|
- lib/chelsea/iq_client.rb
|
219
233
|
- lib/chelsea/oss_index.rb
|
234
|
+
- lib/chelsea/spinner.rb
|
220
235
|
- lib/chelsea/version.rb
|
221
236
|
homepage: https://github.com/sonatype-nexus-community/chelsea
|
222
237
|
licenses:
|