summaryrefslogtreecommitdiff
path: root/lib/rubygems
diff options
context:
space:
mode:
authorAshley Ellis Pierce <anellis12@gmail.com>2022-01-24 15:25:28 -0500
committergit <svn-admin@ruby-lang.org>2022-04-06 08:54:54 +0900
commitb3f1b3ccef6f61b95685690e5a8faaa3f009c25f (patch)
tree1ec0750cf7a6b76579beeeafaa2859fe022bc2ef /lib/rubygems
parent8ee4a82e8cfe6f39abeb60013447bdd2a3a3c61f (diff)
[rubygems/rubygems] Enable mfa on specific keys during gem signin
https://github.com/rubygems/rubygems/commit/e787f7f655
Diffstat (limited to 'lib/rubygems')
-rw-r--r--lib/rubygems/gemcutter_utilities.rb25
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb
index 0968e1a6f9..adf85d1b6c 100644
--- a/lib/rubygems/gemcutter_utilities.rb
+++ b/lib/rubygems/gemcutter_utilities.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require_relative 'remote_fetcher'
require_relative 'text'
+require 'json'
##
# Utility methods for using the RubyGems API.
@@ -163,12 +164,13 @@ module Gem::GemcutterUtilities
key_name = get_key_name(scope)
scope_params = get_scope_params(scope)
+ mfa_params = get_mfa_params(email, password)
response = rubygems_api_request(:post, "api/v1/api_key",
sign_in_host, scope: scope) do |request|
request.basic_auth email, password
request["OTP"] = otp if otp
- request.body = URI.encode_www_form({ name: key_name }.merge(scope_params))
+ request.body = URI.encode_www_form({ name: key_name }.merge(scope_params, mfa_params))
end
with_response response do |resp|
@@ -267,6 +269,27 @@ module Gem::GemcutterUtilities
scope_params
end
+ def get_mfa_params(email, password)
+ mfa_level = get_user_mfa_level(email, password)
+ params = {}
+ if mfa_level == "ui_only" || mfa_level == "ui_and_gem_sign"
+ selected = ask "Would you like to enable MFA for this key? [y/N]"
+ params["mfa"] = true if selected =~ /^[yY](es)?$/
+ elsif mfa_level == "ui_and_api"
+ params["mfa"] = true
+ end
+ params
+ end
+
+ def get_user_mfa_level(email, password)
+ response = rubygems_api_request(:get, "api/v1/profile") do |request|
+ request.basic_auth email, password
+ end
+ with_response response do |resp|
+ JSON.parse(resp.body)["mfa"]
+ end
+ end
+
def get_key_name(scope)
hostname = Socket.gethostname || "unknown-host"
user = ENV["USER"] || ENV["USERNAME"] || "unknown-user"