audit: remove appcast checkpoints
This commit is contained in:
parent
727413da3c
commit
c68526ac09
@ -26,7 +26,7 @@ module Hbc
|
|||||||
check_version_and_checksum
|
check_version_and_checksum
|
||||||
check_version
|
check_version
|
||||||
check_sha256
|
check_sha256
|
||||||
check_appcast
|
check_appcast_checkpoint
|
||||||
check_url
|
check_url
|
||||||
check_generic_artifacts
|
check_generic_artifacts
|
||||||
check_token_conflicts
|
check_token_conflicts
|
||||||
@ -185,58 +185,11 @@ module Hbc
|
|||||||
add_error "cannot use the sha256 for an empty string in #{stanza}: #{empty_sha256}"
|
add_error "cannot use the sha256 for an empty string in #{stanza}: #{empty_sha256}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_appcast
|
def check_appcast_checkpoint
|
||||||
return unless cask.appcast
|
return unless cask.appcast
|
||||||
odebug "Auditing appcast"
|
|
||||||
check_appcast_has_checkpoint
|
|
||||||
return unless cask.appcast.checkpoint
|
return unless cask.appcast.checkpoint
|
||||||
check_sha256_actually_256(sha256: cask.appcast.checkpoint, stanza: "appcast :checkpoint")
|
|
||||||
check_sha256_invalid(sha256: cask.appcast.checkpoint, stanza: "appcast :checkpoint")
|
|
||||||
return unless download
|
|
||||||
check_appcast_http_code
|
|
||||||
check_appcast_checkpoint_accuracy
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_appcast_has_checkpoint
|
add_error "Appcast checkpoints have been removed from Homebrew-Cask"
|
||||||
odebug "Verifying appcast has :checkpoint key"
|
|
||||||
add_error "a checkpoint sha256 is required for appcast" unless cask.appcast.checkpoint
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_appcast_http_code
|
|
||||||
odebug "Verifying appcast returns 200 HTTP response code"
|
|
||||||
|
|
||||||
curl_executable, *args = curl_args(
|
|
||||||
"--compressed", "--location", "--fail",
|
|
||||||
"--write-out", "%{http_code}",
|
|
||||||
"--output", "/dev/null",
|
|
||||||
cask.appcast,
|
|
||||||
user_agent: :fake
|
|
||||||
)
|
|
||||||
result = @command.run(curl_executable, args: args, print_stderr: false)
|
|
||||||
if result.success?
|
|
||||||
http_code = result.stdout.chomp
|
|
||||||
add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
|
|
||||||
else
|
|
||||||
add_warning "error retrieving appcast: #{result.stderr}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_appcast_checkpoint_accuracy
|
|
||||||
odebug "Verifying appcast checkpoint is accurate"
|
|
||||||
result = cask.appcast.calculate_checkpoint
|
|
||||||
|
|
||||||
actual_checkpoint = result[:checkpoint]
|
|
||||||
|
|
||||||
if actual_checkpoint.nil?
|
|
||||||
add_warning "error retrieving appcast: #{result[:command_result].stderr}"
|
|
||||||
else
|
|
||||||
expected = cask.appcast.checkpoint
|
|
||||||
add_warning <<~EOS unless expected == actual_checkpoint
|
|
||||||
appcast checkpoint mismatch
|
|
||||||
Expected: #{expected}
|
|
||||||
Actual: #{actual_checkpoint}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_latest_with_appcast
|
def check_latest_with_appcast
|
||||||
|
@ -317,124 +317,19 @@ describe Hbc::Audit, :cask do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "appcast checks" do
|
describe "appcast checkpoint check" do
|
||||||
context "when appcast has no sha256" do
|
let(:error_msg) { "Appcast checkpoints have been removed from Homebrew-Cask" }
|
||||||
let(:cask_token) { "appcast-missing-checkpoint" }
|
|
||||||
|
|
||||||
it { is_expected.to fail_with(/checkpoint sha256 is required for appcast/) }
|
context "when the Cask does not have a checkpoint" do
|
||||||
|
let(:cask_token) { "with-appcast" }
|
||||||
|
|
||||||
|
it { is_expected.not_to fail_with(error_msg) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when appcast checkpoint is not a string of 64 hexadecimal characters" do
|
context "when the Cask has a checkpoint" do
|
||||||
let(:cask_token) { "appcast-invalid-checkpoint" }
|
let(:cask_token) { "appcast-with-checkpoint" }
|
||||||
|
|
||||||
it { is_expected.to fail_with(/string must be of 64 hexadecimal characters/) }
|
it { is_expected.to fail_with(error_msg) }
|
||||||
end
|
|
||||||
|
|
||||||
context "when appcast checkpoint is sha256 for empty string" do
|
|
||||||
let(:cask_token) { "appcast-checkpoint-sha256-for-empty-string" }
|
|
||||||
|
|
||||||
it { is_expected.to fail_with(/cannot use the sha256 for an empty string/) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when appcast checkpoint is valid sha256" do
|
|
||||||
let(:cask_token) { "appcast-valid-checkpoint" }
|
|
||||||
|
|
||||||
it { is_expected.not_to fail_with(/appcast :checkpoint/) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when verifying appcast HTTP code" do
|
|
||||||
let(:cask_token) { "appcast-valid-checkpoint" }
|
|
||||||
let(:download) { instance_double(Hbc::Download) }
|
|
||||||
let(:wrong_code_msg) { /unexpected HTTP response code/ }
|
|
||||||
let(:curl_error_msg) { /error retrieving appcast/ }
|
|
||||||
let(:fake_curl_result) { instance_double(Hbc::SystemCommand::Result) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(audit).to receive(:check_appcast_checkpoint_accuracy)
|
|
||||||
allow(fake_system_command).to receive(:run).and_return(fake_curl_result)
|
|
||||||
allow(fake_curl_result).to receive(:success?).and_return(success)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when curl succeeds" do
|
|
||||||
let(:success) { true }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(fake_curl_result).to receive(:stdout).and_return(stdout)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when HTTP code is 200" do
|
|
||||||
let(:stdout) { "200" }
|
|
||||||
|
|
||||||
it { is_expected.not_to warn_with(wrong_code_msg) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when HTTP code is not 200" do
|
|
||||||
let(:stdout) { "404" }
|
|
||||||
|
|
||||||
it { is_expected.to warn_with(wrong_code_msg) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when curl fails" do
|
|
||||||
let(:success) { false }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(fake_curl_result).to receive(:stderr).and_return("Some curl error")
|
|
||||||
end
|
|
||||||
|
|
||||||
it { is_expected.to warn_with(curl_error_msg) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when verifying appcast checkpoint" do
|
|
||||||
let(:cask_token) { "appcast-valid-checkpoint" }
|
|
||||||
let(:download) { instance_double(Hbc::Download) }
|
|
||||||
let(:mismatch_msg) { /appcast checkpoint mismatch/ }
|
|
||||||
let(:curl_error_msg) { /error retrieving appcast/ }
|
|
||||||
let(:fake_curl_result) { instance_double(Hbc::SystemCommand::Result) }
|
|
||||||
let(:expected_checkpoint) { "d5b2dfbef7ea28c25f7a77cd7fa14d013d82b626db1d82e00e25822464ba19e2" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(audit).to receive(:check_appcast_http_code)
|
|
||||||
allow(Hbc::SystemCommand).to receive(:run).and_return(fake_curl_result)
|
|
||||||
allow(fake_curl_result).to receive(:success?).and_return(success)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when appcast download succeeds" do
|
|
||||||
let(:success) { true }
|
|
||||||
let(:appcast_text) { instance_double(::String) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(fake_curl_result).to receive(:stdout).and_return(appcast_text)
|
|
||||||
allow(appcast_text).to receive(:gsub).and_return(appcast_text)
|
|
||||||
allow(appcast_text).to receive(:end_with?).with("\n").and_return(true)
|
|
||||||
allow(Digest::SHA2).to receive(:hexdigest).and_return(actual_checkpoint)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when appcast checkpoint is out of date" do
|
|
||||||
let(:actual_checkpoint) { "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }
|
|
||||||
|
|
||||||
it { is_expected.to warn_with(mismatch_msg) }
|
|
||||||
it { is_expected.not_to warn_with(curl_error_msg) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when appcast checkpoint is up to date" do
|
|
||||||
let(:actual_checkpoint) { expected_checkpoint }
|
|
||||||
|
|
||||||
it { is_expected.not_to warn_with(mismatch_msg) }
|
|
||||||
it { is_expected.not_to warn_with(curl_error_msg) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when appcast download fails" do
|
|
||||||
let(:success) { false }
|
|
||||||
|
|
||||||
before do
|
|
||||||
allow(fake_curl_result).to receive(:stderr).and_return("Some curl error")
|
|
||||||
end
|
|
||||||
|
|
||||||
it { is_expected.to warn_with(curl_error_msg) }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
cask 'appcast-valid-checkpoint' do
|
cask 'appcast-with-checkpoint' do
|
||||||
appcast 'http://localhost/appcast.xml',
|
appcast 'http://localhost/appcast.xml',
|
||||||
checkpoint: 'd5b2dfbef7ea28c25f7a77cd7fa14d013d82b626db1d82e00e25822464ba19e2'
|
checkpoint: 'd5b2dfbef7ea28c25f7a77cd7fa14d013d82b626db1d82e00e25822464ba19e2'
|
||||||
end
|
end
|
Loading…
x
Reference in New Issue
Block a user