rubygems-update 3.4.17 → 3.4.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/Manifest.txt +7 -4
- data/POLICIES.md +2 -2
- data/bundler/CHANGELOG.md +30 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/binstubs.rb +1 -1
- data/bundler/lib/bundler/cli/info.rb +1 -1
- data/bundler/lib/bundler/cli/install.rb +1 -1
- data/bundler/lib/bundler/cli/outdated.rb +1 -1
- data/bundler/lib/bundler/cli/platform.rb +7 -5
- data/bundler/lib/bundler/definition.rb +25 -20
- data/bundler/lib/bundler/dsl.rb +1 -1
- data/bundler/lib/bundler/env.rb +1 -1
- data/bundler/lib/bundler/fetcher/compact_index.rb +3 -3
- data/bundler/lib/bundler/fetcher/downloader.rb +2 -0
- data/bundler/lib/bundler/fetcher/index.rb +1 -2
- data/bundler/lib/bundler/fetcher.rb +11 -1
- data/bundler/lib/bundler/friendly_errors.rb +1 -1
- data/bundler/lib/bundler/gem_helper.rb +3 -4
- data/bundler/lib/bundler/installer/parallel_installer.rb +1 -1
- data/bundler/lib/bundler/man/bundle-add.1 +1 -1
- data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
- data/bundler/lib/bundler/man/bundle-check.1 +1 -1
- data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
- data/bundler/lib/bundler/man/bundle-config.1 +1 -1
- data/bundler/lib/bundler/man/bundle-console.1 +1 -1
- data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
- data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
- data/bundler/lib/bundler/man/bundle-gem.1 +1 -1
- data/bundler/lib/bundler/man/bundle-help.1 +1 -1
- data/bundler/lib/bundler/man/bundle-info.1 +3 -3
- data/bundler/lib/bundler/man/bundle-info.1.ronn +3 -3
- data/bundler/lib/bundler/man/bundle-init.1 +1 -1
- data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
- data/bundler/lib/bundler/man/bundle-install.1 +1 -1
- data/bundler/lib/bundler/man/bundle-list.1 +1 -1
- data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
- data/bundler/lib/bundler/man/bundle-open.1 +1 -1
- data/bundler/lib/bundler/man/bundle-outdated.1 +13 -9
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +12 -9
- data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
- data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
- data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
- data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
- data/bundler/lib/bundler/man/bundle-show.1 +1 -1
- data/bundler/lib/bundler/man/bundle-update.1 +1 -1
- data/bundler/lib/bundler/man/bundle-version.1 +1 -1
- data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
- data/bundler/lib/bundler/man/bundle.1 +1 -1
- data/bundler/lib/bundler/man/gemfile.5 +14 -1
- data/bundler/lib/bundler/man/gemfile.5.ronn +5 -0
- data/bundler/lib/bundler/plugin/index.rb +1 -1
- data/bundler/lib/bundler/ruby_dsl.rb +6 -0
- data/bundler/lib/bundler/ruby_version.rb +2 -2
- data/bundler/lib/bundler/rubygems_integration.rb +1 -1
- data/bundler/lib/bundler/source/git.rb +7 -0
- data/bundler/lib/bundler/source_list.rb +0 -4
- 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/ui/rg_proxy.rb +1 -1
- 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/bundler/lib/bundler.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/bundler_version_finder.rb +1 -1
- 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 +30 -26
- 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 +2 -2
- 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 +2 -1
- 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 +1 -0
- 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 +11 -3
- 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 +4 -2
- 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 +3 -3
- data/rubygems-update.gemspec +5 -4
- 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/helper.rb +1 -1
- 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 +1 -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 +1 -0
- 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 +39 -10
- data/lib/rubygems/webauthn_listener/response.rb +0 -161
- data/lib/rubygems/webauthn_listener.rb +0 -92
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "helper"
|
3
4
|
require "rubygems/ext"
|
4
5
|
require "rubygems/installer"
|
@@ -104,7 +105,7 @@ install:
|
|
104
105
|
end
|
105
106
|
|
106
107
|
def test_build_extensions
|
107
|
-
pend
|
108
|
+
pend "terminates on mswin" if vc_windows? && ruby_repo?
|
108
109
|
@spec.extensions << "ext/extconf.rb"
|
109
110
|
|
110
111
|
ext_dir = File.join @spec.gem_dir, "ext"
|
@@ -140,7 +141,7 @@ install:
|
|
140
141
|
end
|
141
142
|
|
142
143
|
def test_build_extensions_with_gemhome_with_space
|
143
|
-
pend
|
144
|
+
pend "terminates on mswin" if vc_windows? && ruby_repo?
|
144
145
|
new_gemhome = File.join @tempdir, "gem home"
|
145
146
|
File.rename(@gemhome, new_gemhome)
|
146
147
|
@gemhome = new_gemhome
|
@@ -161,7 +162,7 @@ install:
|
|
161
162
|
false
|
162
163
|
end
|
163
164
|
end
|
164
|
-
pend
|
165
|
+
pend "terminates on mswin" if vc_windows? && ruby_repo?
|
165
166
|
|
166
167
|
@spec.extensions << "ext/extconf.rb"
|
167
168
|
|
@@ -100,7 +100,7 @@ class TestGemExtCargoBuilder < Gem::TestCase
|
|
100
100
|
require "tmpdir"
|
101
101
|
|
102
102
|
env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home)
|
103
|
-
gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../
|
103
|
+
gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../exe/gem", __dir__)]
|
104
104
|
|
105
105
|
Dir.mktmpdir("rust_ruby_example") do |dir|
|
106
106
|
built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem"))
|
@@ -122,7 +122,7 @@ class TestGemExtCargoBuilder < Gem::TestCase
|
|
122
122
|
require "tmpdir"
|
123
123
|
|
124
124
|
env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home)
|
125
|
-
gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../
|
125
|
+
gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../exe/gem", __dir__)]
|
126
126
|
|
127
127
|
Dir.mktmpdir("custom_name") do |dir|
|
128
128
|
built_gem = File.expand_path(File.join(dir, "custom_name.gem"))
|
@@ -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"
|