package-audit 0.3.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 +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
|