rubygems-update 3.4.16 → 3.4.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/Manifest.txt +7 -4
- data/bundler/CHANGELOG.md +24 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/feature_flag.rb +0 -1
- data/bundler/lib/bundler/man/bundle-config.1 +0 -3
- data/bundler/lib/bundler/man/bundle-config.1.ronn +0 -3
- data/bundler/lib/bundler/man/bundle-outdated.1 +12 -8
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +12 -9
- data/bundler/lib/bundler/settings.rb +0 -1
- data/bundler/lib/bundler/source/git.rb +19 -13
- data/bundler/lib/bundler/source.rb +1 -1
- data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +4 -4
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +2 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/version.rb +1 -1
- data/{bin → exe}/gem +2 -0
- data/{bin → exe}/update_rubygems +7 -5
- data/lib/rubygems/available_set.rb +1 -0
- data/lib/rubygems/basic_specification.rb +1 -0
- data/lib/rubygems/command.rb +1 -0
- data/lib/rubygems/command_manager.rb +1 -0
- data/lib/rubygems/commands/build_command.rb +1 -0
- data/lib/rubygems/commands/cert_command.rb +1 -0
- data/lib/rubygems/commands/check_command.rb +1 -0
- data/lib/rubygems/commands/cleanup_command.rb +1 -0
- data/lib/rubygems/commands/contents_command.rb +1 -0
- data/lib/rubygems/commands/dependency_command.rb +1 -0
- data/lib/rubygems/commands/environment_command.rb +1 -0
- data/lib/rubygems/commands/exec_command.rb +1 -0
- data/lib/rubygems/commands/fetch_command.rb +1 -0
- data/lib/rubygems/commands/generate_index_command.rb +1 -0
- data/lib/rubygems/commands/help_command.rb +1 -0
- data/lib/rubygems/commands/install_command.rb +1 -0
- data/lib/rubygems/commands/list_command.rb +1 -0
- data/lib/rubygems/commands/lock_command.rb +1 -0
- data/lib/rubygems/commands/mirror_command.rb +1 -0
- data/lib/rubygems/commands/open_command.rb +1 -0
- data/lib/rubygems/commands/outdated_command.rb +1 -0
- data/lib/rubygems/commands/owner_command.rb +1 -0
- data/lib/rubygems/commands/pristine_command.rb +1 -0
- data/lib/rubygems/commands/push_command.rb +1 -0
- data/lib/rubygems/commands/query_command.rb +1 -0
- data/lib/rubygems/commands/rdoc_command.rb +1 -0
- data/lib/rubygems/commands/search_command.rb +1 -0
- data/lib/rubygems/commands/server_command.rb +1 -0
- data/lib/rubygems/commands/setup_command.rb +2 -1
- data/lib/rubygems/commands/signin_command.rb +1 -0
- data/lib/rubygems/commands/signout_command.rb +1 -0
- data/lib/rubygems/commands/sources_command.rb +1 -0
- data/lib/rubygems/commands/specification_command.rb +1 -0
- data/lib/rubygems/commands/stale_command.rb +1 -0
- data/lib/rubygems/commands/uninstall_command.rb +1 -0
- data/lib/rubygems/commands/unpack_command.rb +1 -0
- data/lib/rubygems/commands/update_command.rb +1 -0
- data/lib/rubygems/commands/which_command.rb +1 -0
- data/lib/rubygems/commands/yank_command.rb +1 -0
- data/lib/rubygems/config_file.rb +1 -0
- data/lib/rubygems/core_ext/kernel_require.rb +1 -0
- data/lib/rubygems/core_ext/tcpsocket_init.rb +2 -0
- data/lib/rubygems/defaults.rb +1 -0
- data/lib/rubygems/dependency.rb +1 -0
- data/lib/rubygems/dependency_installer.rb +1 -0
- data/lib/rubygems/dependency_list.rb +1 -0
- data/lib/rubygems/deprecate.rb +1 -0
- data/lib/rubygems/doctor.rb +1 -0
- data/lib/rubygems/errors.rb +1 -0
- data/lib/rubygems/ext/build_error.rb +1 -0
- data/lib/rubygems/ext/builder.rb +1 -0
- data/lib/rubygems/ext/configure_builder.rb +1 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +1 -0
- data/lib/rubygems/ext.rb +1 -0
- data/lib/rubygems/gem_runner.rb +1 -0
- data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +163 -0
- data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +105 -0
- data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +78 -0
- data/lib/rubygems/gemcutter_utilities.rb +29 -24
- data/lib/rubygems/indexer.rb +1 -0
- data/lib/rubygems/install_default_message.rb +1 -0
- data/lib/rubygems/install_message.rb +1 -0
- data/lib/rubygems/install_update_options.rb +1 -0
- data/lib/rubygems/installer.rb +1 -0
- data/lib/rubygems/local_remote_options.rb +1 -0
- data/lib/rubygems/mock_gem_ui.rb +1 -0
- data/lib/rubygems/name_tuple.rb +1 -0
- data/lib/rubygems/package/digest_io.rb +1 -0
- data/lib/rubygems/package/file_source.rb +1 -0
- data/lib/rubygems/package/io_source.rb +1 -0
- data/lib/rubygems/package/old.rb +1 -0
- data/lib/rubygems/package/source.rb +1 -0
- data/lib/rubygems/package/tar_header.rb +1 -0
- data/lib/rubygems/package/tar_reader/entry.rb +1 -0
- data/lib/rubygems/package/tar_reader.rb +1 -0
- data/lib/rubygems/package/tar_writer.rb +1 -0
- data/lib/rubygems/package.rb +1 -0
- data/lib/rubygems/package_task.rb +1 -0
- data/lib/rubygems/path_support.rb +1 -0
- data/lib/rubygems/platform.rb +1 -0
- data/lib/rubygems/psych_tree.rb +1 -0
- data/lib/rubygems/rdoc.rb +1 -0
- data/lib/rubygems/remote_fetcher.rb +1 -0
- data/lib/rubygems/request/http_pool.rb +1 -0
- data/lib/rubygems/request/https_pool.rb +1 -0
- data/lib/rubygems/request.rb +1 -0
- data/lib/rubygems/request_set/gem_dependency_api.rb +1 -0
- data/lib/rubygems/request_set/lockfile/parser.rb +1 -0
- data/lib/rubygems/request_set/lockfile/tokenizer.rb +2 -0
- data/lib/rubygems/request_set/lockfile.rb +1 -0
- data/lib/rubygems/request_set.rb +1 -0
- data/lib/rubygems/requirement.rb +1 -0
- data/lib/rubygems/resolver/activation_request.rb +1 -0
- data/lib/rubygems/resolver/api_set.rb +1 -0
- data/lib/rubygems/resolver/api_specification.rb +1 -0
- data/lib/rubygems/resolver/best_set.rb +1 -0
- data/lib/rubygems/resolver/composed_set.rb +1 -0
- data/lib/rubygems/resolver/conflict.rb +1 -0
- data/lib/rubygems/resolver/current_set.rb +1 -0
- data/lib/rubygems/resolver/dependency_request.rb +1 -0
- data/lib/rubygems/resolver/git_set.rb +1 -0
- data/lib/rubygems/resolver/git_specification.rb +1 -0
- data/lib/rubygems/resolver/index_set.rb +1 -0
- data/lib/rubygems/resolver/index_specification.rb +1 -0
- data/lib/rubygems/resolver/installed_specification.rb +1 -0
- data/lib/rubygems/resolver/installer_set.rb +4 -1
- data/lib/rubygems/resolver/local_specification.rb +1 -0
- data/lib/rubygems/resolver/lock_set.rb +1 -0
- data/lib/rubygems/resolver/lock_specification.rb +1 -0
- data/lib/rubygems/resolver/molinillo.rb +1 -0
- data/lib/rubygems/resolver/requirement_list.rb +1 -0
- data/lib/rubygems/resolver/set.rb +1 -0
- data/lib/rubygems/resolver/source_set.rb +2 -0
- data/lib/rubygems/resolver/spec_specification.rb +1 -0
- data/lib/rubygems/resolver/specification.rb +1 -0
- data/lib/rubygems/resolver/stats.rb +1 -0
- data/lib/rubygems/resolver/vendor_set.rb +1 -0
- data/lib/rubygems/resolver/vendor_specification.rb +1 -0
- data/lib/rubygems/resolver.rb +1 -0
- data/lib/rubygems/s3_uri_signer.rb +4 -2
- data/lib/rubygems/safe_yaml.rb +2 -0
- data/lib/rubygems/security/policies.rb +1 -0
- data/lib/rubygems/security/policy.rb +1 -0
- data/lib/rubygems/security/signer.rb +1 -0
- data/lib/rubygems/security/trust_dir.rb +1 -0
- data/lib/rubygems/security.rb +1 -0
- data/lib/rubygems/security_option.rb +1 -0
- data/lib/rubygems/source/installed.rb +1 -0
- data/lib/rubygems/source/local.rb +1 -0
- data/lib/rubygems/source/lock.rb +1 -0
- data/lib/rubygems/source/specific_file.rb +1 -0
- data/lib/rubygems/source/vendor.rb +1 -0
- data/lib/rubygems/spec_fetcher.rb +1 -0
- data/lib/rubygems/specification.rb +9 -1
- data/lib/rubygems/specification_policy.rb +2 -0
- data/lib/rubygems/stub_specification.rb +1 -0
- data/lib/rubygems/uninstaller.rb +1 -0
- data/lib/rubygems/user_interaction.rb +2 -0
- data/lib/rubygems/util/licenses.rb +1 -0
- data/lib/rubygems/util/list.rb +1 -0
- data/lib/rubygems/util.rb +1 -0
- data/lib/rubygems/validator.rb +1 -0
- data/lib/rubygems/version_option.rb +1 -0
- data/lib/rubygems.rb +2 -1
- data/rubygems-update.gemspec +2 -1
- data/setup.rb +1 -0
- data/test/rubygems/bad_rake.rb +1 -0
- data/test/rubygems/bundler_test_gem.rb +3 -1
- data/test/rubygems/fake_certlib/openssl.rb +1 -0
- data/test/rubygems/good_rake.rb +1 -0
- data/test/rubygems/installer_test_case.rb +1 -0
- data/test/rubygems/multifactor_auth_utilities.rb +111 -0
- data/test/rubygems/package/tar_test_case.rb +1 -0
- data/test/rubygems/plugin/exception/rubygems_plugin.rb +1 -0
- data/test/rubygems/plugin/load/rubygems_plugin.rb +1 -0
- data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +1 -0
- data/test/rubygems/rubygems/commands/crash_command.rb +1 -0
- data/test/rubygems/rubygems_plugin.rb +1 -0
- data/test/rubygems/simple_gem.rb +1 -0
- data/test/rubygems/specifications/bar-0.0.2.gemspec +2 -0
- data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +2 -0
- data/test/rubygems/test_bundled_ca.rb +1 -0
- data/test/rubygems/test_config.rb +1 -0
- data/test/rubygems/test_deprecate.rb +1 -0
- data/test/rubygems/test_gem.rb +1 -0
- data/test/rubygems/test_gem_available_set.rb +1 -0
- data/test/rubygems/test_gem_bundler_version_finder.rb +1 -0
- data/test/rubygems/test_gem_command.rb +1 -0
- data/test/rubygems/test_gem_command_manager.rb +1 -0
- data/test/rubygems/test_gem_commands_build_command.rb +1 -0
- data/test/rubygems/test_gem_commands_cert_command.rb +1 -0
- data/test/rubygems/test_gem_commands_check_command.rb +1 -0
- data/test/rubygems/test_gem_commands_cleanup_command.rb +1 -0
- data/test/rubygems/test_gem_commands_contents_command.rb +1 -0
- data/test/rubygems/test_gem_commands_dependency_command.rb +1 -0
- data/test/rubygems/test_gem_commands_environment_command.rb +1 -0
- data/test/rubygems/test_gem_commands_exec_command.rb +2 -0
- data/test/rubygems/test_gem_commands_fetch_command.rb +1 -0
- data/test/rubygems/test_gem_commands_generate_index_command.rb +1 -0
- data/test/rubygems/test_gem_commands_help_command.rb +1 -0
- data/test/rubygems/test_gem_commands_info_command.rb +1 -0
- data/test/rubygems/test_gem_commands_install_command.rb +1 -0
- data/test/rubygems/test_gem_commands_list_command.rb +1 -0
- data/test/rubygems/test_gem_commands_lock_command.rb +1 -0
- data/test/rubygems/test_gem_commands_mirror.rb +1 -0
- data/test/rubygems/test_gem_commands_open_command.rb +1 -0
- data/test/rubygems/test_gem_commands_outdated_command.rb +1 -0
- data/test/rubygems/test_gem_commands_owner_command.rb +68 -39
- data/test/rubygems/test_gem_commands_pristine_command.rb +1 -0
- data/test/rubygems/test_gem_commands_push_command.rb +68 -37
- data/test/rubygems/test_gem_commands_query_command.rb +1 -0
- data/test/rubygems/test_gem_commands_search_command.rb +1 -0
- data/test/rubygems/test_gem_commands_server_command.rb +1 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +1 -1
- data/test/rubygems/test_gem_commands_signin_command.rb +1 -0
- data/test/rubygems/test_gem_commands_sources_command.rb +1 -0
- data/test/rubygems/test_gem_commands_specification_command.rb +1 -0
- data/test/rubygems/test_gem_commands_stale_command.rb +1 -0
- data/test/rubygems/test_gem_commands_uninstall_command.rb +1 -0
- data/test/rubygems/test_gem_commands_unpack_command.rb +1 -0
- data/test/rubygems/test_gem_commands_update_command.rb +1 -0
- data/test/rubygems/test_gem_commands_which_command.rb +1 -0
- data/test/rubygems/test_gem_commands_yank_command.rb +76 -41
- data/test/rubygems/test_gem_config_file.rb +1 -0
- data/test/rubygems/test_gem_dependency.rb +1 -0
- data/test/rubygems/test_gem_dependency_installer.rb +35 -0
- data/test/rubygems/test_gem_dependency_list.rb +1 -0
- data/test/rubygems/test_gem_dependency_resolution_error.rb +1 -0
- data/test/rubygems/test_gem_doctor.rb +1 -0
- data/test/rubygems/test_gem_ext_builder.rb +4 -3
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +2 -0
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +2 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +2 -0
- data/test/rubygems/test_gem_ext_cargo_builder.rb +2 -2
- data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +1 -0
- data/test/rubygems/test_gem_ext_cmake_builder.rb +1 -0
- data/test/rubygems/test_gem_ext_configure_builder.rb +1 -0
- data/test/rubygems/test_gem_ext_rake_builder.rb +1 -0
- data/test/rubygems/test_gem_gem_runner.rb +1 -0
- data/test/rubygems/test_gem_gemcutter_utilities.rb +106 -92
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +1 -0
- data/test/rubygems/test_gem_indexer.rb +1 -0
- data/test/rubygems/test_gem_install_update_options.rb +1 -0
- data/test/rubygems/test_gem_installer.rb +2 -1
- data/test/rubygems/test_gem_local_remote_options.rb +1 -0
- data/test/rubygems/test_gem_name_tuple.rb +1 -0
- data/test/rubygems/test_gem_package_old.rb +1 -0
- data/test/rubygems/test_gem_package_tar_header.rb +1 -0
- data/test/rubygems/test_gem_package_tar_reader.rb +1 -0
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +1 -0
- data/test/rubygems/test_gem_package_tar_writer.rb +1 -0
- data/test/rubygems/test_gem_package_task.rb +1 -0
- data/test/rubygems/test_gem_path_support.rb +1 -0
- data/test/rubygems/test_gem_platform.rb +1 -0
- data/test/rubygems/test_gem_rdoc.rb +1 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +1 -0
- data/test/rubygems/test_gem_request.rb +10 -4
- data/test/rubygems/test_gem_request_connection_pools.rb +1 -0
- data/test/rubygems/test_gem_request_set.rb +1 -0
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +1 -0
- data/test/rubygems/test_gem_request_set_lockfile.rb +1 -0
- data/test/rubygems/test_gem_request_set_lockfile_parser.rb +1 -0
- data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +1 -0
- data/test/rubygems/test_gem_requirement.rb +1 -0
- data/test/rubygems/test_gem_resolver.rb +1 -0
- data/test/rubygems/test_gem_resolver_activation_request.rb +1 -0
- data/test/rubygems/test_gem_resolver_api_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_api_specification.rb +1 -0
- data/test/rubygems/test_gem_resolver_best_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_composed_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_conflict.rb +1 -0
- data/test/rubygems/test_gem_resolver_dependency_request.rb +1 -0
- data/test/rubygems/test_gem_resolver_git_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_git_specification.rb +2 -1
- data/test/rubygems/test_gem_resolver_index_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_index_specification.rb +1 -0
- data/test/rubygems/test_gem_resolver_installed_specification.rb +1 -0
- data/test/rubygems/test_gem_resolver_installer_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_local_specification.rb +1 -0
- data/test/rubygems/test_gem_resolver_lock_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_lock_specification.rb +1 -0
- data/test/rubygems/test_gem_resolver_requirement_list.rb +1 -0
- data/test/rubygems/test_gem_resolver_specification.rb +1 -0
- data/test/rubygems/test_gem_resolver_vendor_set.rb +1 -0
- data/test/rubygems/test_gem_resolver_vendor_specification.rb +1 -0
- data/test/rubygems/test_gem_security.rb +1 -0
- data/test/rubygems/test_gem_security_signer.rb +1 -0
- data/test/rubygems/test_gem_security_trust_dir.rb +1 -0
- data/test/rubygems/test_gem_silent_ui.rb +1 -0
- data/test/rubygems/test_gem_source.rb +1 -0
- data/test/rubygems/test_gem_source_fetch_problem.rb +1 -0
- data/test/rubygems/test_gem_source_git.rb +1 -0
- data/test/rubygems/test_gem_source_installed.rb +1 -0
- data/test/rubygems/test_gem_source_list.rb +1 -0
- data/test/rubygems/test_gem_source_local.rb +1 -0
- data/test/rubygems/test_gem_source_lock.rb +1 -0
- data/test/rubygems/test_gem_source_specific_file.rb +1 -0
- data/test/rubygems/test_gem_source_subpath_problem.rb +1 -0
- data/test/rubygems/test_gem_source_vendor.rb +1 -0
- data/test/rubygems/test_gem_spec_fetcher.rb +1 -0
- data/test/rubygems/test_gem_specification.rb +9 -0
- data/test/rubygems/test_gem_stream_ui.rb +34 -3
- data/test/rubygems/test_gem_stub_specification.rb +1 -0
- data/test/rubygems/test_gem_text.rb +1 -0
- data/test/rubygems/test_gem_uninstaller.rb +1 -0
- data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +1 -0
- data/test/rubygems/test_gem_update_suggestion.rb +1 -0
- data/test/rubygems/test_gem_uri.rb +2 -0
- data/test/rubygems/test_gem_uri_formatter.rb +1 -0
- data/test/rubygems/test_gem_util.rb +1 -0
- data/test/rubygems/test_gem_version.rb +1 -0
- data/test/rubygems/test_gem_version_option.rb +1 -0
- data/test/rubygems/test_kernel.rb +1 -0
- data/test/rubygems/test_remote_fetch_error.rb +1 -0
- data/test/rubygems/test_require.rb +1 -0
- data/test/rubygems/test_rubygems.rb +2 -0
- data/test/rubygems/test_webauthn_listener.rb +29 -6
- data/test/rubygems/test_webauthn_listener_response.rb +8 -8
- data/test/rubygems/test_webauthn_poller.rb +124 -0
- data/test/rubygems/utilities.rb +1 -0
- data/test/test_changelog_generator.rb +1 -1
- metadata +11 -8
- data/lib/rubygems/webauthn_listener/response.rb +0 -161
- data/lib/rubygems/webauthn_listener.rb +0 -92
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "helper"
|
4
|
+
require_relative "multifactor_auth_utilities"
|
3
5
|
require "rubygems"
|
4
6
|
require "rubygems/command"
|
5
7
|
require "rubygems/gemcutter_utilities"
|
@@ -9,6 +11,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
9
11
|
super
|
10
12
|
|
11
13
|
credential_setup
|
14
|
+
@fetcher = SignInFetcher.new
|
12
15
|
|
13
16
|
# below needed for random testing, class property
|
14
17
|
Gem.configuration.disable_default_gem_server = nil
|
@@ -92,21 +95,19 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
92
95
|
end
|
93
96
|
|
94
97
|
def test_sign_in
|
95
|
-
|
96
|
-
util_sign_in HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
|
98
|
+
util_sign_in
|
97
99
|
|
98
100
|
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
|
99
101
|
assert @fetcher.last_request["authorization"]
|
100
102
|
assert_match %r{Signed in.}, @sign_in_ui.output
|
101
103
|
|
102
104
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
103
|
-
assert_equal api_key, credentials[:rubygems_api_key]
|
105
|
+
assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
|
104
106
|
end
|
105
107
|
|
106
108
|
def test_sign_in_with_host
|
107
|
-
|
108
|
-
|
109
|
-
util_sign_in HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK"), "http://example.com", ["http://example.com"]
|
109
|
+
@fetcher = SignInFetcher.new(host: "http://example.com")
|
110
|
+
util_sign_in
|
110
111
|
|
111
112
|
assert_match "Enter your http://example.com credentials.",
|
112
113
|
@sign_in_ui.output
|
@@ -114,13 +115,12 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
114
115
|
assert_match %r{Signed in.}, @sign_in_ui.output
|
115
116
|
|
116
117
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
117
|
-
assert_equal api_key, credentials["http://example.com"]
|
118
|
+
assert_equal @fetcher.api_key, credentials["http://example.com"]
|
118
119
|
end
|
119
120
|
|
120
121
|
def test_sign_in_with_host_nil
|
121
|
-
|
122
|
-
|
123
|
-
util_sign_in HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK"), nil, [nil]
|
122
|
+
@fetcher = SignInFetcher.new(host: nil)
|
123
|
+
util_sign_in(args: [nil])
|
124
124
|
|
125
125
|
assert_match "Enter your RubyGems.org credentials.",
|
126
126
|
@sign_in_ui.output
|
@@ -128,12 +128,12 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
128
128
|
assert_match %r{Signed in.}, @sign_in_ui.output
|
129
129
|
|
130
130
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
131
|
-
assert_equal api_key, credentials[:rubygems_api_key]
|
131
|
+
assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
|
132
132
|
end
|
133
133
|
|
134
134
|
def test_sign_in_with_host_ENV
|
135
|
-
|
136
|
-
util_sign_in
|
135
|
+
@fetcher = SignInFetcher.new(host: "http://example.com")
|
136
|
+
util_sign_in
|
137
137
|
|
138
138
|
assert_match "Enter your http://example.com credentials.",
|
139
139
|
@sign_in_ui.output
|
@@ -141,47 +141,45 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
141
141
|
assert_match %r{Signed in.}, @sign_in_ui.output
|
142
142
|
|
143
143
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
144
|
-
assert_equal api_key, credentials["http://example.com"]
|
144
|
+
assert_equal @fetcher.api_key, credentials["http://example.com"]
|
145
145
|
end
|
146
146
|
|
147
147
|
def test_sign_in_skips_with_existing_credentials
|
148
|
-
|
149
|
-
Gem.configuration.rubygems_api_key = api_key
|
148
|
+
Gem.configuration.rubygems_api_key = @fetcher.api_key
|
150
149
|
|
151
|
-
util_sign_in
|
150
|
+
util_sign_in
|
152
151
|
|
153
152
|
assert_equal "", @sign_in_ui.output
|
154
153
|
end
|
155
154
|
|
156
155
|
def test_sign_in_skips_with_key_override
|
157
|
-
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
|
158
156
|
Gem.configuration.api_keys[:KEY] = "other"
|
159
157
|
@cmd.options[:key] = :KEY
|
160
|
-
util_sign_in
|
158
|
+
util_sign_in
|
161
159
|
|
162
160
|
assert_equal "", @sign_in_ui.output
|
163
161
|
end
|
164
162
|
|
165
163
|
def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys
|
166
|
-
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
|
167
164
|
other_api_key = "f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf"
|
168
165
|
|
169
166
|
File.open Gem.configuration.credentials_path, "w" do |f|
|
170
167
|
f.write Hash[:other_api_key, other_api_key].to_yaml
|
171
168
|
end
|
172
|
-
util_sign_in
|
169
|
+
util_sign_in
|
173
170
|
|
174
171
|
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
|
175
172
|
assert_match %r{Signed in.}, @sign_in_ui.output
|
176
173
|
|
177
174
|
credentials = load_yaml_file Gem.configuration.credentials_path
|
178
|
-
assert_equal api_key, credentials[:rubygems_api_key]
|
175
|
+
assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
|
179
176
|
assert_equal other_api_key, credentials[:other_api_key]
|
180
177
|
end
|
181
178
|
|
182
179
|
def test_sign_in_with_bad_credentials
|
180
|
+
@fetcher.respond_with_forbidden_api_key_response
|
183
181
|
assert_raise Gem::MockGemUi::TermError do
|
184
|
-
util_sign_in
|
182
|
+
util_sign_in
|
185
183
|
end
|
186
184
|
|
187
185
|
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
|
@@ -190,26 +188,16 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
190
188
|
|
191
189
|
def test_signin_with_env_otp_code
|
192
190
|
ENV["GEM_HOST_OTP_CODE"] = "111111"
|
193
|
-
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
|
194
191
|
|
195
|
-
util_sign_in
|
192
|
+
util_sign_in
|
196
193
|
|
197
194
|
assert_match "Signed in with API key:", @sign_in_ui.output
|
198
195
|
assert_equal "111111", @fetcher.last_request["OTP"]
|
199
196
|
end
|
200
197
|
|
201
198
|
def test_sign_in_with_correct_otp_code
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
util_sign_in(proc do
|
206
|
-
@call_count ||= 0
|
207
|
-
if (@call_count += 1).odd?
|
208
|
-
HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized")
|
209
|
-
else
|
210
|
-
HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
|
211
|
-
end
|
212
|
-
end, nil, [], "111111\n")
|
199
|
+
@fetcher.respond_with_require_otp
|
200
|
+
util_sign_in(extra_input: "111111\n")
|
213
201
|
|
214
202
|
assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output
|
215
203
|
assert_match "Code: ", @sign_in_ui.output
|
@@ -220,8 +208,9 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
220
208
|
def test_sign_in_with_incorrect_otp_code
|
221
209
|
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
|
222
210
|
|
211
|
+
@fetcher.respond_with_unauthorized_api_key_response
|
223
212
|
assert_raise Gem::MockGemUi::TermError do
|
224
|
-
util_sign_in
|
213
|
+
util_sign_in(extra_input: "111111\n")
|
225
214
|
end
|
226
215
|
|
227
216
|
assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output
|
@@ -231,87 +220,87 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
231
220
|
end
|
232
221
|
|
233
222
|
def test_sign_in_with_webauthn_enabled
|
234
|
-
|
235
|
-
response_fail = "You have enabled multifactor authentication"
|
236
|
-
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
|
237
|
-
port = 5678
|
238
|
-
server = TCPServer.new(port)
|
223
|
+
server = Gem::MockTCPServer.new
|
239
224
|
|
225
|
+
@fetcher.respond_with_require_otp
|
226
|
+
@fetcher.respond_with_webauthn_url
|
240
227
|
TCPServer.stub(:new, server) do
|
241
|
-
Gem::WebauthnListener.stub(:
|
242
|
-
util_sign_in
|
243
|
-
@call_count ||= 0
|
244
|
-
if (@call_count += 1).odd?
|
245
|
-
HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized")
|
246
|
-
else
|
247
|
-
HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
|
248
|
-
end
|
249
|
-
end, nil, [], "", webauthn_verification_url)
|
228
|
+
Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
|
229
|
+
util_sign_in
|
250
230
|
end
|
251
|
-
ensure
|
252
|
-
server.close
|
253
231
|
end
|
254
232
|
|
255
|
-
|
256
|
-
|
233
|
+
assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
|
234
|
+
"to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
|
235
|
+
"you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
|
257
236
|
assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
|
258
237
|
assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
|
259
238
|
end
|
260
239
|
|
261
240
|
def test_sign_in_with_webauthn_enabled_with_error
|
262
|
-
|
263
|
-
|
264
|
-
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
|
265
|
-
port = 5678
|
266
|
-
server = TCPServer.new(port)
|
267
|
-
raise_error = ->(*_args) { raise Gem::WebauthnVerificationError, "Something went wrong" }
|
241
|
+
server = Gem::MockTCPServer.new
|
242
|
+
error = Gem::WebauthnVerificationError.new("Something went wrong")
|
268
243
|
|
244
|
+
@fetcher.respond_with_require_otp
|
245
|
+
@fetcher.respond_with_webauthn_url
|
269
246
|
error = assert_raise Gem::MockGemUi::TermError do
|
270
247
|
TCPServer.stub(:new, server) do
|
271
|
-
Gem::WebauthnListener.stub(:
|
272
|
-
util_sign_in
|
273
|
-
@call_count ||= 0
|
274
|
-
if (@call_count += 1).odd?
|
275
|
-
HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized")
|
276
|
-
else
|
277
|
-
HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
|
278
|
-
end
|
279
|
-
end, nil, [], "", webauthn_verification_url)
|
248
|
+
Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
|
249
|
+
util_sign_in
|
280
250
|
end
|
281
|
-
ensure
|
282
|
-
server.close
|
283
251
|
end
|
284
252
|
end
|
285
253
|
assert_equal 1, error.exit_code
|
286
254
|
|
287
|
-
|
288
|
-
|
255
|
+
assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
|
256
|
+
"to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
|
257
|
+
"you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
|
289
258
|
assert_match "ERROR: Security device verification failed: Something went wrong", @sign_in_ui.error
|
290
259
|
refute_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
|
291
260
|
refute_match "Signed in with API key:", @sign_in_ui.output
|
292
261
|
end
|
293
262
|
|
294
|
-
def
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
if webauthn_url
|
300
|
-
HTTPResponseFactory.create(body: webauthn_url, code: 200, msg: "OK")
|
301
|
-
else
|
302
|
-
HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
|
303
|
-
end
|
263
|
+
def test_sign_in_with_webauthn_enabled_with_polling
|
264
|
+
server = Gem::MockTCPServer.new
|
265
|
+
@fetcher.respond_with_require_otp
|
266
|
+
@fetcher.respond_with_webauthn_url
|
267
|
+
@fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
|
304
268
|
|
305
|
-
|
306
|
-
|
307
|
-
else
|
308
|
-
host = Gem.host
|
269
|
+
TCPServer.stub(:new, server) do
|
270
|
+
util_sign_in
|
309
271
|
end
|
310
272
|
|
311
|
-
@fetcher
|
312
|
-
|
313
|
-
|
314
|
-
|
273
|
+
assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
|
274
|
+
"to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
|
275
|
+
"you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
|
276
|
+
assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
|
277
|
+
assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_sign_in_with_webauthn_enabled_with_polling_failure
|
281
|
+
server = Gem::MockTCPServer.new
|
282
|
+
@fetcher.respond_with_require_otp
|
283
|
+
@fetcher.respond_with_webauthn_url
|
284
|
+
@fetcher.respond_with_webauthn_polling_failure
|
285
|
+
|
286
|
+
assert_raise Gem::MockGemUi::TermError do
|
287
|
+
TCPServer.stub(:new, server) do
|
288
|
+
util_sign_in
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
|
293
|
+
"to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
|
294
|
+
"you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
|
295
|
+
assert_match "ERROR: Security device verification failed: " \
|
296
|
+
"The token in the link you used has either expired or been used already.", @sign_in_ui.error
|
297
|
+
end
|
298
|
+
|
299
|
+
def util_sign_in(args: [], extra_input: "")
|
300
|
+
email = "you@example.com"
|
301
|
+
password = "secret"
|
302
|
+
|
303
|
+
ENV["RUBYGEMS_HOST"] = @fetcher.host
|
315
304
|
Gem::RemoteFetcher.fetcher = @fetcher
|
316
305
|
|
317
306
|
@sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input)
|
@@ -341,4 +330,29 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
341
330
|
@cmd.verify_api_key :missing
|
342
331
|
end
|
343
332
|
end
|
333
|
+
|
334
|
+
class SignInFetcher < Gem::MultifactorAuthFetcher
|
335
|
+
attr_reader :api_key
|
336
|
+
|
337
|
+
def initialize(host: nil)
|
338
|
+
super(host: host)
|
339
|
+
@api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
|
340
|
+
@data["#{@host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: @api_key, code: 200, msg: "OK")
|
341
|
+
@data["#{@host}/api/v1/profile/me.yaml"] = Gem::HTTPResponseFactory.create(body: "mfa: disabled\n", code: 200, msg: "OK")
|
342
|
+
end
|
343
|
+
|
344
|
+
def respond_with_require_otp
|
345
|
+
super("#{host}/api/v1/api_key", @api_key)
|
346
|
+
end
|
347
|
+
|
348
|
+
def respond_with_forbidden_api_key_response
|
349
|
+
@data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: "Access Denied.", code: 403, msg: "Forbidden")
|
350
|
+
end
|
351
|
+
|
352
|
+
def respond_with_unauthorized_api_key_response
|
353
|
+
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
|
354
|
+
|
355
|
+
@data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
|
356
|
+
end
|
357
|
+
end
|
344
358
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "installer_test_case"
|
3
4
|
|
4
5
|
class TestGemInstaller < Gem::InstallerTestCase
|
@@ -1541,7 +1542,7 @@ end
|
|
1541
1542
|
|
1542
1543
|
def test_install_extension_and_script
|
1543
1544
|
pend "Makefile creation crashes on jruby" if Gem.java_platform?
|
1544
|
-
pend
|
1545
|
+
pend "terminates on mswin" if vc_windows? && ruby_repo?
|
1545
1546
|
|
1546
1547
|
@spec = setup_base_spec
|
1547
1548
|
@spec.extensions << "extconf.rb"
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "helper"
|
3
4
|
require "rubygems/request"
|
4
5
|
require "ostruct"
|
5
|
-
require "base64"
|
6
6
|
|
7
7
|
unless Gem::HAVE_OPENSSL
|
8
8
|
warn "Skipping Gem::Request tests. openssl not found."
|
@@ -20,6 +20,12 @@ class TestGemRequest < Gem::TestCase
|
|
20
20
|
Gem::Request.create_with_proxy uri, request_class, last_modified, proxy
|
21
21
|
end
|
22
22
|
|
23
|
+
# This method is same code as Base64.encode64
|
24
|
+
# We should not use Base64.encode64 because we need to avoid gem activation.
|
25
|
+
def base64_encode64(bin)
|
26
|
+
[bin].pack("m")
|
27
|
+
end
|
28
|
+
|
23
29
|
def setup
|
24
30
|
@proxies = %w[http_proxy https_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY]
|
25
31
|
@old_proxies = @proxies.map {|k| ENV[k] }
|
@@ -208,7 +214,7 @@ class TestGemRequest < Gem::TestCase
|
|
208
214
|
end
|
209
215
|
|
210
216
|
auth_header = conn.payload["Authorization"]
|
211
|
-
assert_equal "Basic #{
|
217
|
+
assert_equal "Basic #{base64_encode64('user:pass')}".strip, auth_header
|
212
218
|
assert_includes @ui.output, "GET https://user:REDACTED@example.rubygems/specs.#{Gem.marshal_version}"
|
213
219
|
end
|
214
220
|
|
@@ -225,7 +231,7 @@ class TestGemRequest < Gem::TestCase
|
|
225
231
|
end
|
226
232
|
|
227
233
|
auth_header = conn.payload["Authorization"]
|
228
|
-
assert_equal "Basic #{
|
234
|
+
assert_equal "Basic #{base64_encode64('user:{DEScede}pass')}".strip, auth_header
|
229
235
|
assert_includes @ui.output, "GET https://user:REDACTED@example.rubygems/specs.#{Gem.marshal_version}"
|
230
236
|
end
|
231
237
|
|
@@ -242,7 +248,7 @@ class TestGemRequest < Gem::TestCase
|
|
242
248
|
end
|
243
249
|
|
244
250
|
auth_header = conn.payload["Authorization"]
|
245
|
-
assert_equal "Basic #{
|
251
|
+
assert_equal "Basic #{base64_encode64('{DEScede}pass:x-oauth-basic')}".strip, auth_header
|
246
252
|
assert_includes @ui.output, "GET https://REDACTED:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}"
|
247
253
|
end
|
248
254
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "helper"
|
3
4
|
require "rubygems/installer"
|
4
5
|
|
@@ -63,7 +64,7 @@ class TestGemResolverGitSpecification < Gem::TestCase
|
|
63
64
|
|
64
65
|
def test_install_extension
|
65
66
|
pend if Gem.java_platform?
|
66
|
-
pend
|
67
|
+
pend "terminates on mswin" if vc_windows? && ruby_repo?
|
67
68
|
name, _, repository, = git_gem "a", 1 do |s|
|
68
69
|
s.extensions << "ext/extconf.rb"
|
69
70
|
end
|