diff options
author | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-01 11:01:00 +0000 |
---|---|---|
committer | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-01 11:01:00 +0000 |
commit | 7a46a3b94121339cbead211c4497142bee82fddb (patch) | |
tree | bc6e9f11a1b60f8c4258e4780b18f952b0a8ec35 /lib | |
parent | 5cae104e51be9cbf524b7d953b33d0909c46d006 (diff) |
Merge rubygems-3.0.0.beta3.
* [GSoC] Multi-factor feature for RubyGems https://github.com/rubygems/rubygems/pull/2369
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rubygems.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/commands/owner_command.rb | 18 | ||||
-rw-r--r-- | lib/rubygems/commands/push_command.rb | 20 | ||||
-rw-r--r-- | lib/rubygems/commands/signin_command.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/gemcutter_utilities.rb | 31 | ||||
-rw-r--r-- | lib/rubygems/test_utilities.rb | 2 |
6 files changed, 65 insertions, 10 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb index b335dc321b..048eb9bdda 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -9,7 +9,7 @@ require 'rbconfig' module Gem - VERSION = "3.0.0.beta2".freeze + VERSION = "3.0.0.beta3".freeze end # Must be first since it unloads the prelude from 1.9.2 diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb index 9cfaa241b5..799f31704a 100644 --- a/lib/rubygems/commands/owner_command.rb +++ b/lib/rubygems/commands/owner_command.rb @@ -30,6 +30,7 @@ permission to. super 'owner', 'Manage gem owners of a gem on the push server' add_proxy_option add_key_option + add_otp_option defaults.merge! :add => [], :remove => [] add_option '-a', '--add EMAIL', 'Add an owner' do |value, options| @@ -84,9 +85,10 @@ permission to. def manage_owners(method, name, owners) owners.each do |owner| begin - response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request| - request.set_form_data 'email' => owner - request.add_field "Authorization", api_key + response = send_owner_request(method, name, owner) + + if need_otp? response + response = send_owner_request(method, name, owner, true) end action = method == :delete ? "Removing" : "Adding" @@ -98,4 +100,14 @@ permission to. end end + private + + def send_owner_request(method, name, owner, use_otp = false) + rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request| + request.set_form_data 'email' => owner + request.add_field "Authorization", api_key + request.add_field "OTP", options[:otp] if use_otp + end + end + end diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb index 20812368c4..3ea4703a3e 100644 --- a/lib/rubygems/commands/push_command.rb +++ b/lib/rubygems/commands/push_command.rb @@ -33,6 +33,7 @@ command. For further discussion see the help for the yank command. add_proxy_option add_key_option + add_otp_option add_option('--host HOST', 'Push to another gemcutter-compatible host', @@ -113,11 +114,10 @@ You can upgrade or downgrade to the latest release version with: say "Pushing gem to #{@host || Gem.host}..." - response = rubygems_api_request(*args) do |request| - request.body = Gem.read_binary name - request.add_field "Content-Length", request.body.size - request.add_field "Content-Type", "application/octet-stream" - request.add_field "Authorization", api_key + response = send_push_request(name, args) + + if need_otp? response + response = send_push_request(name, args, true) end with_response response @@ -125,6 +125,16 @@ You can upgrade or downgrade to the latest release version with: private + def send_push_request(name, args, use_otp = false) + rubygems_api_request(*args) do |request| + request.body = Gem.read_binary name + request.add_field "Content-Length", request.body.size + request.add_field "Content-Type", "application/octet-stream" + request.add_field "Authorization", api_key + request.add_field "OTP", options[:otp] if use_otp + end + end + def get_hosts_for(name) gem_metadata = Gem::Package.new(name).spec.metadata diff --git a/lib/rubygems/commands/signin_command.rb b/lib/rubygems/commands/signin_command.rb index 64b187f26f..0d527fc339 100644 --- a/lib/rubygems/commands/signin_command.rb +++ b/lib/rubygems/commands/signin_command.rb @@ -12,6 +12,8 @@ class Gem::Commands::SigninCommand < Gem::Command add_option('--host HOST', 'Push to another gemcutter-compatible host') do |value, options| options[:host] = value end + + add_otp_option end def description # :nodoc: diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index 6fe8455498..3607b61529 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -25,6 +25,16 @@ module Gem::GemcutterUtilities end ## + # Add the --otp option + + def add_otp_option + add_option('--otp CODE', + 'Digit code for multifactor authentication') do |value, options| + options[:otp] = value + end + end + + ## # The API key from the command options or from the user's configuration. def api_key @@ -113,6 +123,13 @@ module Gem::GemcutterUtilities request.basic_auth email, password end + if need_otp? response + response = rubygems_api_request(:get, "api/v1/api_key", sign_in_host) do |request| + request.basic_auth email, password + request.add_field "OTP", options[:otp] + end + end + with_response response do |resp| say "Signed in." set_api_key host, resp.body @@ -156,6 +173,20 @@ module Gem::GemcutterUtilities end end + ## + # Returns true when the user has enabled multifactor authentication from + # +response+ text. + + def need_otp?(response) + return unless response.kind_of?(Net::HTTPUnauthorized) && + response.body.start_with?('You have enabled multifactor authentication') + return true if options[:otp] + + say 'You have enabled multi-factor authentication. Please enter OTP code.' + options[:otp] = ask 'Code: ' + true + end + def set_api_key(host, key) if host == Gem::DEFAULT_HOST Gem.configuration.rubygems_api_key = key diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb index fe7eff8d8c..d531239812 100644 --- a/lib/rubygems/test_utilities.rb +++ b/lib/rubygems/test_utilities.rb @@ -87,7 +87,7 @@ class Gem::FakeFetcher def request(uri, request_class, last_modified = nil) data = find_data(uri) - body, code, msg = data + body, code, msg = (data.respond_to?(:call) ? data.call : data) @last_request = request_class.new uri.request_uri yield @last_request if block_given? |