Class: Gem::Guardian::RubygemsClient

Inherits:
Object
  • Object
show all
Defined in:
lib/gem/guardian/rubygems_client.rb

Overview

Reads checksum metadata from RubyGems.org and downloads gem artifacts. rubocop:disable Metrics/ClassLength

Defined Under Namespace

Classes: TrustedPublishingProvenance

Constant Summary collapse

SOURCE_COMMIT_PATTERN =
%r{Source Commit\s+([A-Za-z0-9._/-]+@[A-Za-z0-9._-]+)}i
BUILD_FILE_PATTERN =
/Build File\s+([^\s]+)/i
LOG_ENTRY_PATTERN =
%r{transparency log entry\s*(https?://[^\s]+)}i
SHA256_PATTERN =
/SHA 256 checksum\s*([a-f0-9]{64})/i
WORKFLOW_PATTERN =
/
  Built and signed on\s+
  ([A-Za-z0-9 ._-]+?)
  (?:\s+Build summary|\s+Source Commit|\z)
/ix
DEFAULT_HOST =

Default RubyGems.org endpoint used by the client.

"https://rubygems.org"

Instance Method Summary collapse

Constructor Details

#initialize(host: DEFAULT_HOST, http: Net::HTTP) ⇒ RubygemsClient

Returns a new instance of RubygemsClient.



31
32
33
34
# File 'lib/gem/guardian/rubygems_client.rb', line 31

def initialize(host: DEFAULT_HOST, http: Net::HTTP)
  @host = host.delete_suffix("/")
  @http = http
end

Instance Method Details

#download_gem(dependency, destination) ⇒ Object

Downloads the .gem file for +dependency+ into +destination+.



57
58
59
60
61
62
63
# File 'lib/gem/guardian/rubygems_client.rb', line 57

def download_gem(dependency, destination)
  body = get("/downloads/#{dependency.gem_filename}")
  File.binwrite(destination, body)
  destination
rescue StandardError => e
  raise ArtifactFetchError, "Could not fetch #{dependency.gem_filename}: #{e.message}"
end

#expected_sha256(dependency) ⇒ Object

Returns the expected SHA256 checksum for +dependency+.



37
38
39
40
41
42
43
44
45
46
# File 'lib/gem/guardian/rubygems_client.rb', line 37

def expected_sha256(dependency)
  version = matching_version(dependency)
  sha = version && version_checksum(version)
  if blank?(sha)
    raise ChecksumNotFound,
          "No SHA256 found for #{dependency.name} #{dependency.version} #{dependency.platform}"
  end

  sha.downcase
end

#trusted_publishing_provenance(dependency) ⇒ Object

Returns trusted publishing provenance data for +dependency+ when RubyGems exposes it.



49
50
51
52
53
54
# File 'lib/gem/guardian/rubygems_client.rb', line 49

def trusted_publishing_provenance(dependency)
  version = matching_version(dependency)
  version && provenance_for(version) ||
    attestation_api_provenance(dependency) ||
    version_page_provenance(dependency)
end