package-audit 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/package/audit/cli.rb +32 -32
- 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} +7 -6
- data/lib/package/audit/npm/node_collection.rb +21 -10
- data/lib/package/audit/npm/vulnerability_finder.rb +1 -1
- data/lib/package/audit/npm/yarn_lock_parser.rb +1 -1
- data/lib/package/audit/ruby/bundler_specs.rb +1 -1
- data/lib/package/audit/ruby/gem_collection.rb +23 -6
- data/lib/package/audit/ruby/gem_meta_data.rb +1 -1
- data/lib/package/audit/ruby/vulnerability_finder.rb +1 -1
- 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 +20 -9
- 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 +1 -1
- data/sig/package/audit/ruby/gem_collection.rbs +4 -1
- 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 'const/file'
|
1
2
|
require_relative 'const/time'
|
3
|
+
require_relative 'enum/option'
|
4
|
+
require_relative 'services/command_parser'
|
2
5
|
require_relative 'version'
|
3
|
-
require_relative 'util/summary_printer'
|
4
|
-
require_relative 'ruby/bundler_specs'
|
5
|
-
require_relative 'printer'
|
6
|
-
require_relative 'ruby/gem_collection'
|
7
|
-
require_relative 'npm/node_collection'
|
8
|
-
require_relative 'command_service'
|
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
34
|
desc 'report [DIR]', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
21
|
-
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
22
|
-
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
23
|
-
|
24
35
|
def report(dir = Dir.pwd)
|
25
|
-
|
26
|
-
exit CommandService.new(dir, options).all
|
27
|
-
# end
|
36
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::ALL).run }
|
28
37
|
end
|
29
38
|
|
30
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
|
-
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
33
|
-
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
34
|
-
|
35
41
|
def deprecated(dir = Dir.pwd)
|
36
|
-
within_rescue_block
|
37
|
-
exit CommandService.new(dir, options).deprecated
|
38
|
-
end
|
42
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::DEPRECATED).run }
|
39
43
|
end
|
40
44
|
|
41
45
|
desc 'outdated [DIR]', 'Show packages that are out of date'
|
42
|
-
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
43
|
-
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
44
|
-
|
45
46
|
def outdated(dir = Dir.pwd)
|
46
|
-
within_rescue_block
|
47
|
-
exit CommandService.new(dir, options).outdated
|
48
|
-
end
|
47
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::OUTDATED).run }
|
49
48
|
end
|
50
49
|
|
51
50
|
desc 'vulnerable [DIR]', 'Show packages and their dependencies that have security vulnerabilities'
|
52
|
-
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
53
|
-
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
54
|
-
|
55
51
|
def vulnerable(dir = Dir.pwd)
|
56
|
-
within_rescue_block
|
57
|
-
exit CommandService.new(dir, options).vulnerable
|
58
|
-
end
|
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,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 '../enum/environment'
|
2
|
+
require_relative '../enum/risk_explanation'
|
3
|
+
require_relative '../enum/risk_type'
|
4
|
+
require_relative '../services/risk_calculator'
|
1
5
|
require_relative 'risk'
|
2
|
-
require_relative 'risk_calculator'
|
3
|
-
require_relative 'enum/environment'
|
4
|
-
require_relative 'enum/risk_type'
|
5
|
-
require_relative 'enum/risk_explanation'
|
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,18 +1,29 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../const/file'
|
2
|
+
require_relative '../services/duplicate_package_merger'
|
2
3
|
require_relative 'npm_meta_data'
|
3
4
|
require_relative 'vulnerability_finder'
|
4
|
-
require_relative '
|
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
|
@@ -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
|
@@ -34,7 +34,7 @@ module Package
|
|
34
34
|
full_name = "#{name}@#{version}"
|
35
35
|
vulnerability = advisory[:severity] || Enum::VulnerabilityType::UNKNOWN
|
36
36
|
|
37
|
-
@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
|
38
38
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
39
39
|
@vuln_hash[full_name].update groups: @pkg_hash[parent_name].groups
|
40
40
|
end
|
@@ -12,7 +12,7 @@ module Package
|
|
12
12
|
default_deps.merge(dev_deps).each do |dep_name, expected_version|
|
13
13
|
pkg_block = fetch_package_block(dep_name, expected_version)
|
14
14
|
version = fetch_package_version(dep_name, pkg_block)
|
15
|
-
pks = Package.new(dep_name.to_s, version)
|
15
|
+
pks = Package.new(dep_name.to_s, version, 'node')
|
16
16
|
pks.update groups: dev_deps.key?(dep_name) ? %i[development] : %i[default development]
|
17
17
|
pkgs << pks
|
18
18
|
end
|
@@ -1,18 +1,35 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../enum/report'
|
2
2
|
require_relative '../enum/risk_type'
|
3
|
-
require_relative '../duplicate_package_merger'
|
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 initialize(dir)
|
10
|
+
def initialize(dir, report)
|
10
11
|
@dir = dir
|
12
|
+
@report = report
|
11
13
|
end
|
12
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
|
+
|
13
30
|
def all
|
14
31
|
specs = BundlerSpecs.gemfile(@dir)
|
15
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
32
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
16
33
|
vulnerable_pkgs = VulnerabilityFinder.new(@dir).run
|
17
34
|
pkgs = GemMetaData.new(pkgs + vulnerable_pkgs).fetch.filter(&:risk?)
|
18
35
|
DuplicatePackageMerger.new(pkgs).run
|
@@ -20,14 +37,14 @@ module Package
|
|
20
37
|
|
21
38
|
def deprecated
|
22
39
|
specs = BundlerSpecs.gemfile(@dir)
|
23
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
40
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
24
41
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:deprecated?)
|
25
42
|
DuplicatePackageMerger.new(pkgs).run
|
26
43
|
end
|
27
44
|
|
28
45
|
def outdated(include_implicit: false)
|
29
46
|
specs = include_implicit ? BundlerSpecs.all(@dir) : BundlerSpecs.gemfile(@dir)
|
30
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
47
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
31
48
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:outdated?)
|
32
49
|
DuplicatePackageMerger.new(pkgs).run
|
33
50
|
end
|
@@ -26,7 +26,7 @@ module Package
|
|
26
26
|
version = json[:gem][:version]
|
27
27
|
full_name = "#{name}@#{version}"
|
28
28
|
vulnerability = json[:advisory][:criticality] || Enum::VulnerabilityType::UNKNOWN
|
29
|
-
@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
|
30
30
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
31
31
|
end
|
32
32
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require_relative '../const/cmd'
|
2
|
+
require_relative '../const/file'
|
3
|
+
require_relative '../enum/option'
|
4
|
+
require_relative '../enum/report'
|
5
|
+
require_relative '../technology/detector'
|
6
|
+
require_relative '../technology/validator'
|
7
|
+
require_relative '../util/summary_printer'
|
8
|
+
require_relative 'package_finder'
|
9
|
+
require_relative 'package_printer'
|
10
|
+
|
11
|
+
require 'yaml'
|
12
|
+
|
13
|
+
module Package
|
14
|
+
module Audit
|
15
|
+
class CommandParser
|
16
|
+
def initialize(dir, options, report)
|
17
|
+
@dir = dir
|
18
|
+
@options = options
|
19
|
+
@report = report
|
20
|
+
@config = parse_config_file
|
21
|
+
@technologies = parse_technologies
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
cumulative_pkgs = []
|
26
|
+
|
27
|
+
@technologies.each do |technology|
|
28
|
+
all_pkgs, ignored_pkgs = PackageFinder.new(@config, @dir, @report).run(technology)
|
29
|
+
ignored_pkgs = [] if @options[Enum::Option::INCLUDE_IGNORED]
|
30
|
+
cumulative_pkgs << all_pkgs
|
31
|
+
print_results(technology, (all_pkgs || []) - (ignored_pkgs || []), ignored_pkgs || [])
|
32
|
+
end
|
33
|
+
|
34
|
+
cumulative_pkgs.any?
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def print_results(technology, pkgs, ignored_pkgs)
|
40
|
+
PackagePrinter.new(@options, pkgs).print(report_fields)
|
41
|
+
print_summary(technology, pkgs, ignored_pkgs) unless @options[Enum::Option::CSV]
|
42
|
+
print_disclaimer(technology) unless @options[Enum::Option::CSV] || pkgs.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
def print_summary(technology, pkgs, ignored_pkgs)
|
46
|
+
if @report == Enum::Report::ALL
|
47
|
+
Util::SummaryPrinter.statistics(technology, @report, pkgs, ignored_pkgs)
|
48
|
+
else
|
49
|
+
Util::SummaryPrinter.total(technology, @report, pkgs, ignored_pkgs)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def print_disclaimer(technology)
|
54
|
+
case @report
|
55
|
+
when Enum::Report::DEPRECATED
|
56
|
+
Util::SummaryPrinter.deprecated
|
57
|
+
when Enum::Report::ALL, Enum::Report::VULNERABLE
|
58
|
+
Util::SummaryPrinter.vulnerable(technology, learn_more_command(technology))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def learn_more_command(technology)
|
63
|
+
case technology
|
64
|
+
when Enum::Technology::RUBY
|
65
|
+
Const::Cmd::BUNDLE_AUDIT
|
66
|
+
when Enum::Technology::NODE
|
67
|
+
Const::Cmd::YARN_AUDIT
|
68
|
+
else
|
69
|
+
raise ArgumentError, "Unexpected technology \"#{technology}\" found in #{__method__}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def report_fields
|
74
|
+
case @report
|
75
|
+
when Enum::Report::DEPRECATED
|
76
|
+
Const::Fields::DEPRECATED
|
77
|
+
when Enum::Report::OUTDATED
|
78
|
+
Const::Fields::OUTDATED
|
79
|
+
when Enum::Report::VULNERABLE
|
80
|
+
Const::Fields::VULNERABLE
|
81
|
+
else
|
82
|
+
Const::Fields::ALL
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_config_file
|
87
|
+
if @options[Enum::Option::CONFIG].nil?
|
88
|
+
YAML.load_file("#{@dir}/#{Const::File::CONFIG}") if File.exist? "#{@dir}/#{Const::File::CONFIG}"
|
89
|
+
elsif File.exist? @options[Enum::Option::CONFIG]
|
90
|
+
YAML.load_file(@options[Enum::Option::CONFIG])
|
91
|
+
else
|
92
|
+
raise ArgumentError, "Configuration file not found: #{@options[Enum::Option::CONFIG]}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_technologies
|
97
|
+
technology_validator = Technology::Validator.new(@dir)
|
98
|
+
@options[Enum::Option::TECHNOLOGY]&.each { |technology| technology_validator.validate! technology }
|
99
|
+
@options[Enum::Option::TECHNOLOGY] || Technology::Detector.new(@dir).detect
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../const/cmd'
|
2
|
+
require_relative '../const/file'
|
3
|
+
require_relative '../const/yaml'
|
4
|
+
require_relative '../enum/technology'
|
5
|
+
require_relative '../ruby/gem_collection'
|
6
|
+
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
module Package
|
10
|
+
module Audit
|
11
|
+
class PackageFilter
|
12
|
+
def initialize(config)
|
13
|
+
@config = config
|
14
|
+
end
|
15
|
+
|
16
|
+
def ignored?(pkg)
|
17
|
+
pkg_yaml = pkg_yaml_from_config(pkg)
|
18
|
+
pkg_version_in_config?(pkg, pkg_yaml) && ignore_package?(pkg, pkg_yaml)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def pkg_yaml_from_config(pkg)
|
24
|
+
yaml_fragment = @config&.dig(Const::YAML::TECHNOLOGY, pkg.technology, pkg.name)&.to_yaml
|
25
|
+
yaml_fragment.nil? ? nil : YAML.safe_load(yaml_fragment)
|
26
|
+
end
|
27
|
+
|
28
|
+
def pkg_version_in_config?(pkg, yaml)
|
29
|
+
yaml&.dig(Const::YAML::VERSION) == pkg.version
|
30
|
+
end
|
31
|
+
|
32
|
+
def ignore_package?(pkg, yaml)
|
33
|
+
(!pkg.deprecated? || yaml&.dig(Const::YAML::DEPRECATED) == false) &&
|
34
|
+
(!pkg.outdated? || yaml&.dig(Const::YAML::OUTDATED) == false) &&
|
35
|
+
(!pkg.vulnerable? || yaml&.dig(Const::YAML::VULNERABLE) == false)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative '../const/cmd'
|
2
|
+
require_relative '../const/file'
|
3
|
+
require_relative '../const/yaml'
|
4
|
+
require_relative '../enum/technology'
|
5
|
+
require_relative '../npm/node_collection'
|
6
|
+
require_relative '../ruby/gem_collection'
|
7
|
+
require_relative 'package_filter'
|
8
|
+
|
9
|
+
require 'yaml'
|
10
|
+
|
11
|
+
module Package
|
12
|
+
module Audit
|
13
|
+
class PackageFinder
|
14
|
+
def initialize(config, dir, report)
|
15
|
+
@config = config
|
16
|
+
@dir = dir
|
17
|
+
@report = report
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(technology)
|
21
|
+
all_pkgs = find_by_technology(technology)
|
22
|
+
ignored_pkgs = filter_pkgs_based_on_config(all_pkgs)
|
23
|
+
[all_pkgs, ignored_pkgs]
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def find_by_technology(technology)
|
29
|
+
case technology
|
30
|
+
when Enum::Technology::RUBY
|
31
|
+
find_ruby
|
32
|
+
when Enum::Technology::NODE
|
33
|
+
find_node
|
34
|
+
else
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_node
|
40
|
+
Npm::NodeCollection.new(@dir, @report).fetch
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_ruby
|
44
|
+
Ruby::GemCollection.new(@dir, @report).fetch
|
45
|
+
end
|
46
|
+
|
47
|
+
def filter_pkgs_based_on_config(pkgs)
|
48
|
+
package_filter = PackageFilter.new(@config)
|
49
|
+
ignored_pkgs = []
|
50
|
+
|
51
|
+
pkgs.each do |pkg|
|
52
|
+
ignored_pkgs << pkg if package_filter.ignored?(pkg)
|
53
|
+
end
|
54
|
+
ignored_pkgs
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|