Skip to content

Commit

Permalink
Validate spec checksums in verify gem contents task (#4262)
Browse files Browse the repository at this point in the history
  • Loading branch information
segiddins authored Dec 3, 2023
1 parent 5c6e71f commit 3299b92
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 21 deletions.
27 changes: 12 additions & 15 deletions app/tasks/maintenance/verify_gem_contents_in_fs_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,8 @@ def collection

def process(version)
logger.tagged(version_id: version.id, name: version.rubygem.name, number: version.number, platform: version.platform) do
gem_path = "gems/#{version.gem_file_name}"
spec_path = "quick/Marshal.4.8/#{version.full_name}.gemspec.rz"

expected_checksum = version.sha256
logger.warn "Version #{version.full_name} has no checksum" if expected_checksum.blank?

gem_contents = RubygemFs.instance.get(gem_path)
logger.warn "Version #{version.full_name} is missing gem contents" if gem_contents.blank?

logger.warn "#{spec_path} is missing" if RubygemFs.instance.head(spec_path).blank?

return unless gem_contents.present? && expected_checksum.present?

sha256 = Digest::SHA256.base64digest(gem_contents)
logger.error "#{gem_path} has incorrect checksum (expected #{expected_checksum}, got #{sha256})" if sha256 != expected_checksum
validate_checksum(version, "gem", "gems/#{version.gem_file_name}", version.sha256)
validate_checksum(version, "spec", "quick/Marshal.4.8/#{version.full_name}.gemspec.rz", version.spec_sha256)
end
end

Expand All @@ -60,4 +47,14 @@ def patterns_are_valid
def matches_regexp(collection, field, regexp)
collection.where(collection.arel_table[field].matches_regexp(regexp))
end

def validate_checksum(version, name, path, expected_checksum)
logger.warn "Version #{version.fullname} has no #{name} checksum" if expected_checksum.blank?
contents = RubygemFs.instance.get(path)
logger.warn "Version #{version.full_name} is missing #{name} contents (#{path})" if contents.blank?

return unless contents.present? && expected_checksum.present?
sha256 = Digest::SHA256.base64digest(contents)
logger.error "#{path} has incorrect checksum (expected #{expected_checksum}, got #{sha256})" if sha256 != expected_checksum
end
end
19 changes: 13 additions & 6 deletions test/tasks/maintenance/verify_gem_contents_in_fs_task_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ def task(**attrs)
assert_semantic_logger_event(
@task.logger.events[1],
level: :warn,
message_includes: ".gemspec.rz is missing"
message_includes: "is missing spec contents"
)
end

should "not error when checksums match" do
gem = "foo-1.0.0.gem"
gemspec = "#{gem}spec"
sha256 = Digest::SHA256.base64digest(gem)
version = create(:version, sha256:)
spec_sha256 = Digest::SHA256.base64digest(gemspec)
version = create(:version, sha256:, spec_sha256:)
RubygemFs.instance.store("gems/#{version.full_name}.gem", gem)
RubygemFs.instance.store("quick/Marshal.4.8/#{version.full_name}.gemspec.rz", "")
RubygemFs.instance.store("quick/Marshal.4.8/#{version.full_name}.gemspec.rz", gemspec)

@task = task
@task.process(version)
Expand All @@ -49,19 +51,24 @@ def task(**attrs)
end

should "error when checksums do not match" do
version = create(:version, sha256: "abcd")
version = create(:version, sha256: "abcd", spec_sha256: "defg")
RubygemFs.instance.store("gems/#{version.full_name}.gem", "abcd")
RubygemFs.instance.store("quick/Marshal.4.8/#{version.full_name}.gemspec.rz", "")
RubygemFs.instance.store("quick/Marshal.4.8/#{version.full_name}.gemspec.rz", "defg")

@task = task
@task.process(version)

assert_equal 1, @task.logger.events.size
assert_equal 2, @task.logger.events.size
assert_semantic_logger_event(
@task.logger.events[0],
level: :error,
message_includes: "has incorrect checksum (expected abcd, got #{Digest::SHA256.base64digest('abcd')})"
)
assert_semantic_logger_event(
@task.logger.events[1],
level: :error,
message_includes: "has incorrect checksum (expected defg, got #{Digest::SHA256.base64digest('defg')})"
)
end
end

Expand Down

0 comments on commit 3299b92

Please sign in to comment.