class MiniPortile

def verify_file(file)

def verify_file(file)
  if file.has_key?(:gpg)
    gpg = file[:gpg]
    signature_url = gpg[:signature_url] || "#{file[:url]}.asc"
    signature_file = file[:local_path] + ".asc"
    # download the signature file
    download_file(signature_url, signature_file)
    gpg_exe = which('gpg2') || which('gpg') || raise("Neither GPG nor GPG2 is installed")
    # import the key into our own keyring
    gpg_error = nil
    gpg_status = Open3.popen3(gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--import") do |gpg_in, gpg_out, gpg_err, _thread|
      gpg_in.write gpg[:key]
      gpg_in.close
      gpg_error = gpg_err.read
      gpg_out.read
    end
    key_ids = gpg_status.scan(/\[GNUPG:\] IMPORT_OK \d+ (?<key_id>[0-9a-f]+)/i).map(&:first)
    raise "invalid gpg key provided:\n#{gpg_error}" if key_ids.empty?
    begin
      # verify the signature against our keyring
      gpg_status, gpg_error, _status = Open3.capture3(gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--verify", signature_file, file[:local_path])
      raise "signature mismatch:\n#{gpg_error}" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)
    ensure
      # remove the key from our keyring
      key_ids.each do |key_id|
        IO.popen([gpg_exe, "--batch", "--yes", "--no-default-keyring", "--keyring", KEYRING_NAME, "--delete-keys", key_id], &:read)
        raise "unable to delete the imported key" unless $?.exitstatus==0
      end
    end
  else
    digest = case
      when exp=file[:sha256] then Digest::SHA256
      when exp=file[:sha1] then Digest::SHA1
      when exp=file[:md5] then Digest::MD5
    end
    if digest
      is = digest.file(file[:local_path]).hexdigest
      unless is == exp.downcase
        raise "Downloaded file '#{file[:local_path]}' has wrong hash: expected: #{exp} is: #{is}"
      end
    end
  end
end