Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,19 @@ def requirements_update_strategy
end

def conflicting_dependencies
ConflictingDependencyResolver.new(
conflicts = ConflictingDependencyResolver.new(
dependency_files: dependency_files,
credentials: credentials
).conflicting_dependencies(
dependency: dependency,
target_version: lowest_security_fix_version
)

vulnerable = vulnerability_audit.select do |v|
!v["fix_available"] && v["explanation"]
end

conflicts + vulnerable
end

private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def initialize(dependency_files:, credentials:, allow_removal: false)
@allow_removal = allow_removal
end

# rubocop:disable Metrics/MethodLength
# Finds any dependencies in the `package-lock.json` or `npm-shrinkwrap.json` that have
# a subdependency on the given dependency that is locked to a vuln version range.
#
Expand All @@ -41,6 +42,7 @@ def initialize(dependency_files:, credentials:, allow_removal: false)
# dependency on the blocking dependency
# * :top_level_ancestors [Array<String>] the names of all top-level dependencies with a transitive
# dependency on the dependency
# * :explanation [String] an explanation for why the project failed the vulnerability auditor run
def audit(dependency:, security_advisories:)
fix_unavailable = {
"dependency_name" => dependency.name,
Expand Down Expand Up @@ -74,21 +76,36 @@ def audit(dependency:, security_advisories:)
function: "npm:vulnerabilityAuditor",
args: [Dir.pwd, vuln_versions]
)
return fix_unavailable unless viable_audit_result?(audit_result, security_advisories)

validation_result = validate_audit_result(audit_result, security_advisories)
unless viable_audit_result?(validation_result)
fix_unavailable["explanation"] = explain_fix_unavailable(validation_result, dependency)
return fix_unavailable
end

audit_result
end
rescue SharedHelpers::HelperSubprocessFailed => e
log_helper_subprocess_failure(dependency, e)
fix_unavailable
end
# rubocop:enable Metrics/MethodLength

private

attr_reader :dependency_files, :credentials

def viable_audit_result?(audit_result, security_advisories)
validation_result = validate_audit_result(audit_result, security_advisories)
def explain_fix_unavailable(validation_result, dependency)
case validation_result
when :fix_unavailable, :dependency_still_vulnerable, :downgrades_dependencies
"No patched version available for #{dependency.name}"
when :vulnerable_dependency_removed
"#{dependency.name} was removed in the update. Dependabot is not able to " \
"deal with this yet, but you can still upgrade manually."
end
end

def viable_audit_result?(validation_result)
return true if validation_result == :viable

Dependabot.logger.info("VulnerabilityAuditor: audit result not viable: #{validation_result}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@

expect(Dependabot.logger).to receive(:info).with(/audit result not viable: vulnerable_dependency_removed/i)
expect(subject.audit(dependency: dependency, security_advisories: security_advisories)).
to include("fix_available" => false)
to include(
"fix_available" => false,
"explanation" => "#{dependency.name} was removed in the update. "\
"Dependabot is not able to deal with this yet, but you can still upgrade manually."
)
end
end
end
Expand All @@ -137,7 +141,10 @@

expect(Dependabot.logger).to receive(:info).with(/audit result not viable: dependency_still_vulnerable/i)
expect(subject.audit(dependency: dependency, security_advisories: security_advisories)).
to include("fix_available" => false)
to include(
"fix_available" => false,
"explanation" => "No patched version available for #{dependency.name}"
)
end
end

Expand Down Expand Up @@ -172,7 +179,10 @@

expect(Dependabot.logger).to receive(:info).with(/audit result not viable: downgrades_dependencies/i)
expect(subject.audit(dependency: dependency, security_advisories: security_advisories)).
to include("fix_available" => false)
to include(
"fix_available" => false,
"explanation" => "No patched version available for #{dependency.name}"
)
end
end

Expand Down