From cec85795db3d4e6c5bd93205cda0525670fe8f3e Mon Sep 17 00:00:00 2001 From: Steven Webb Date: Sun, 11 Aug 2024 18:15:21 +0800 Subject: [PATCH] Use env var to set api key on install This commit allows setting the authorization header for `gem install` commands using the GEM_HOST_API_KEY environment variable. This is useful when working with private registries using short lived api tokens (e.g., OIDC tokens). For example: ``` GEM_HOST_API_KEY="secret_token" gem install private_gem --clear-sources \ --source https://private.repo.com ``` The GEM_HOST_API_KEY environment variable can already be used by the `gem push` command. I'm simply extending it's usage to `gem install` as well. --- lib/rubygems/commands/install_command.rb | 4 ++++ .../test_gem_commands_install_command.rb | 20 +++++++++++++++++++ test/rubygems/utilities.rb | 2 ++ 3 files changed, 26 insertions(+) diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index 2091634a2912..a15038e83e24 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -159,6 +159,10 @@ def execute load_hooks + if ENV["GEM_HOST_API_KEY"] + Gem::RemoteFetcher.fetcher.headers[:authorization] = ENV["GEM_HOST_API_KEY"] + end + exit_code = install_gems show_installed diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 5b09512ac45c..c7bbfa8ae9f5 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -28,6 +28,10 @@ def teardown Gem::Command.build_args = @orig_args File.unlink @gemdeps if File.file? @gemdeps File.unlink "#{@gemdeps}.lock" if File.file? "#{@gemdeps}.lock" + + if defined? Gem::RemoteFetcher + Gem::RemoteFetcher.fetcher = nil + end end def test_execute_exclude_prerelease @@ -760,6 +764,22 @@ def test_execute_remote assert_match "1 gem installed", @ui.output end + def test_execute_remote_gem_host_api_key + Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new + @a1, @a1_gem = util_gem "a", "1" + util_setup_spec_fetcher @a1 + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = Gem.read_binary(@a1_gem) + + ENV["GEM_HOST_API_KEY"] = "temporary_secret_key" + @cmd.options[:args] = %w[a] + use_ui @stub_ui do + @cmd.execute + end + + assert_match "1 gem installed", @ui.output + assert_equal "temporary_secret_key", @fetcher.headers[:authorization] + end + def test_execute_with_invalid_gem_file FileUtils.touch("a.gem") diff --git a/test/rubygems/utilities.rb b/test/rubygems/utilities.rb index 357379f88d8a..5ef123a784c2 100644 --- a/test/rubygems/utilities.rb +++ b/test/rubygems/utilities.rb @@ -31,11 +31,13 @@ class Gem::FakeFetcher attr_reader :data + attr_reader :headers attr_reader :last_request attr_accessor :paths def initialize @data = {} + @headers = {} @paths = [] end