diff --git a/Rakefile b/Rakefile index 9732e2e19f..207341ea7a 100644 --- a/Rakefile +++ b/Rakefile @@ -4,6 +4,7 @@ Bundler::GemHelper.install_tasks require "rake/testtask" require_relative "guides/_tasks/site" +require_relative "lib/graphql/rake_task/validate" Rake::TestTask.new do |t| t.libs << "spec" << "lib" @@ -23,7 +24,6 @@ task :build_parser do `ragel -R -F1 lib/graphql/language/lexer.rl` end - namespace :bench do def prepare_benchmark $LOAD_PATH << "./lib" << "./spec/support" diff --git a/guides/pro/installation.md b/guides/pro/installation.md index 28989ec638..7f776cf80d 100644 --- a/guides/pro/installation.md +++ b/guides/pro/installation.md @@ -47,12 +47,42 @@ Be sure to check the [changelog](https://github.com/rmosolgo/graphql-ruby/blob/m You can verify the integrity of `graphql-pro` by getting its checksum and comparing it to the [published checksums](https://github.com/rmosolgo/graphql-ruby/blob/master/guides/pro/checksums). -First, get the checksum: +Include the `graphql:pro:validate` task in your `Rakefile`: -```sh -# For example, to get the checksum of graphql-pro 1.0.0: -$ gem fetch graphql-pro -v 1.0.0 --source https://YOUR_KEY@gems.graphql.pro -$ ruby -rdigest/sha2 -e "puts Digest::SHA512.new.hexdigest(File.read('graphql-pro-1.0.0.gem'))" +```ruby +# Rakefile +require "graphql/rake_task/validate" ``` -Then, compare it to the corresponding checksum [listed on GitHub](https://github.com/rmosolgo/graphql-ruby/blob/master/guides/pro/checksums). If it the results don't match, then the gem was compromised. +Then invoke it with a version: + +``` +$ bundle exec rake graphql:pro:validate[1.0.0] +Validating graphql-pro v1.0.0 + - Checking for graphql-pro credentials... + ✓ found + - Fetching the gem... + ✓ fetched + - Validating digest... + ✓ validated from GitHub + ✓ validated from graphql-ruby.org +✔ graphql-pro 1.0.0 validated successfully! +``` + +In case of a failure, please open an issue: + +``` +Validating graphql-pro v1.4.800 + - Checking for graphql-pro credentials... + ✓ found + - Fetching the gem... + ✓ fetched + - Validating digest... + ✘ SHA mismatch: + Downloaded: c9cab2619aa6540605ce7922784fc84dbba3623383fdce6b17fde01d8da0aff49d666810c97f66310013c030e3ab7712094ee2d8f1ea9ce79aaf65c1684d992a + GitHub: 404: Not Found + graphql-ruby.org: 404: Not Found + + This download of graphql-pro is invalid, please open an issue: + https://github.com/rmosolgo/graphql-ruby/issues/new?title=graphql-pro%20digest%20mismatch%20(1.4.800) +``` diff --git a/lib/graphql/rake_task.rb b/lib/graphql/rake_task.rb index 8b87dd7b54..c58f3c605c 100644 --- a/lib/graphql/rake_task.rb +++ b/lib/graphql/rake_task.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true require "fileutils" +require "graphql/rake_task/validate" + module GraphQL # A rake task for dumping a schema as IDL or JSON. # diff --git a/lib/graphql/rake_task/validate.rb b/lib/graphql/rake_task/validate.rb new file mode 100644 index 0000000000..718b2c8aaf --- /dev/null +++ b/lib/graphql/rake_task/validate.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module GraphQL + class RakeTask + extend Rake::DSL + + desc "Get the checksum of a graphql-pro version and compare it to published versions on GitHub and graphql-ruby.org" + task "graphql:pro:validate", [:gem_version] do |t, args| + version = args[:gem_version] + check = "\e[32m✓\e[0m" + ex = "\e[31m✘\e[0m" + puts "Validating graphql-pro v#{version}" + puts " - Checking for graphql-pro credentials..." + + creds = `bundle config gems.graphql.pro`[/[a-z0-9]{11}:[a-z0-9]{11}/] + if creds.nil? + puts " #{ex} failed, please set with `bundle config gems.graphql.pro $MY_CREDENTIALS`" + exit(1) + else + puts " #{check} found" + end + + puts " - Fetching the gem..." + fetch_result = `gem fetch graphql-pro -v #{version} --source https://#{creds}@gems.graphql.pro` + if fetch_result.empty? + puts " #{ex} failed to fetch v#{version}" + exit(1) + else + puts " #{check} fetched" + end + + puts " - Validating digest..." + require "digest/sha2" + gem_digest = Digest::SHA512.new.hexdigest(File.read("graphql-pro-#{version}.gem")) + require "net/http" + github_uri = URI("https://raw.githubusercontent.com/rmosolgo/graphql-ruby/master/guides/pro/checksums/graphql-pro-#{version}.txt") + # Remove final newline from .txt file + github_digest = Net::HTTP.get(github_uri).chomp + + docs_uri = URI("https://raw.githubusercontent.com/rmosolgo/graphql-ruby/master/guides/pro/checksums/graphql-pro-#{version}.txt") + docs_digest = Net::HTTP.get(docs_uri).chomp + + if docs_digest == gem_digest && github_digest == gem_digest + puts " #{check} validated from GitHub" + puts " #{check} validated from graphql-ruby.org" + else + puts " #{ex} SHA mismatch:" + puts " Downloaded: #{gem_digest}" + puts " GitHub: #{github_digest}" + puts " graphql-ruby.org: #{docs_digest}" + puts "" + puts " This download of graphql-pro is invalid, please open an issue:" + puts " https://github.com/rmosolgo/graphql-ruby/issues/new?title=graphql-pro%20digest%20mismatch%20(#{version})" + exit(1) + end + + puts "\e[32m✔\e[0m graphql-pro #{version} validated successfully!" + end + end +end