зеркало из https://github.com/github/ruby.git
[rubygems/rubygems] Improve gem login scope selection
https://github.com/rubygems/rubygems/commit/26c7abe5f6
This commit is contained in:
Родитель
b0711b1cf1
Коммит
d42330d702
|
@ -10,7 +10,8 @@ require_relative "gemcutter_utilities/webauthn_poller"
|
||||||
|
|
||||||
module Gem::GemcutterUtilities
|
module Gem::GemcutterUtilities
|
||||||
ERROR_CODE = 1
|
ERROR_CODE = 1
|
||||||
API_SCOPES = [:index_rubygems, :push_rubygem, :yank_rubygem, :add_owner, :remove_owner, :access_webhooks, :show_dashboard].freeze
|
API_SCOPES = [:index_rubygems, :push_rubygem, :yank_rubygem, :add_owner, :remove_owner, :access_webhooks].freeze
|
||||||
|
EXCLUSIVELY_API_SCOPES = [:show_dashboard].freeze
|
||||||
|
|
||||||
include Gem::Text
|
include Gem::Text
|
||||||
|
|
||||||
|
@ -309,15 +310,31 @@ module Gem::GemcutterUtilities
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_scope_params(scope)
|
def get_scope_params(scope)
|
||||||
scope_params = {}
|
scope_params = { index_rubygems: true }
|
||||||
|
|
||||||
if scope
|
if scope
|
||||||
scope_params = { scope => true }
|
scope_params = { scope => true }
|
||||||
else
|
else
|
||||||
say "Please select scopes you want to enable for the API key (y/n)"
|
say "The default access scope is:"
|
||||||
API_SCOPES.each do |s|
|
scope_params.each do |k, _v|
|
||||||
selected = ask_yes_no(s.to_s, false)
|
say " #{k}: y"
|
||||||
scope_params[s] = true if selected
|
end
|
||||||
|
say "\n"
|
||||||
|
customise = ask_yes_no("Do you want to customise scopes?", false)
|
||||||
|
if customise
|
||||||
|
EXCLUSIVELY_API_SCOPES.each do |excl_scope|
|
||||||
|
selected = ask_yes_no("#{excl_scope} (exclusive scope, answering yes will not prompt for other scopes)", false)
|
||||||
|
next unless selected
|
||||||
|
|
||||||
|
return { excl_scope => true }
|
||||||
|
end
|
||||||
|
|
||||||
|
scope_params = {}
|
||||||
|
|
||||||
|
API_SCOPES.each do |s|
|
||||||
|
selected = ask_yes_no(s.to_s, false)
|
||||||
|
scope_params[s] = true if selected
|
||||||
|
end
|
||||||
end
|
end
|
||||||
say "\n"
|
say "\n"
|
||||||
end
|
end
|
||||||
|
|
|
@ -85,7 +85,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
headers: { "location" => redirected_uri }
|
headers: { "location" => redirected_uri }
|
||||||
)
|
)
|
||||||
Gem::RemoteFetcher.fetcher = fetcher
|
Gem::RemoteFetcher.fetcher = fetcher
|
||||||
ui = Gem::MockGemUi.new("you@example.com\nsecret\n\n\n\n\n\n\n\n\n")
|
ui = Gem::MockGemUi.new("you@example.com\nsecret\n\n\n")
|
||||||
|
|
||||||
assert_raise Gem::MockGemUi::TermError do
|
assert_raise Gem::MockGemUi::TermError do
|
||||||
use_ui ui do
|
use_ui ui do
|
||||||
|
@ -106,51 +106,98 @@ class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
assert_equal api_key, credentials[:rubygems_api_key]
|
assert_equal api_key, credentials[:rubygems_api_key]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_execute_with_key_name_and_scope
|
def test_execute_with_key_name_default_scope
|
||||||
email = "you@example.com"
|
email = "you@example.com"
|
||||||
password = "secret"
|
password = "secret"
|
||||||
api_key = "1234abcd"
|
api_key = "1234abcd"
|
||||||
fetcher = Gem::RemoteFetcher.fetcher
|
fetcher = Gem::RemoteFetcher.fetcher
|
||||||
|
|
||||||
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\n"
|
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\n"
|
||||||
util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
|
util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
|
||||||
|
|
||||||
user = ENV["USER"] || ENV["USERNAME"]
|
user = ENV["USER"] || ENV["USERNAME"]
|
||||||
|
|
||||||
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
||||||
|
assert_match "The default access scope is:", key_name_ui.output
|
||||||
|
assert_match "index_rubygems: y", key_name_ui.output
|
||||||
|
assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
|
||||||
|
assert_equal "name=test-key&index_rubygems=true", fetcher.last_request.body
|
||||||
|
|
||||||
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
||||||
|
assert_equal api_key, credentials[:rubygems_api_key]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_with_key_name_and_custom_scope
|
||||||
|
email = "you@example.com"
|
||||||
|
password = "secret"
|
||||||
|
api_key = "1234abcd"
|
||||||
|
fetcher = Gem::RemoteFetcher.fetcher
|
||||||
|
|
||||||
|
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\n"
|
||||||
|
util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
|
||||||
|
|
||||||
|
user = ENV["USER"] || ENV["USERNAME"]
|
||||||
|
|
||||||
|
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
||||||
|
assert_match "The default access scope is:", key_name_ui.output
|
||||||
|
assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
|
||||||
|
assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
|
||||||
assert_match "index_rubygems [yN]", key_name_ui.output
|
assert_match "index_rubygems [yN]", key_name_ui.output
|
||||||
assert_match "push_rubygem [yN]", key_name_ui.output
|
assert_match "push_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "yank_rubygem [yN]", key_name_ui.output
|
assert_match "yank_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "add_owner [yN]", key_name_ui.output
|
assert_match "add_owner [yN]", key_name_ui.output
|
||||||
assert_match "remove_owner [yN]", key_name_ui.output
|
assert_match "remove_owner [yN]", key_name_ui.output
|
||||||
assert_match "access_webhooks [yN]", key_name_ui.output
|
assert_match "access_webhooks [yN]", key_name_ui.output
|
||||||
assert_match "show_dashboard [yN]", key_name_ui.output
|
|
||||||
assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body
|
assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body
|
||||||
|
|
||||||
credentials = load_yaml_file Gem.configuration.credentials_path
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
||||||
assert_equal api_key, credentials[:rubygems_api_key]
|
assert_equal api_key, credentials[:rubygems_api_key]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_execute_with_key_name_scope_and_mfa_level_of_ui_only
|
def test_execute_with_key_name_and_exclusive_scope
|
||||||
|
email = "you@example.com"
|
||||||
|
password = "secret"
|
||||||
|
api_key = "1234abcd"
|
||||||
|
fetcher = Gem::RemoteFetcher.fetcher
|
||||||
|
|
||||||
|
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\ny\n"
|
||||||
|
util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
|
||||||
|
|
||||||
|
user = ENV["USER"] || ENV["USERNAME"]
|
||||||
|
|
||||||
|
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
||||||
|
assert_match "The default access scope is:", key_name_ui.output
|
||||||
|
assert_match "index_rubygems: y", key_name_ui.output
|
||||||
|
assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
|
||||||
|
assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
|
||||||
|
assert_equal "name=test-key&show_dashboard=true", fetcher.last_request.body
|
||||||
|
|
||||||
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
||||||
|
assert_equal api_key, credentials[:rubygems_api_key]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_with_key_name_custom_scope_and_mfa_level_of_ui_only
|
||||||
email = "you@example.com"
|
email = "you@example.com"
|
||||||
password = "secret"
|
password = "secret"
|
||||||
api_key = "1234abcd"
|
api_key = "1234abcd"
|
||||||
fetcher = Gem::RemoteFetcher.fetcher
|
fetcher = Gem::RemoteFetcher.fetcher
|
||||||
mfa_level = "ui_only"
|
mfa_level = "ui_only"
|
||||||
|
|
||||||
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny"
|
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
|
||||||
util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute }
|
util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute }
|
||||||
|
|
||||||
user = ENV["USER"] || ENV["USERNAME"]
|
user = ENV["USER"] || ENV["USERNAME"]
|
||||||
|
|
||||||
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
||||||
|
assert_match "The default access scope is:", key_name_ui.output
|
||||||
|
assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
|
||||||
|
assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
|
||||||
assert_match "index_rubygems [yN]", key_name_ui.output
|
assert_match "index_rubygems [yN]", key_name_ui.output
|
||||||
assert_match "push_rubygem [yN]", key_name_ui.output
|
assert_match "push_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "yank_rubygem [yN]", key_name_ui.output
|
assert_match "yank_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "add_owner [yN]", key_name_ui.output
|
assert_match "add_owner [yN]", key_name_ui.output
|
||||||
assert_match "remove_owner [yN]", key_name_ui.output
|
assert_match "remove_owner [yN]", key_name_ui.output
|
||||||
assert_match "access_webhooks [yN]", key_name_ui.output
|
assert_match "access_webhooks [yN]", key_name_ui.output
|
||||||
assert_match "show_dashboard [yN]", key_name_ui.output
|
|
||||||
assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output
|
assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output
|
||||||
assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body
|
assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body
|
||||||
|
|
||||||
|
@ -158,26 +205,28 @@ class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
assert_equal api_key, credentials[:rubygems_api_key]
|
assert_equal api_key, credentials[:rubygems_api_key]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_execute_with_key_name_scope_and_mfa_level_of_gem_signin
|
def test_execute_with_key_name_custom_scope_and_mfa_level_of_gem_signin
|
||||||
email = "you@example.com"
|
email = "you@example.com"
|
||||||
password = "secret"
|
password = "secret"
|
||||||
api_key = "1234abcd"
|
api_key = "1234abcd"
|
||||||
fetcher = Gem::RemoteFetcher.fetcher
|
fetcher = Gem::RemoteFetcher.fetcher
|
||||||
mfa_level = "ui_and_gem_signin"
|
mfa_level = "ui_and_gem_signin"
|
||||||
|
|
||||||
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny"
|
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
|
||||||
util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute }
|
util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute }
|
||||||
|
|
||||||
user = ENV["USER"] || ENV["USERNAME"]
|
user = ENV["USER"] || ENV["USERNAME"]
|
||||||
|
|
||||||
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
||||||
|
assert_match "The default access scope is:", key_name_ui.output
|
||||||
|
assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
|
||||||
|
assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
|
||||||
assert_match "index_rubygems [yN]", key_name_ui.output
|
assert_match "index_rubygems [yN]", key_name_ui.output
|
||||||
assert_match "push_rubygem [yN]", key_name_ui.output
|
assert_match "push_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "yank_rubygem [yN]", key_name_ui.output
|
assert_match "yank_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "add_owner [yN]", key_name_ui.output
|
assert_match "add_owner [yN]", key_name_ui.output
|
||||||
assert_match "remove_owner [yN]", key_name_ui.output
|
assert_match "remove_owner [yN]", key_name_ui.output
|
||||||
assert_match "access_webhooks [yN]", key_name_ui.output
|
assert_match "access_webhooks [yN]", key_name_ui.output
|
||||||
assert_match "show_dashboard [yN]", key_name_ui.output
|
|
||||||
assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output
|
assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output
|
||||||
assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body
|
assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body
|
||||||
|
|
||||||
|
@ -207,7 +256,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
api_key = "1234abcd"
|
api_key = "1234abcd"
|
||||||
fetcher = Gem::RemoteFetcher.fetcher
|
fetcher = Gem::RemoteFetcher.fetcher
|
||||||
|
|
||||||
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny"
|
key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
|
||||||
|
|
||||||
# Set the expected response for the Web-API supplied
|
# Set the expected response for the Web-API supplied
|
||||||
ENV["RUBYGEMS_HOST"] = host
|
ENV["RUBYGEMS_HOST"] = host
|
||||||
|
@ -221,13 +270,13 @@ class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
user = ENV["USER"] || ENV["USERNAME"]
|
user = ENV["USER"] || ENV["USERNAME"]
|
||||||
|
|
||||||
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
|
||||||
|
assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
|
||||||
assert_match "index_rubygems [yN]", key_name_ui.output
|
assert_match "index_rubygems [yN]", key_name_ui.output
|
||||||
assert_match "push_rubygem [yN]", key_name_ui.output
|
assert_match "push_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "yank_rubygem [yN]", key_name_ui.output
|
assert_match "yank_rubygem [yN]", key_name_ui.output
|
||||||
assert_match "add_owner [yN]", key_name_ui.output
|
assert_match "add_owner [yN]", key_name_ui.output
|
||||||
assert_match "remove_owner [yN]", key_name_ui.output
|
assert_match "remove_owner [yN]", key_name_ui.output
|
||||||
assert_match "access_webhooks [yN]", key_name_ui.output
|
assert_match "access_webhooks [yN]", key_name_ui.output
|
||||||
assert_match "show_dashboard [yN]", key_name_ui.output
|
|
||||||
assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body
|
assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -248,7 +297,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
fetcher.data[profile] = profile_response
|
fetcher.data[profile] = profile_response
|
||||||
Gem::RemoteFetcher.fetcher = fetcher
|
Gem::RemoteFetcher.fetcher = fetcher
|
||||||
|
|
||||||
sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n")
|
sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n")
|
||||||
|
|
||||||
use_ui sign_in_ui do
|
use_ui sign_in_ui do
|
||||||
yield
|
yield
|
||||||
|
|
|
@ -306,7 +306,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
||||||
ENV["RUBYGEMS_HOST"] = @fetcher.host
|
ENV["RUBYGEMS_HOST"] = @fetcher.host
|
||||||
Gem::RemoteFetcher.fetcher = @fetcher
|
Gem::RemoteFetcher.fetcher = @fetcher
|
||||||
|
|
||||||
@sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input)
|
@sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n" + extra_input)
|
||||||
|
|
||||||
use_ui @sign_in_ui do
|
use_ui @sign_in_ui do
|
||||||
if args.length > 0
|
if args.length > 0
|
||||||
|
|
Загрузка…
Ссылка в новой задаче