package-audit 0.2.0 → 0.4.0
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/lib/package/audit/cli.rb +42 -42
- data/lib/package/audit/const/cmd.rb +3 -3
- data/lib/package/audit/const/fields.rb +4 -4
- data/lib/package/audit/const/file.rb +1 -0
- data/lib/package/audit/const/yaml.rb +13 -0
- data/lib/package/audit/enum/option.rb +13 -0
- data/lib/package/audit/enum/report.rb +12 -0
- data/lib/package/audit/enum/technology.rb +14 -0
- data/lib/package/audit/formatter/risk.rb +1 -1
- data/lib/package/audit/formatter/version.rb +1 -1
- data/lib/package/audit/formatter/version_date.rb +1 -1
- data/lib/package/audit/formatter/vulnerability.rb +1 -1
- data/lib/package/audit/{package.rb → models/package.rb} +8 -7
- data/lib/package/audit/npm/node_collection.rb +25 -14
- data/lib/package/audit/npm/vulnerability_finder.rb +4 -3
- data/lib/package/audit/npm/yarn_lock_parser.rb +10 -6
- data/lib/package/audit/ruby/bundler_specs.rb +16 -9
- data/lib/package/audit/ruby/gem_collection.rb +36 -15
- data/lib/package/audit/ruby/gem_meta_data.rb +1 -1
- data/lib/package/audit/ruby/vulnerability_finder.rb +4 -3
- data/lib/package/audit/services/command_parser.rb +103 -0
- data/lib/package/audit/services/package_filter.rb +39 -0
- data/lib/package/audit/services/package_finder.rb +58 -0
- data/lib/package/audit/{printer.rb → services/package_printer.rb} +12 -11
- data/lib/package/audit/{risk_calculator.rb → services/risk_calculator.rb} +8 -4
- data/lib/package/audit/technology/detector.rb +40 -0
- data/lib/package/audit/technology/validator.rb +56 -0
- data/lib/package/audit/util/summary_printer.rb +22 -11
- data/lib/package/audit/version.rb +1 -1
- data/sig/package/audit/cli.rbs +2 -0
- data/sig/package/audit/const/fields.rbs +2 -1
- data/sig/package/audit/const/file.rbs +1 -0
- data/sig/package/audit/const/yaml.rbs +13 -0
- data/sig/package/audit/enum/option.rbs +13 -0
- data/sig/package/audit/enum/report.rbs +12 -0
- data/sig/package/audit/enum/technology.rbs +12 -0
- data/sig/package/audit/{package.rbs → models/package.rbs} +3 -1
- data/sig/package/audit/{risk.rbs → models/risk.rbs} +1 -1
- data/sig/package/audit/npm/node_collection.rbs +4 -5
- data/sig/package/audit/npm/vulnerability_finder.rbs +3 -2
- data/sig/package/audit/npm/yarn_lock_parser.rbs +1 -0
- data/sig/package/audit/ruby/bundler_specs.rbs +2 -2
- data/sig/package/audit/ruby/gem_collection.rbs +11 -4
- data/sig/package/audit/ruby/vulnerability_finder.rbs +3 -0
- data/sig/package/audit/services/command_parser.rbs +31 -0
- data/sig/package/audit/services/package_filter.rbs +19 -0
- data/sig/package/audit/services/package_finder.rbs +23 -0
- data/sig/package/audit/{printer.rbs → services/package_printer.rbs} +3 -3
- data/sig/package/audit/technology/detector.rbs +19 -0
- data/sig/package/audit/technology/validator.rbs +19 -0
- data/sig/package/audit/util/summary_printer.rbs +5 -5
- metadata +30 -14
- data/lib/package/audit/command_service.rb +0 -187
- data/sig/package/audit/command_service.rbs +0 -29
- /data/lib/package/audit/{risk.rb → models/risk.rb} +0 -0
- /data/lib/package/audit/{duplicate_package_merger.rb → services/duplicate_package_merger.rb} +0 -0
- /data/sig/package/audit/{duplicate_package_merger.rbs → services/duplicate_package_merger.rbs} +0 -0
- /data/sig/package/audit/{risk_calculator.rbs → services/risk_calculator.rbs} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d30d08ba36373c75427371f922cb0a5819a021868bf82001428e0541571df9f8
|
4
|
+
data.tar.gz: ac4dce54e3905dd56de9b137a62101de7267262c1f6b0310e4697c8f016a36b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00be4151f4f124614d117a739a558f9f2816f0f72095f222ddadf5101a6d089b40bdc5369c4a68c9b096b1547932561394f1fee5ca58712e13a4909c4a8c9558
|
7
|
+
data.tar.gz: f224c2c2fe2ff39586d20989ef6999d7b2a52acd2276dcdd9895441105ccaebc5991523676b88545a5afa96d4ffcac10291ab76dfab735b65d42aabc4598d7e4
|
data/lib/package/audit/cli.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative './ruby/gem_collection'
|
7
|
-
require_relative './npm/node_collection'
|
8
|
-
require_relative './command_service'
|
1
|
+
require_relative 'const/file'
|
2
|
+
require_relative 'const/time'
|
3
|
+
require_relative 'enum/option'
|
4
|
+
require_relative 'services/command_parser'
|
5
|
+
require_relative 'version'
|
9
6
|
|
10
7
|
require 'json'
|
11
8
|
require 'thor'
|
@@ -15,57 +12,52 @@ module Package
|
|
15
12
|
class CLI < Thor
|
16
13
|
default_task :report
|
17
14
|
|
15
|
+
class_option Enum::Option::CONFIG,
|
16
|
+
aliases: '-c', banner: 'FILE',
|
17
|
+
desc: "Path to a custom configuration file, default: #{Const::File::CONFIG})"
|
18
|
+
class_option Enum::Option::TECHNOLOGY,
|
19
|
+
aliases: '-t', repeatable: true,
|
20
|
+
desc: 'Technology to be audited (repeat this flag for each technology)'
|
21
|
+
class_option Enum::Option::INCLUDE_IGNORED,
|
22
|
+
type: :boolean, default: false,
|
23
|
+
desc: 'Include packages ignored by a configuration file'
|
24
|
+
class_option Enum::Option::CSV,
|
25
|
+
type: :boolean, default: false,
|
26
|
+
desc: 'Output reports using comma separated values (CSV)'
|
27
|
+
class_option Enum::Option::CSV_EXCLUDE_HEADERS,
|
28
|
+
type: :boolean, default: false,
|
29
|
+
desc: "Hide headers when using the --#{Enum::Option::CSV} option"
|
30
|
+
|
31
|
+
map '-v' => :version
|
18
32
|
map '--version' => :version
|
19
33
|
|
20
|
-
desc 'report', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def report
|
25
|
-
within_rescue_block do
|
26
|
-
exit CommandService.new(Dir.pwd, options).all
|
27
|
-
end
|
34
|
+
desc 'report [DIR]', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
35
|
+
def report(dir = Dir.pwd)
|
36
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::ALL).run }
|
28
37
|
end
|
29
38
|
|
30
|
-
desc 'deprecated',
|
39
|
+
desc 'deprecated [DIR]',
|
31
40
|
"Show packages with no updates by author for at least #{Const::Time::YEARS_ELAPSED_TO_BE_OUTDATED} years"
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def deprecated
|
36
|
-
within_rescue_block do
|
37
|
-
exit CommandService.new(Dir.pwd, options).deprecated
|
38
|
-
end
|
41
|
+
def deprecated(dir = Dir.pwd)
|
42
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::DEPRECATED).run }
|
39
43
|
end
|
40
44
|
|
41
|
-
desc 'outdated', 'Show packages that are out of date'
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
def outdated
|
46
|
-
within_rescue_block do
|
47
|
-
exit CommandService.new(Dir.pwd, options).outdated
|
48
|
-
end
|
45
|
+
desc 'outdated [DIR]', 'Show packages that are out of date'
|
46
|
+
def outdated(dir = Dir.pwd)
|
47
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::OUTDATED).run }
|
49
48
|
end
|
50
49
|
|
51
|
-
desc 'vulnerable', 'Show packages and their dependencies that have security vulnerabilities'
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
def vulnerable
|
56
|
-
within_rescue_block do
|
57
|
-
exit CommandService.new(Dir.pwd, options).vulnerable
|
58
|
-
end
|
50
|
+
desc 'vulnerable [DIR]', 'Show packages and their dependencies that have security vulnerabilities'
|
51
|
+
def vulnerable(dir = Dir.pwd)
|
52
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::VULNERABLE).run }
|
59
53
|
end
|
60
54
|
|
61
55
|
desc 'risk', 'Print information on how risk is calculated'
|
62
|
-
|
63
56
|
def risk
|
64
57
|
Util::SummaryPrinter.risk
|
65
58
|
end
|
66
59
|
|
67
60
|
desc 'version', 'Print the currently installed version of the package-audit gem'
|
68
|
-
|
69
61
|
def version
|
70
62
|
puts "package-audit #{VERSION}"
|
71
63
|
end
|
@@ -74,6 +66,14 @@ module Package
|
|
74
66
|
true
|
75
67
|
end
|
76
68
|
|
69
|
+
def method_missing(command, *args)
|
70
|
+
invoke :report, [command], args
|
71
|
+
end
|
72
|
+
|
73
|
+
def respond_to_missing?
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
77
|
private
|
78
78
|
|
79
79
|
def within_rescue_block
|
@@ -2,14 +2,14 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Const
|
4
4
|
module Cmd
|
5
|
-
BUNDLE_AUDIT = 'bundle
|
6
|
-
BUNDLE_AUDIT_JSON = 'bundle
|
5
|
+
BUNDLE_AUDIT = 'bundle-audit check --update'
|
6
|
+
BUNDLE_AUDIT_JSON = 'bundle-audit check --update --quiet --format json %s'
|
7
7
|
|
8
8
|
NPM_AUDIT = 'npm audit'
|
9
9
|
NPM_AUDIT_JSON = 'npm audit --json'
|
10
10
|
|
11
11
|
YARN_AUDIT = 'yarn audit'
|
12
|
-
YARN_AUDIT_JSON = 'yarn audit --json'
|
12
|
+
YARN_AUDIT_JSON = 'yarn audit --json --cwd %s'
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -2,7 +2,7 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Const
|
4
4
|
module Fields
|
5
|
-
|
5
|
+
AVAILABLE = %i[
|
6
6
|
name
|
7
7
|
version
|
8
8
|
version_date
|
@@ -14,15 +14,15 @@ module Package
|
|
14
14
|
risk_explanation
|
15
15
|
]
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
ALL = %i[name version latest_version latest_version_date groups vulnerabilities risk_type risk_explanation]
|
18
|
+
DEPRECATED = %i[name version latest_version latest_version_date groups]
|
19
19
|
OUTDATED = %i[name version latest_version latest_version_date groups]
|
20
|
+
VULNERABLE = %i[name version latest_version groups vulnerabilities]
|
20
21
|
|
21
22
|
# the names of these fields must match the instance variables in the Dependency class
|
22
23
|
HEADERS = {
|
23
24
|
name: 'Package',
|
24
25
|
version: 'Version',
|
25
|
-
version_date: 'Date',
|
26
26
|
latest_version: 'Latest',
|
27
27
|
latest_version_date: 'Latest Date',
|
28
28
|
groups: 'Groups',
|
@@ -1,18 +1,19 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
1
|
+
require_relative '../enum/environment'
|
2
|
+
require_relative '../enum/risk_explanation'
|
3
|
+
require_relative '../enum/risk_type'
|
4
|
+
require_relative '../services/risk_calculator'
|
5
|
+
require_relative 'risk'
|
6
6
|
|
7
7
|
module Package
|
8
8
|
module Audit
|
9
9
|
class Package
|
10
|
-
attr_reader :name, :version
|
10
|
+
attr_reader :name, :version, :technology
|
11
11
|
attr_accessor :groups, :version_date, :latest_version, :latest_version_date, :vulnerabilities
|
12
12
|
|
13
|
-
def initialize(name, version, **attr)
|
13
|
+
def initialize(name, version, technology, **attr)
|
14
14
|
@name = name.to_s
|
15
15
|
@version = version.to_s
|
16
|
+
@technology = technology.to_s
|
16
17
|
@groups = []
|
17
18
|
@vulnerabilities = []
|
18
19
|
@risks = []
|
@@ -1,23 +1,34 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
1
|
+
require_relative '../const/file'
|
2
|
+
require_relative '../services/duplicate_package_merger'
|
3
|
+
require_relative 'npm_meta_data'
|
4
|
+
require_relative 'vulnerability_finder'
|
5
|
+
require_relative 'yarn_lock_parser'
|
5
6
|
|
6
7
|
module Package
|
7
8
|
module Audit
|
8
9
|
module Npm
|
9
10
|
class NodeCollection
|
10
|
-
|
11
|
-
PACKAGE_LOCK = 'package-lock.json'
|
12
|
-
YARN_LOCK = 'yarn.lock'
|
13
|
-
|
14
|
-
def initialize(dir)
|
11
|
+
def initialize(dir, report)
|
15
12
|
@dir = dir
|
13
|
+
@report = report
|
14
|
+
end
|
15
|
+
|
16
|
+
def fetch
|
17
|
+
case @report
|
18
|
+
when Enum::Report::DEPRECATED
|
19
|
+
deprecated
|
20
|
+
when Enum::Report::OUTDATED
|
21
|
+
outdated
|
22
|
+
when Enum::Report::VULNERABLE
|
23
|
+
vulnerable
|
24
|
+
else
|
25
|
+
all
|
26
|
+
end
|
16
27
|
end
|
17
28
|
|
18
29
|
def all
|
19
30
|
implicit_pkgs = fetch_from_lock_file
|
20
|
-
vulnerable_pkgs = VulnerabilityFinder.new(implicit_pkgs).run
|
31
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir, implicit_pkgs).run
|
21
32
|
pkgs = NpmMetaData.new(vulnerable_pkgs + implicit_pkgs).fetch.filter(&:risk?)
|
22
33
|
DuplicatePackageMerger.new(pkgs).run
|
23
34
|
end
|
@@ -36,7 +47,7 @@ module Package
|
|
36
47
|
|
37
48
|
def vulnerable
|
38
49
|
implicit_pkgs = fetch_from_lock_file
|
39
|
-
vulnerable_pkgs = VulnerabilityFinder.new(implicit_pkgs).run
|
50
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir, implicit_pkgs).run
|
40
51
|
pkgs = NpmMetaData.new(vulnerable_pkgs).fetch
|
41
52
|
DuplicatePackageMerger.new(pkgs).run
|
42
53
|
end
|
@@ -44,7 +55,7 @@ module Package
|
|
44
55
|
private
|
45
56
|
|
46
57
|
def fetch_from_package_json
|
47
|
-
package_json = JSON.parse(File.read("#{@dir}/#{PACKAGE_JSON}"), symbolize_names: true)
|
58
|
+
package_json = JSON.parse(File.read("#{@dir}/#{Const::File::PACKAGE_JSON}"), symbolize_names: true)
|
48
59
|
default_deps = package_json[:dependencies] || {}
|
49
60
|
dev_deps = package_json[:devDependencies] || {}
|
50
61
|
[default_deps, dev_deps]
|
@@ -52,8 +63,8 @@ module Package
|
|
52
63
|
|
53
64
|
def fetch_from_lock_file
|
54
65
|
default_deps, dev_deps = fetch_from_package_json
|
55
|
-
if File.exist?("#{@dir}/#{YARN_LOCK}")
|
56
|
-
YarnLockParser.new("#{@dir}/#{YARN_LOCK}").fetch(default_deps || {}, dev_deps || {})
|
66
|
+
if File.exist?("#{@dir}/#{Const::File::YARN_LOCK}")
|
67
|
+
YarnLockParser.new("#{@dir}/#{Const::File::YARN_LOCK}").fetch(default_deps || {}, dev_deps || {})
|
57
68
|
else
|
58
69
|
[]
|
59
70
|
end
|
@@ -7,13 +7,14 @@ module Package
|
|
7
7
|
class VulnerabilityFinder
|
8
8
|
AUDIT_ADVISORY_REGEX = /^{"type":"auditAdvisory".*$/
|
9
9
|
|
10
|
-
def initialize(pkgs)
|
10
|
+
def initialize(dir, pkgs)
|
11
|
+
@dir = dir
|
11
12
|
@pkg_hash = pkgs.to_h { |pkg| [pkg.name, pkg] }
|
12
13
|
@vuln_hash = {}
|
13
14
|
end
|
14
15
|
|
15
16
|
def run
|
16
|
-
json_string_lines = `#{Const::Cmd::YARN_AUDIT_JSON}`
|
17
|
+
json_string_lines = `#{format(Const::Cmd::YARN_AUDIT_JSON, @dir)}`
|
17
18
|
array = json_string_lines.scan(AUDIT_ADVISORY_REGEX)
|
18
19
|
|
19
20
|
vulnerability_json_array = JSON.parse("[#{array.join(',')}]", symbolize_names: true)
|
@@ -33,7 +34,7 @@ module Package
|
|
33
34
|
full_name = "#{name}@#{version}"
|
34
35
|
vulnerability = advisory[:severity] || Enum::VulnerabilityType::UNKNOWN
|
35
36
|
|
36
|
-
@vuln_hash[full_name] = Package.new(name, version) unless @vuln_hash.key? full_name
|
37
|
+
@vuln_hash[full_name] = Package.new(name, version, 'node') unless @vuln_hash.key? full_name
|
37
38
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
38
39
|
@vuln_hash[full_name].update groups: @pkg_hash[parent_name].groups
|
39
40
|
end
|
@@ -3,7 +3,8 @@ module Package
|
|
3
3
|
module Npm
|
4
4
|
class YarnLockParser
|
5
5
|
def initialize(yarn_lock_path)
|
6
|
-
@
|
6
|
+
@yarn_lock_file = File.read(yarn_lock_path)
|
7
|
+
@yarn_lock_path = yarn_lock_path
|
7
8
|
end
|
8
9
|
|
9
10
|
def fetch(default_deps, dev_deps)
|
@@ -11,7 +12,7 @@ module Package
|
|
11
12
|
default_deps.merge(dev_deps).each do |dep_name, expected_version|
|
12
13
|
pkg_block = fetch_package_block(dep_name, expected_version)
|
13
14
|
version = fetch_package_version(dep_name, pkg_block)
|
14
|
-
pks = Package.new(dep_name.to_s, version)
|
15
|
+
pks = Package.new(dep_name.to_s, version, 'node')
|
15
16
|
pks.update groups: dev_deps.key?(dep_name) ? %i[development] : %i[default development]
|
16
17
|
pkgs << pks
|
17
18
|
end
|
@@ -22,17 +23,20 @@ module Package
|
|
22
23
|
|
23
24
|
def fetch_package_block(dep_name, expected_version)
|
24
25
|
regex = /#{Regexp.escape(dep_name)}@#{Regexp.escape(expected_version)}.*?:.*?(\n\n|\z)/m
|
25
|
-
blocks = @
|
26
|
+
blocks = @yarn_lock_file.match(regex)
|
26
27
|
if blocks.nil? || blocks[0].nil?
|
27
|
-
raise NoMatchingPatternError, "Unable to find #{dep_name} in #{@yarn_lock_path}"
|
28
|
+
raise NoMatchingPatternError, "Unable to find \"#{dep_name}\" in #{@yarn_lock_path}"
|
28
29
|
end
|
29
30
|
|
30
31
|
blocks[0] || ''
|
31
32
|
end
|
32
33
|
|
33
34
|
def fetch_package_version(dep_name, pkg_block)
|
34
|
-
version = pkg_block.match(/version
|
35
|
-
|
35
|
+
version = pkg_block.match(/version"?\s*"(.*?)"/)&.captures&.[](0)
|
36
|
+
if version.nil?
|
37
|
+
raise NoMatchingPatternError,
|
38
|
+
"Unable to find the version of \"#{dep_name}\" in #{@yarn_lock_path}"
|
39
|
+
end
|
36
40
|
|
37
41
|
version || '0.0.0.0'
|
38
42
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative '../package'
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
1
|
+
require_relative '../models/package'
|
2
|
+
require_relative 'gem_meta_data'
|
3
|
+
require_relative 'vulnerability_finder'
|
4
4
|
|
5
5
|
require 'bundler'
|
6
6
|
|
@@ -8,16 +8,23 @@ module Package
|
|
8
8
|
module Audit
|
9
9
|
module Ruby
|
10
10
|
class BundlerSpecs
|
11
|
-
def self.all
|
12
|
-
Bundler.
|
11
|
+
def self.all(dir)
|
12
|
+
Bundler.with_unbundled_env do
|
13
|
+
ENV['BUNDLE_GEMFILE'] = "#{dir}/Gemfile"
|
14
|
+
Bundler.ui.silence { Bundler.definition.resolve }
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
|
-
def self.gemfile
|
16
|
-
current_dependencies = Bundler.
|
17
|
-
|
18
|
+
def self.gemfile(dir)
|
19
|
+
current_dependencies = Bundler.with_unbundled_env do
|
20
|
+
ENV['BUNDLE_GEMFILE'] = "#{dir}/Gemfile"
|
21
|
+
Bundler.reset!
|
22
|
+
Bundler.ui.silence do
|
23
|
+
Bundler.load.dependencies.to_h { |dep| [dep.name, dep] }
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
|
-
gemfile_specs, = all.partition do |spec|
|
27
|
+
gemfile_specs, = all(dir).partition do |spec|
|
21
28
|
current_dependencies.key? spec.name
|
22
29
|
end
|
23
30
|
gemfile_specs
|
@@ -1,35 +1,56 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '../duplicate_package_merger'
|
1
|
+
require_relative '../enum/report'
|
2
|
+
require_relative '../enum/risk_type'
|
3
|
+
require_relative '../services/duplicate_package_merger'
|
4
|
+
require_relative 'bundler_specs'
|
4
5
|
|
5
6
|
module Package
|
6
7
|
module Audit
|
7
8
|
module Ruby
|
8
9
|
class GemCollection
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def initialize(dir, report)
|
11
|
+
@dir = dir
|
12
|
+
@report = report
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
case @report
|
17
|
+
when Enum::Report::DEPRECATED
|
18
|
+
deprecated
|
19
|
+
when Enum::Report::OUTDATED
|
20
|
+
outdated
|
21
|
+
when Enum::Report::VULNERABLE
|
22
|
+
vulnerable
|
23
|
+
else
|
24
|
+
all
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def all
|
31
|
+
specs = BundlerSpecs.gemfile(@dir)
|
32
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
33
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir).run
|
13
34
|
pkgs = GemMetaData.new(pkgs + vulnerable_pkgs).fetch.filter(&:risk?)
|
14
35
|
DuplicatePackageMerger.new(pkgs).run
|
15
36
|
end
|
16
37
|
|
17
|
-
def
|
18
|
-
specs = BundlerSpecs.gemfile
|
19
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
38
|
+
def deprecated
|
39
|
+
specs = BundlerSpecs.gemfile(@dir)
|
40
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
20
41
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:deprecated?)
|
21
42
|
DuplicatePackageMerger.new(pkgs).run
|
22
43
|
end
|
23
44
|
|
24
|
-
def
|
25
|
-
specs = include_implicit ? BundlerSpecs.all : BundlerSpecs.gemfile
|
26
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
45
|
+
def outdated(include_implicit: false)
|
46
|
+
specs = include_implicit ? BundlerSpecs.all(@dir) : BundlerSpecs.gemfile(@dir)
|
47
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
27
48
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:outdated?)
|
28
49
|
DuplicatePackageMerger.new(pkgs).run
|
29
50
|
end
|
30
51
|
|
31
|
-
def
|
32
|
-
pkgs = VulnerabilityFinder.new.run
|
52
|
+
def vulnerable
|
53
|
+
pkgs = VulnerabilityFinder.new(@dir).run
|
33
54
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:vulnerable?)
|
34
55
|
DuplicatePackageMerger.new(pkgs).run
|
35
56
|
end
|
@@ -5,12 +5,13 @@ module Package
|
|
5
5
|
module Audit
|
6
6
|
module Ruby
|
7
7
|
class VulnerabilityFinder
|
8
|
-
def initialize
|
8
|
+
def initialize(dir)
|
9
|
+
@dir = dir
|
9
10
|
@vuln_hash = {}
|
10
11
|
end
|
11
12
|
|
12
13
|
def run
|
13
|
-
json_result = `#{Const::Cmd::BUNDLE_AUDIT_JSON}`
|
14
|
+
json_result = `#{format(Const::Cmd::BUNDLE_AUDIT_JSON, @dir)}`
|
14
15
|
vulnerability_json_array = JSON.parse(json_result, symbolize_names: true)[:results]
|
15
16
|
vulnerability_json_array.each do |vulnerability_json|
|
16
17
|
update_meta_data(vulnerability_json)
|
@@ -25,7 +26,7 @@ module Package
|
|
25
26
|
version = json[:gem][:version]
|
26
27
|
full_name = "#{name}@#{version}"
|
27
28
|
vulnerability = json[:advisory][:criticality] || Enum::VulnerabilityType::UNKNOWN
|
28
|
-
@vuln_hash[full_name] = Package.new(name, version) unless @vuln_hash.key? full_name
|
29
|
+
@vuln_hash[full_name] = Package.new(name, version, 'ruby') unless @vuln_hash.key? full_name
|
29
30
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
30
31
|
end
|
31
32
|
end
|