Refactor Hbc::Verify.
				
					
				
			This commit is contained in:
		
							parent
							
								
									beb6656278
								
							
						
					
					
						commit
						0e03b46899
					
				@ -1,31 +1,24 @@
 | 
			
		||||
require "cask/verify/checksum"
 | 
			
		||||
 | 
			
		||||
module Hbc
 | 
			
		||||
  module Verify
 | 
			
		||||
    module_function
 | 
			
		||||
 | 
			
		||||
    def verifications
 | 
			
		||||
      [
 | 
			
		||||
        Hbc::Verify::Checksum,
 | 
			
		||||
      ]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def all(cask, downloaded_path)
 | 
			
		||||
      odebug "Verifying download"
 | 
			
		||||
      verifications = for_cask(cask)
 | 
			
		||||
      odebug "#{verifications.size} verifications defined", verifications
 | 
			
		||||
      verifications.each do |verification|
 | 
			
		||||
        odebug "Running verification of class #{verification}"
 | 
			
		||||
        verification.new(cask, downloaded_path).verify
 | 
			
		||||
      if cask.sha256 == :no_check
 | 
			
		||||
        ohai "No SHA-256 checksum defined for Cask '#{cask}', skipping verification."
 | 
			
		||||
        return
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def for_cask(cask)
 | 
			
		||||
      odebug "Determining which verifications to run for Cask #{cask}"
 | 
			
		||||
      verifications.select do |verification|
 | 
			
		||||
        odebug "Checking for verification class #{verification}"
 | 
			
		||||
        verification.me?(cask)
 | 
			
		||||
      end
 | 
			
		||||
      ohai "Verifying SHA-256 checksum for Cask '#{cask}'."
 | 
			
		||||
 | 
			
		||||
      expected = cask.sha256
 | 
			
		||||
      computed = downloaded_path.sha256
 | 
			
		||||
 | 
			
		||||
      raise CaskSha256MissingError.new(cask.token, expected, computed) if expected.nil? || expected.empty?
 | 
			
		||||
 | 
			
		||||
      return if expected == computed
 | 
			
		||||
 | 
			
		||||
      ohai "Note: Running `brew update` may fix SHA-256 checksum errors."
 | 
			
		||||
      raise CaskSha256MismatchError.new(cask.token, expected, computed, downloaded_path)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -1,47 +0,0 @@
 | 
			
		||||
require "digest"
 | 
			
		||||
 | 
			
		||||
module Hbc
 | 
			
		||||
  module Verify
 | 
			
		||||
    class Checksum
 | 
			
		||||
      def self.me?(cask)
 | 
			
		||||
        return true unless cask.sha256 == :no_check
 | 
			
		||||
        ohai "No checksum defined for Cask #{cask}, skipping verification"
 | 
			
		||||
        false
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      attr_reader :cask, :downloaded_path
 | 
			
		||||
 | 
			
		||||
      def initialize(cask, downloaded_path)
 | 
			
		||||
        @cask = cask
 | 
			
		||||
        @downloaded_path = downloaded_path
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def verify
 | 
			
		||||
        return unless self.class.me?(cask)
 | 
			
		||||
        ohai "Verifying SHA-256 checksum for Cask '#{cask}'."
 | 
			
		||||
        verify_checksum
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      private
 | 
			
		||||
 | 
			
		||||
      def expected
 | 
			
		||||
        @expected ||= cask.sha256
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def computed
 | 
			
		||||
        @computed ||= downloaded_path.sha256
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def verify_checksum
 | 
			
		||||
        raise CaskSha256MissingError.new(cask.token, expected, computed) if expected.nil? || expected.empty?
 | 
			
		||||
 | 
			
		||||
        if expected == computed
 | 
			
		||||
          odebug "SHA-256 checksums match."
 | 
			
		||||
        else
 | 
			
		||||
          ohai 'Note: running "brew update" may fix sha256 checksum errors'
 | 
			
		||||
          raise CaskSha256MismatchError.new(cask.token, expected, computed, downloaded_path)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -1,88 +0,0 @@
 | 
			
		||||
describe Hbc::Verify::Checksum, :cask do
 | 
			
		||||
  let(:cask) { double("cask", token: "cask") }
 | 
			
		||||
  let(:downloaded_path) { instance_double("Pathname") }
 | 
			
		||||
  let(:verification) { described_class.new(cask, downloaded_path) }
 | 
			
		||||
 | 
			
		||||
  before do
 | 
			
		||||
    allow(cask).to receive(:sha256).and_return(expected_sha256)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe ".me?" do
 | 
			
		||||
    subject { described_class.me?(cask) }
 | 
			
		||||
 | 
			
		||||
    context "when expected sha256 is :no_check" do
 | 
			
		||||
      let(:expected_sha256) { :no_check }
 | 
			
		||||
 | 
			
		||||
      it { is_expected.to be false }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "when expected sha256 is nil" do
 | 
			
		||||
      let(:expected_sha256) { nil }
 | 
			
		||||
 | 
			
		||||
      it { is_expected.to be true }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "sha256 is empty" do
 | 
			
		||||
      let(:expected_sha256) { "" }
 | 
			
		||||
 | 
			
		||||
      it { is_expected.to be true }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "when expected sha256 is a valid shasum" do
 | 
			
		||||
      let(:expected_sha256) { "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }
 | 
			
		||||
 | 
			
		||||
      it { is_expected.to be true }
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#verify" do
 | 
			
		||||
    subject { verification.verify }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      allow(cask).to receive(:sha256).and_return(expected_sha256)
 | 
			
		||||
      allow(downloaded_path).to receive(:sha256).and_return(actual_sha256)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    let(:actual_sha256) { "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }
 | 
			
		||||
 | 
			
		||||
    context "when expected matches actual sha256" do
 | 
			
		||||
      let(:expected_sha256) { actual_sha256 }
 | 
			
		||||
 | 
			
		||||
      it "does not raise an error" do
 | 
			
		||||
        expect { subject }.not_to raise_error
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "when expected sha256 is :no_check" do
 | 
			
		||||
      let(:expected_sha256) { :no_check }
 | 
			
		||||
 | 
			
		||||
      it "does not raise an error" do
 | 
			
		||||
        expect { subject }.not_to raise_error
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "when expected does not match sha256" do
 | 
			
		||||
      let(:expected_sha256) { "d3adb33fd3adb33fd3adb33fd3adb33fd3adb33fd3adb33fd3adb33fd3adb33f" }
 | 
			
		||||
 | 
			
		||||
      it "raises an error" do
 | 
			
		||||
        expect { subject }.to raise_error(Hbc::CaskSha256MismatchError)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "when expected sha256 is nil" do
 | 
			
		||||
      let(:expected_sha256) { nil }
 | 
			
		||||
 | 
			
		||||
      it "raises an error" do
 | 
			
		||||
        expect { subject }.to raise_error(Hbc::CaskSha256MissingError)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "when expected sha256 is empty" do
 | 
			
		||||
      let(:expected_sha256) { "" }
 | 
			
		||||
 | 
			
		||||
      it "raises an error" do
 | 
			
		||||
        expect { subject }.to raise_error(Hbc::CaskSha256MissingError)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -1,63 +1,52 @@
 | 
			
		||||
describe Hbc::Verify, :cask do
 | 
			
		||||
  let(:cask) { double("cask") }
 | 
			
		||||
module Hbc
 | 
			
		||||
  describe Verify, :cask do
 | 
			
		||||
    describe "::all" do
 | 
			
		||||
      subject(:verification) { described_class.all(cask, downloaded_path) }
 | 
			
		||||
      let(:cask) { instance_double(Cask, token: "cask", sha256: expected_sha256) }
 | 
			
		||||
      let(:cafebabe) { "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe" }
 | 
			
		||||
      let(:deadbeef) { "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }
 | 
			
		||||
      let(:computed_sha256) { cafebabe }
 | 
			
		||||
      let(:downloaded_path) { instance_double(Pathname, sha256: computed_sha256) }
 | 
			
		||||
 | 
			
		||||
  let(:verification_classes) {
 | 
			
		||||
    [
 | 
			
		||||
      applicable_verification_class,
 | 
			
		||||
      inapplicable_verification_class,
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
      context "when the expected checksum is :no_check" do
 | 
			
		||||
        let(:expected_sha256) { :no_check }
 | 
			
		||||
 | 
			
		||||
  let(:applicable_verification_class) {
 | 
			
		||||
    double("applicable_verification_class", me?: true)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let(:inapplicable_verification_class) {
 | 
			
		||||
    double("inapplicable_verification_class", me?: false)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  before do
 | 
			
		||||
    allow(described_class).to receive(:verifications)
 | 
			
		||||
      .and_return(verification_classes)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe ".for_cask" do
 | 
			
		||||
    subject { described_class.for_cask(cask) }
 | 
			
		||||
 | 
			
		||||
    it "checks applicability of each verification" do
 | 
			
		||||
      verification_classes.each do |verify_class|
 | 
			
		||||
        expect(verify_class).to receive(:me?).with(cask)
 | 
			
		||||
        it "skips the check" do
 | 
			
		||||
          expect { verification }.to output(/skipping verification/).to_stdout
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      subject
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "includes applicable verifications" do
 | 
			
		||||
      expect(subject).to include(applicable_verification_class)
 | 
			
		||||
    end
 | 
			
		||||
      context "when expected and computed checksums match" do
 | 
			
		||||
        let(:expected_sha256) { cafebabe }
 | 
			
		||||
 | 
			
		||||
    it "excludes inapplicable verifications" do
 | 
			
		||||
      expect(subject).not_to include(inapplicable_verification_class)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
        it "does not raise an error" do
 | 
			
		||||
          expect { verification }.not_to raise_error
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
  describe ".all" do
 | 
			
		||||
    subject { described_class.all(cask, downloaded_path) }
 | 
			
		||||
      context "when the expected checksum is nil" do
 | 
			
		||||
        let(:expected_sha256) { nil }
 | 
			
		||||
 | 
			
		||||
    let(:downloaded_path) { double("downloaded_path") }
 | 
			
		||||
    let(:applicable_verification) { double("applicable_verification") }
 | 
			
		||||
    let(:inapplicable_verification) { double("inapplicable_verification") }
 | 
			
		||||
        it "raises an error" do
 | 
			
		||||
          expect { verification }.to raise_error CaskSha256MissingError
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      allow(applicable_verification_class).to receive(:new)
 | 
			
		||||
        .and_return(applicable_verification)
 | 
			
		||||
      allow(inapplicable_verification_class).to receive(:new)
 | 
			
		||||
        .and_return(inapplicable_verification)
 | 
			
		||||
    end
 | 
			
		||||
      context "when the expected checksum is empty" do
 | 
			
		||||
        let(:expected_sha256) { "" }
 | 
			
		||||
 | 
			
		||||
    it "runs only applicable verifications" do
 | 
			
		||||
      expect(applicable_verification).to receive(:verify)
 | 
			
		||||
      expect(inapplicable_verification).not_to receive(:verify)
 | 
			
		||||
      subject
 | 
			
		||||
        it "raises an error" do
 | 
			
		||||
          expect { verification }.to raise_error CaskSha256MissingError
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      context "when expected and computed checksums do not match" do
 | 
			
		||||
        let(:expected_sha256) { deadbeef }
 | 
			
		||||
 | 
			
		||||
        it "raises an error" do
 | 
			
		||||
          expect { verification }.to raise_error CaskSha256MismatchError
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user