rubygems-update 3.3.26 → 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 +1334 -1088
- data/CONTRIBUTING.md +31 -8
- data/Manifest.txt +49 -35
- data/POLICIES.md +15 -13
- data/README.md +19 -6
- data/bundler/CHANGELOG.md +290 -1
- data/bundler/README.md +3 -6
- data/bundler/UPGRADING.md +1 -1
- data/bundler/bundler.gemspec +2 -2
- data/bundler/exe/bundle +5 -16
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/add.rb +1 -1
- data/bundler/lib/bundler/cli/binstubs.rb +5 -1
- data/bundler/lib/bundler/cli/check.rb +1 -1
- data/bundler/lib/bundler/cli/common.rb +1 -0
- data/bundler/lib/bundler/cli/console.rb +2 -2
- data/bundler/lib/bundler/cli/doctor.rb +4 -6
- data/bundler/lib/bundler/cli/gem.rb +62 -40
- data/bundler/lib/bundler/cli/init.rb +2 -2
- data/bundler/lib/bundler/cli/install.rb +2 -3
- data/bundler/lib/bundler/cli/lock.rb +8 -5
- data/bundler/lib/bundler/cli/open.rb +6 -4
- data/bundler/lib/bundler/cli/outdated.rb +1 -3
- data/bundler/lib/bundler/cli/viz.rb +1 -1
- data/bundler/lib/bundler/cli.rb +45 -2
- data/bundler/lib/bundler/compact_index_client/cache.rb +1 -1
- data/bundler/lib/bundler/compact_index_client/updater.rb +40 -39
- data/bundler/lib/bundler/constants.rb +1 -1
- data/bundler/lib/bundler/current_ruby.rb +2 -0
- data/bundler/lib/bundler/definition.rb +163 -82
- data/bundler/lib/bundler/dependency.rb +13 -12
- data/bundler/lib/bundler/digest.rb +1 -1
- data/bundler/lib/bundler/dsl.rb +3 -3
- data/bundler/lib/bundler/endpoint_specification.rb +0 -4
- data/bundler/lib/bundler/env.rb +1 -1
- data/bundler/lib/bundler/environment_preserver.rb +3 -2
- data/bundler/lib/bundler/errors.rb +1 -11
- data/bundler/lib/bundler/feature_flag.rb +0 -1
- data/bundler/lib/bundler/fetcher/compact_index.rb +9 -11
- data/bundler/lib/bundler/fetcher/dependency.rb +2 -6
- data/bundler/lib/bundler/fetcher/downloader.rb +2 -5
- data/bundler/lib/bundler/fetcher.rb +4 -8
- data/bundler/lib/bundler/force_platform.rb +18 -0
- data/bundler/lib/bundler/friendly_errors.rb +0 -3
- data/bundler/lib/bundler/gem_version_promoter.rb +52 -86
- data/bundler/lib/bundler/graph.rb +3 -3
- data/bundler/lib/bundler/index.rb +7 -15
- data/bundler/lib/bundler/injector.rb +2 -2
- data/bundler/lib/bundler/inline.rb +8 -10
- data/bundler/lib/bundler/installer/parallel_installer.rb +3 -33
- data/bundler/lib/bundler/installer/standalone.rb +12 -8
- data/bundler/lib/bundler/installer.rb +10 -24
- data/bundler/lib/bundler/lazy_specification.rb +42 -42
- data/bundler/lib/bundler/lockfile_generator.rb +2 -2
- data/bundler/lib/bundler/lockfile_parser.rb +17 -16
- 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 +3 -3
- data/bundler/lib/bundler/man/bundle-cache.1.ronn +2 -2
- 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 +2 -5
- data/bundler/lib/bundler/man/bundle-config.1.ronn +1 -4
- 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 +5 -5
- data/bundler/lib/bundler/man/bundle-exec.1.ronn +5 -5
- data/bundler/lib/bundler/man/bundle-gem.1 +27 -37
- data/bundler/lib/bundler/man/bundle-gem.1.ronn +5 -5
- data/bundler/lib/bundler/man/bundle-help.1 +1 -1
- data/bundler/lib/bundler/man/bundle-info.1 +1 -1
- data/bundler/lib/bundler/man/bundle-init.1 +5 -1
- data/bundler/lib/bundler/man/bundle-init.1.ronn +2 -0
- data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
- data/bundler/lib/bundler/man/bundle-install.1 +1 -30
- data/bundler/lib/bundler/man/bundle-install.1.ronn +0 -29
- 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 +22 -2
- data/bundler/lib/bundler/man/bundle-open.1.ronn +9 -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 +2 -2
- data/bundler/lib/bundler/man/bundle-platform.1.ronn +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 +2 -2
- data/bundler/lib/bundler/man/gemfile.5.ronn +1 -1
- data/bundler/lib/bundler/mirror.rb +5 -7
- data/bundler/lib/bundler/plugin/index.rb +4 -4
- data/bundler/lib/bundler/plugin/installer/rubygems.rb +0 -4
- data/bundler/lib/bundler/plugin/installer.rb +5 -2
- data/bundler/lib/bundler/plugin.rb +1 -1
- data/bundler/lib/bundler/remote_specification.rb +2 -6
- data/bundler/lib/bundler/resolver/base.rb +72 -15
- data/bundler/lib/bundler/resolver/candidate.rb +94 -0
- data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
- data/bundler/lib/bundler/resolver/package.rb +72 -0
- data/bundler/lib/bundler/resolver/root.rb +25 -0
- data/bundler/lib/bundler/resolver/spec_group.rb +26 -36
- data/bundler/lib/bundler/resolver.rb +324 -277
- data/bundler/lib/bundler/ruby_version.rb +1 -1
- data/bundler/lib/bundler/rubygems_ext.rb +16 -9
- data/bundler/lib/bundler/rubygems_gem_installer.rb +4 -2
- data/bundler/lib/bundler/rubygems_integration.rb +10 -14
- data/bundler/lib/bundler/runtime.rb +2 -6
- data/bundler/lib/bundler/safe_marshal.rb +31 -0
- data/bundler/lib/bundler/settings.rb +4 -10
- data/bundler/lib/bundler/setup.rb +4 -1
- data/bundler/lib/bundler/shared_helpers.rb +2 -1
- data/bundler/lib/bundler/source/git/git_proxy.rb +237 -74
- data/bundler/lib/bundler/source/git.rb +48 -30
- data/bundler/lib/bundler/source/metadata.rb +0 -1
- data/bundler/lib/bundler/source/path/installer.rb +1 -22
- data/bundler/lib/bundler/source/path.rb +6 -6
- data/bundler/lib/bundler/source/rubygems.rb +26 -81
- data/bundler/lib/bundler/source.rb +1 -1
- data/bundler/lib/bundler/source_list.rb +8 -2
- data/bundler/lib/bundler/spec_set.rb +22 -14
- data/bundler/lib/bundler/templates/Executable +1 -1
- data/bundler/lib/bundler/templates/Executable.bundler +5 -10
- data/bundler/lib/bundler/templates/Executable.standalone +2 -0
- data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
- data/bundler/lib/bundler/templates/newgem/Gemfile.tt +3 -0
- data/bundler/lib/bundler/templates/newgem/README.md.tt +6 -4
- data/bundler/lib/bundler/templates/newgem/Rakefile.tt +12 -1
- data/bundler/lib/bundler/templates/newgem/bin/console.tt +0 -4
- data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
- data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
- data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
- data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
- data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +8 -0
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +9 -2
- data/bundler/lib/bundler/ui/shell.rb +35 -12
- data/bundler/lib/bundler/ui/silent.rb +21 -5
- data/bundler/lib/bundler/uri_normalizer.rb +23 -0
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1351 -409
- data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
- data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +60 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +248 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
- data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
- data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +15 -9
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +11 -6
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri.rb +3 -2
- data/bundler/lib/bundler/vendored_persistent.rb +1 -33
- data/bundler/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
- data/bundler/lib/bundler/version.rb +5 -1
- data/bundler/lib/bundler/worker.rb +5 -7
- data/bundler/lib/bundler.rb +21 -72
- data/{bin → exe}/gem +3 -4
- data/{bin → exe}/update_rubygems +8 -6
- 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 +16 -7
- data/lib/rubygems/command_manager.rb +23 -8
- data/lib/rubygems/commands/build_command.rb +4 -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 +249 -0
- data/lib/rubygems/commands/fetch_command.rb +2 -1
- data/lib/rubygems/commands/generate_index_command.rb +1 -0
- data/lib/rubygems/commands/help_command.rb +4 -3
- data/lib/rubygems/commands/install_command.rb +8 -3
- 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 +6 -3
- data/lib/rubygems/commands/pristine_command.rb +10 -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 +4 -2
- 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 +4 -3
- 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 +4 -0
- data/lib/rubygems/commands/unpack_command.rb +2 -1
- data/lib/rubygems/commands/update_command.rb +2 -7
- data/lib/rubygems/commands/which_command.rb +1 -0
- data/lib/rubygems/commands/yank_command.rb +1 -0
- data/lib/rubygems/config_file.rb +34 -0
- data/lib/rubygems/core_ext/kernel_gem.rb +0 -5
- data/lib/rubygems/core_ext/kernel_require.rb +108 -114
- data/lib/rubygems/core_ext/kernel_warn.rb +33 -37
- data/lib/rubygems/core_ext/tcpsocket_init.rb +2 -0
- data/lib/rubygems/defaults.rb +17 -2
- data/lib/rubygems/dependency.rb +6 -2
- data/lib/rubygems/dependency_installer.rb +25 -24
- data/lib/rubygems/dependency_list.rb +1 -0
- data/lib/rubygems/deprecate.rb +3 -2
- data/lib/rubygems/doctor.rb +1 -0
- data/lib/rubygems/errors.rb +1 -0
- data/lib/rubygems/exceptions.rb +11 -3
- data/lib/rubygems/ext/build_error.rb +1 -0
- data/lib/rubygems/ext/builder.rb +23 -7
- data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +9 -5
- data/lib/rubygems/ext/cargo_builder.rb +145 -110
- data/lib/rubygems/ext/configure_builder.rb +1 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +4 -2
- data/lib/rubygems/ext/rake_builder.rb +5 -3
- 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 +53 -6
- data/lib/rubygems/indexer.rb +2 -1
- 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 +22 -6
- 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/optparse/lib/optparse.rb +20 -15
- 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 +13 -12
- data/lib/rubygems/package/tar_reader/entry.rb +89 -7
- data/lib/rubygems/package/tar_reader.rb +1 -28
- 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 +4 -5
- 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 +105 -105
- 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 +3 -2
- data/lib/rubygems/requirement.rb +9 -8
- 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 +5 -2
- 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/lib/molinillo/dependency_graph.rb +1 -1
- data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +32 -26
- data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +1 -1
- 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 +2 -1
- 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 +41 -40
- data/lib/rubygems/security/policy.rb +1 -0
- data/lib/rubygems/security/signer.rb +1 -0
- data/lib/rubygems/security/trust_dir.rb +2 -1
- data/lib/rubygems/security.rb +4 -16
- data/lib/rubygems/security_option.rb +1 -0
- data/lib/rubygems/shellwords.rb +3 -0
- data/lib/rubygems/source/git.rb +1 -1
- 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/source.rb +2 -2
- data/lib/rubygems/spec_fetcher.rb +1 -0
- data/lib/rubygems/specification.rb +58 -52
- data/lib/rubygems/specification_policy.rb +21 -0
- data/lib/rubygems/stub_specification.rb +10 -8
- data/lib/rubygems/text.rb +2 -2
- data/lib/rubygems/tsort/lib/tsort.rb +308 -310
- data/lib/rubygems/uninstaller.rb +1 -0
- data/lib/rubygems/update_suggestion.rb +69 -0
- data/lib/rubygems/user_interaction.rb +2 -0
- data/lib/rubygems/util/licenses.rb +3 -2
- data/lib/rubygems/util/list.rb +1 -0
- data/lib/rubygems/util.rb +2 -5
- data/lib/rubygems/validator.rb +2 -1
- data/lib/rubygems/version.rb +2 -2
- data/lib/rubygems/version_option.rb +1 -0
- data/lib/rubygems.rb +32 -11
- data/rubygems-update.gemspec +6 -4
- data/setup.rb +1 -0
- data/test/rubygems/bad_rake.rb +1 -0
- data/test/rubygems/bundler_test_gem.rb +421 -0
- data/test/rubygems/fake_certlib/openssl.rb +1 -0
- data/test/rubygems/good_rake.rb +1 -0
- data/test/rubygems/helper.rb +23 -6
- 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 +51 -15
- 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 +2 -1
- 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 +3 -2
- data/test/rubygems/test_config.rb +2 -1
- data/test/rubygems/test_deprecate.rb +2 -1
- data/test/rubygems/test_exit.rb +7 -1
- data/test/rubygems/test_gem.rb +41 -421
- data/test/rubygems/test_gem_available_set.rb +1 -0
- data/test/rubygems/test_gem_bundler_version_finder.rb +5 -3
- data/test/rubygems/test_gem_command.rb +1 -0
- data/test/rubygems/test_gem_command_manager.rb +67 -1
- data/test/rubygems/test_gem_commands_build_command.rb +11 -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 +853 -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 +21 -1
- 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 +103 -7
- data/test/rubygems/test_gem_commands_pristine_command.rb +50 -1
- data/test/rubygems/test_gem_commands_push_command.rb +110 -6
- 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 +4 -11
- 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 +32 -14
- data/test/rubygems/test_gem_commands_unpack_command.rb +1 -0
- data/test/rubygems/test_gem_commands_update_command.rb +7 -6
- data/test/rubygems/test_gem_commands_which_command.rb +1 -0
- data/test/rubygems/test_gem_commands_yank_command.rb +120 -1
- data/test/rubygems/test_gem_config_file.rb +2 -1
- data/test/rubygems/test_gem_dependency.rb +3 -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 +7 -8
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +4 -4
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/{Cargo.lock → ext/custom_name_lib/Cargo.lock} +22 -32
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/{Cargo.toml → ext/custom_name_lib/Cargo.toml} +1 -1
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/{src → ext/custom_name_lib/src}/lib.rs +1 -1
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +3 -0
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +36 -32
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +1 -1
- 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/rust_ruby_example/src/lib.rs +12 -0
- data/test/rubygems/test_gem_ext_cargo_builder.rb +33 -44
- data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +17 -16
- data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +5 -20
- 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 +8 -2
- data/test/rubygems/test_gem_gemcutter_utilities.rb +130 -48
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +1 -0
- data/test/rubygems/test_gem_indexer.rb +40 -20
- data/test/rubygems/test_gem_install_update_options.rb +1 -0
- data/test/rubygems/test_gem_installer.rb +120 -5
- 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.rb +0 -25
- data/test/rubygems/test_gem_package_old.rb +1 -0
- data/test/rubygems/test_gem_package_tar_header.rb +14 -13
- data/test/rubygems/test_gem_package_tar_reader.rb +49 -1
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +152 -6
- 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 +60 -60
- data/test/rubygems/test_gem_rdoc.rb +1 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +6 -5
- 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 +3 -2
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +11 -10
- data/test/rubygems/test_gem_request_set_lockfile.rb +1 -0
- data/test/rubygems/test_gem_request_set_lockfile_parser.rb +7 -6
- data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +1 -0
- data/test/rubygems/test_gem_requirement.rb +2 -1
- 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 +13 -12
- data/test/rubygems/test_gem_resolver_api_specification.rb +20 -19
- 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 +10 -9
- data/test/rubygems/test_gem_resolver_git_specification.rb +3 -2
- 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_policy.rb +10 -10
- data/test/rubygems/test_gem_security_signer.rb +1 -0
- data/test/rubygems/test_gem_security_trust_dir.rb +3 -2
- data/test/rubygems/test_gem_silent_ui.rb +1 -0
- data/test/rubygems/test_gem_source.rb +2 -1
- data/test/rubygems/test_gem_source_fetch_problem.rb +1 -0
- data/test/rubygems/test_gem_source_git.rb +14 -12
- data/test/rubygems/test_gem_source_installed.rb +2 -1
- 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 +4 -3
- 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 +2 -1
- data/test/rubygems/test_gem_spec_fetcher.rb +1 -0
- data/test/rubygems/test_gem_specification.rb +95 -39
- 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 +6 -5
- data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +1 -0
- data/test/rubygems/test_gem_update_suggestion.rb +209 -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 +3 -2
- data/test/rubygems/test_gem_version_option.rb +1 -0
- data/test/rubygems/test_kernel.rb +12 -17
- data/test/rubygems/test_project_sanity.rb +32 -3
- data/test/rubygems/test_remote_fetch_error.rb +2 -1
- data/test/rubygems/test_require.rb +70 -55
- data/test/rubygems/test_rubygems.rb +2 -0
- data/test/rubygems/test_webauthn_listener.rb +143 -0
- data/test/rubygems/test_webauthn_listener_response.rb +93 -0
- data/test/rubygems/test_webauthn_poller.rb +124 -0
- data/test/rubygems/utilities.rb +45 -3
- data/test/test_changelog_generator.rb +1 -1
- metadata +59 -43
- data/bundler/lib/bundler/templates/gems.rb +0 -5
- data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +0 -5
- data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -6
- data/bundler/lib/bundler/vendor/molinillo/LICENSE +0 -9
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
- data/bundler/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
- data/bundler/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
- data/bundler/lib/bundler/vendored_molinillo.rb +0 -4
- data/bundler/lib/bundler/version_ranges.rb +0 -122
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb +0 -21
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb +0 -21
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "webauthn_listener/response"
|
4
|
+
|
5
|
+
##
|
6
|
+
# The WebauthnListener class retrieves an OTP after a user successfully WebAuthns with the Gem host.
|
7
|
+
# An instance opens a socket using the TCPServer instance given and listens for a request from the Gem host.
|
8
|
+
# The request should be a GET request to the root path and contains the OTP code in the form
|
9
|
+
# of a query parameter `code`. The listener will return the code which will be used as the OTP for
|
10
|
+
# API requests.
|
11
|
+
#
|
12
|
+
# Types of responses sent by the listener after receiving a request:
|
13
|
+
# - 200 OK: OTP code was successfully retrieved
|
14
|
+
# - 204 No Content: If the request was an OPTIONS request
|
15
|
+
# - 400 Bad Request: If the request did not contain a query parameter `code`
|
16
|
+
# - 404 Not Found: The request was not to the root path
|
17
|
+
# - 405 Method Not Allowed: OTP code was not retrieved because the request was not a GET/OPTIONS request
|
18
|
+
#
|
19
|
+
# Example usage:
|
20
|
+
#
|
21
|
+
# thread = Gem::WebauthnListener.listener_thread("https://rubygems.example", server)
|
22
|
+
# thread.join
|
23
|
+
# otp = thread[:otp]
|
24
|
+
# error = thread[:error]
|
25
|
+
#
|
26
|
+
|
27
|
+
module Gem::GemcutterUtilities
|
28
|
+
class WebauthnListener
|
29
|
+
attr_reader :host
|
30
|
+
|
31
|
+
def initialize(host)
|
32
|
+
@host = host
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.listener_thread(host, server)
|
36
|
+
Thread.new do
|
37
|
+
thread = Thread.current
|
38
|
+
thread.abort_on_exception = true
|
39
|
+
thread.report_on_exception = false
|
40
|
+
thread[:otp] = new(host).wait_for_otp_code(server)
|
41
|
+
rescue Gem::WebauthnVerificationError => e
|
42
|
+
thread[:error] = e
|
43
|
+
ensure
|
44
|
+
server.close
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def wait_for_otp_code(server)
|
49
|
+
loop do
|
50
|
+
socket = server.accept
|
51
|
+
request_line = socket.gets
|
52
|
+
|
53
|
+
method, req_uri, _protocol = request_line.split(" ")
|
54
|
+
req_uri = URI.parse(req_uri)
|
55
|
+
|
56
|
+
responder = SocketResponder.new(socket)
|
57
|
+
|
58
|
+
unless root_path?(req_uri)
|
59
|
+
responder.send(NotFoundResponse.for(host))
|
60
|
+
raise Gem::WebauthnVerificationError, "Page at #{req_uri.path} not found."
|
61
|
+
end
|
62
|
+
|
63
|
+
case method.upcase
|
64
|
+
when "OPTIONS"
|
65
|
+
responder.send(NoContentResponse.for(host))
|
66
|
+
next # will be GET
|
67
|
+
when "GET"
|
68
|
+
if otp = parse_otp_from_uri(req_uri)
|
69
|
+
responder.send(OkResponse.for(host))
|
70
|
+
return otp
|
71
|
+
end
|
72
|
+
responder.send(BadRequestResponse.for(host))
|
73
|
+
raise Gem::WebauthnVerificationError, "Did not receive OTP from #{host}."
|
74
|
+
else
|
75
|
+
responder.send(MethodNotAllowedResponse.for(host))
|
76
|
+
raise Gem::WebauthnVerificationError, "Invalid HTTP method #{method.upcase} received."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def root_path?(uri)
|
84
|
+
uri.path == "/"
|
85
|
+
end
|
86
|
+
|
87
|
+
def parse_otp_from_uri(uri)
|
88
|
+
require "cgi"
|
89
|
+
|
90
|
+
return if uri.query.nil?
|
91
|
+
CGI.parse(uri.query).dig("code", 0)
|
92
|
+
end
|
93
|
+
|
94
|
+
class SocketResponder
|
95
|
+
def initialize(socket)
|
96
|
+
@socket = socket
|
97
|
+
end
|
98
|
+
|
99
|
+
def send(response)
|
100
|
+
@socket.print response.to_s
|
101
|
+
@socket.close
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# The WebauthnPoller class retrieves an OTP after a user successfully WebAuthns. An instance
|
5
|
+
# polls the Gem host for the OTP code. The polling request (api/v1/webauthn_verification/<webauthn_token>/status.json)
|
6
|
+
# is sent to the Gem host every 5 seconds and will timeout after 5 minutes. If the status field in the json response
|
7
|
+
# is "success", the code field will contain the OTP code.
|
8
|
+
#
|
9
|
+
# Example usage:
|
10
|
+
#
|
11
|
+
# thread = Gem::WebauthnPoller.poll_thread(
|
12
|
+
# {},
|
13
|
+
# "RubyGems.org",
|
14
|
+
# "https://rubygems.org/api/v1/webauthn_verification/odow34b93t6aPCdY",
|
15
|
+
# { email: "email@example.com", password: "password" }
|
16
|
+
# )
|
17
|
+
# thread.join
|
18
|
+
# otp = thread[:otp]
|
19
|
+
# error = thread[:error]
|
20
|
+
#
|
21
|
+
|
22
|
+
module Gem::GemcutterUtilities
|
23
|
+
class WebauthnPoller
|
24
|
+
include Gem::GemcutterUtilities
|
25
|
+
TIMEOUT_IN_SECONDS = 300
|
26
|
+
|
27
|
+
attr_reader :options, :host
|
28
|
+
|
29
|
+
def initialize(options, host)
|
30
|
+
@options = options
|
31
|
+
@host = host
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.poll_thread(options, host, webauthn_url, credentials)
|
35
|
+
Thread.new do
|
36
|
+
thread = Thread.current
|
37
|
+
thread.abort_on_exception = true
|
38
|
+
thread.report_on_exception = false
|
39
|
+
thread[:otp] = new(options, host).poll_for_otp(webauthn_url, credentials)
|
40
|
+
rescue Gem::WebauthnVerificationError, Timeout::Error => e
|
41
|
+
thread[:error] = e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def poll_for_otp(webauthn_url, credentials)
|
46
|
+
Timeout.timeout(TIMEOUT_IN_SECONDS) do
|
47
|
+
loop do
|
48
|
+
response = webauthn_verification_poll_response(webauthn_url, credentials)
|
49
|
+
raise Gem::WebauthnVerificationError, response.message unless response.is_a?(Net::HTTPSuccess)
|
50
|
+
|
51
|
+
require "json"
|
52
|
+
parsed_response = JSON.parse(response.body)
|
53
|
+
case parsed_response["status"]
|
54
|
+
when "pending"
|
55
|
+
sleep 5
|
56
|
+
when "success"
|
57
|
+
return parsed_response["code"]
|
58
|
+
else
|
59
|
+
raise Gem::WebauthnVerificationError, parsed_response.fetch("message", "Invalid response from server")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def webauthn_verification_poll_response(webauthn_url, credentials)
|
68
|
+
webauthn_token = %r{(?<=\/)[^\/]+(?=$)}.match(webauthn_url)[0]
|
69
|
+
rubygems_api_request(:get, "api/v1/webauthn_verification/#{webauthn_token}/status.json") do |request|
|
70
|
+
if credentials.empty?
|
71
|
+
request.add_field "Authorization", api_key
|
72
|
+
else
|
73
|
+
request.basic_auth credentials[:email], credentials[:password]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "remote_fetcher"
|
3
4
|
require_relative "text"
|
5
|
+
require_relative "gemcutter_utilities/webauthn_listener"
|
6
|
+
require_relative "gemcutter_utilities/webauthn_poller"
|
4
7
|
|
5
8
|
##
|
6
9
|
# Utility methods for using the RubyGems API.
|
@@ -82,7 +85,7 @@ module Gem::GemcutterUtilities
|
|
82
85
|
#
|
83
86
|
# If +allowed_push_host+ metadata is present, then it will only allow that host.
|
84
87
|
|
85
|
-
def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, scope: nil, &block)
|
88
|
+
def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, scope: nil, credentials: {}, &block)
|
86
89
|
require "net/http"
|
87
90
|
|
88
91
|
self.host = host if host
|
@@ -105,7 +108,7 @@ module Gem::GemcutterUtilities
|
|
105
108
|
response = request_with_otp(method, uri, &block)
|
106
109
|
|
107
110
|
if mfa_unauthorized?(response)
|
108
|
-
|
111
|
+
fetch_otp(credentials)
|
109
112
|
response = request_with_otp(method, uri, &block)
|
110
113
|
end
|
111
114
|
|
@@ -167,11 +170,12 @@ module Gem::GemcutterUtilities
|
|
167
170
|
mfa_params = get_mfa_params(profile)
|
168
171
|
all_params = scope_params.merge(mfa_params)
|
169
172
|
warning = profile["warning"]
|
173
|
+
credentials = { email: email, password: password }
|
170
174
|
|
171
175
|
say "#{warning}\n" if warning
|
172
176
|
|
173
177
|
response = rubygems_api_request(:post, "api/v1/api_key",
|
174
|
-
sign_in_host, scope: scope) do |request|
|
178
|
+
sign_in_host, credentials: credentials, scope: scope) do |request|
|
175
179
|
request.basic_auth email, password
|
176
180
|
request["OTP"] = otp if otp
|
177
181
|
request.body = URI.encode_www_form({ name: key_name }.merge(all_params))
|
@@ -250,9 +254,52 @@ module Gem::GemcutterUtilities
|
|
250
254
|
end
|
251
255
|
end
|
252
256
|
|
253
|
-
def
|
254
|
-
|
255
|
-
|
257
|
+
def fetch_otp(credentials)
|
258
|
+
options[:otp] = if webauthn_url = webauthn_verification_url(credentials)
|
259
|
+
server = TCPServer.new 0
|
260
|
+
port = server.addr[1].to_s
|
261
|
+
|
262
|
+
url_with_port = "#{webauthn_url}?port=#{port}"
|
263
|
+
say "You have enabled multi-factor authentication. Please visit #{url_with_port} to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin command with the `--otp [your_code]` option."
|
264
|
+
|
265
|
+
threads = [WebauthnListener.listener_thread(host, server), WebauthnPoller.poll_thread(options, host, webauthn_url, credentials)]
|
266
|
+
otp_thread = wait_for_otp_thread(*threads)
|
267
|
+
|
268
|
+
threads.each(&:join)
|
269
|
+
|
270
|
+
if error = otp_thread[:error]
|
271
|
+
alert_error error.message
|
272
|
+
terminate_interaction(1)
|
273
|
+
end
|
274
|
+
|
275
|
+
say "You are verified with a security device. You may close the browser window."
|
276
|
+
otp_thread[:otp]
|
277
|
+
else
|
278
|
+
say "You have enabled multi-factor authentication. Please enter OTP code."
|
279
|
+
ask "Code: "
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def wait_for_otp_thread(*threads)
|
284
|
+
loop do
|
285
|
+
threads.each do |otp_thread|
|
286
|
+
return otp_thread unless otp_thread.alive?
|
287
|
+
end
|
288
|
+
sleep 0.1
|
289
|
+
end
|
290
|
+
ensure
|
291
|
+
threads.each(&:exit)
|
292
|
+
end
|
293
|
+
|
294
|
+
def webauthn_verification_url(credentials)
|
295
|
+
response = rubygems_api_request(:post, "api/v1/webauthn_verification") do |request|
|
296
|
+
if credentials.empty?
|
297
|
+
request.add_field "Authorization", api_key
|
298
|
+
else
|
299
|
+
request.basic_auth credentials[:email], credentials[:password]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
response.is_a?(Net::HTTPSuccess) ? response.body : nil
|
256
303
|
end
|
257
304
|
|
258
305
|
def pretty_host(host)
|
data/lib/rubygems/indexer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative "../rubygems"
|
3
4
|
require_relative "package"
|
4
5
|
require "tmpdir"
|
@@ -397,7 +398,7 @@ class Gem::Indexer
|
|
397
398
|
dst_name = File.join @dest_directory, file # REFACTOR: duped above
|
398
399
|
|
399
400
|
FileUtils.mv src_name, dst_name, :verbose => verbose,
|
400
|
-
|
401
|
+
:force => true
|
401
402
|
|
402
403
|
File.utime newest_mtime, newest_mtime, dst_name
|
403
404
|
end
|
data/lib/rubygems/installer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
#--
|
3
4
|
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
4
5
|
# All rights reserved.
|
@@ -234,8 +235,8 @@ class Gem::Installer
|
|
234
235
|
io.gets # blankline
|
235
236
|
|
236
237
|
# TODO detect a specially formatted comment instead of trying
|
237
|
-
# to
|
238
|
-
next unless io.gets
|
238
|
+
# to find a string inside Ruby code.
|
239
|
+
next unless io.gets.to_s.include?("This file was generated by RubyGems")
|
239
240
|
|
240
241
|
ruby_executable = true
|
241
242
|
existing = io.read.slice(%r{
|
@@ -342,6 +343,8 @@ class Gem::Installer
|
|
342
343
|
|
343
344
|
Gem::Specification.add_spec(spec)
|
344
345
|
|
346
|
+
load_plugin
|
347
|
+
|
345
348
|
run_post_install_hooks
|
346
349
|
|
347
350
|
spec
|
@@ -388,7 +391,7 @@ class Gem::Installer
|
|
388
391
|
# we'll be installing into.
|
389
392
|
|
390
393
|
def installed_specs
|
391
|
-
@
|
394
|
+
@installed_specs ||= begin
|
392
395
|
specs = []
|
393
396
|
|
394
397
|
Gem::Util.glob_files_in_dir("*.gemspec", File.join(gem_home, "specifications")).each do |path|
|
@@ -649,9 +652,9 @@ class Gem::Installer
|
|
649
652
|
|
650
653
|
def process_options # :nodoc:
|
651
654
|
@options = {
|
652
|
-
:bin_dir
|
653
|
-
:env_shebang
|
654
|
-
:force
|
655
|
+
:bin_dir => nil,
|
656
|
+
:env_shebang => false,
|
657
|
+
:force => false,
|
655
658
|
:only_install_dir => false,
|
656
659
|
:post_install_message => true,
|
657
660
|
}.merge options
|
@@ -1002,4 +1005,17 @@ TEXT
|
|
1002
1005
|
""
|
1003
1006
|
end
|
1004
1007
|
end
|
1008
|
+
|
1009
|
+
def load_plugin
|
1010
|
+
specs = Gem::Specification.find_all_by_name(spec.name)
|
1011
|
+
# If old version already exists, this plugin isn't loaded
|
1012
|
+
# immediately. It's for avoiding a case that multiple versions
|
1013
|
+
# are loaded at the same time.
|
1014
|
+
return unless specs.size == 1
|
1015
|
+
|
1016
|
+
plugin_files = spec.plugins.map do |plugin|
|
1017
|
+
File.join(@plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}")
|
1018
|
+
end
|
1019
|
+
Gem.load_plugin_files(plugin_files)
|
1020
|
+
end
|
1005
1021
|
end
|
data/lib/rubygems/mock_gem_ui.rb
CHANGED
data/lib/rubygems/name_tuple.rb
CHANGED
@@ -425,7 +425,7 @@
|
|
425
425
|
# If you have any questions, file a ticket at http://bugs.ruby-lang.org.
|
426
426
|
#
|
427
427
|
class Gem::OptionParser
|
428
|
-
Gem::OptionParser::Version = "0.
|
428
|
+
Gem::OptionParser::Version = "0.3.0"
|
429
429
|
|
430
430
|
# :stopdoc:
|
431
431
|
NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
|
@@ -765,15 +765,15 @@ class Gem::OptionParser
|
|
765
765
|
end
|
766
766
|
|
767
767
|
#
|
768
|
-
# Switch that takes an argument, which does not begin with '-'.
|
768
|
+
# Switch that takes an argument, which does not begin with '-' or is '-'.
|
769
769
|
#
|
770
770
|
class PlacedArgument < self
|
771
771
|
|
772
772
|
#
|
773
|
-
# Returns nil if argument is not present or begins with '-'.
|
773
|
+
# Returns nil if argument is not present or begins with '-' and is not '-'.
|
774
774
|
#
|
775
775
|
def parse(arg, argv, &error)
|
776
|
-
if !(val = arg) and (argv.empty? or /\A
|
776
|
+
if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0]))
|
777
777
|
return nil, block, nil
|
778
778
|
end
|
779
779
|
opt = (val = parse_arg(val, &error))[1]
|
@@ -1148,6 +1148,7 @@ XXX
|
|
1148
1148
|
@summary_indent = indent
|
1149
1149
|
@default_argv = ARGV
|
1150
1150
|
@require_exact = false
|
1151
|
+
@raise_unknown = true
|
1151
1152
|
add_officious
|
1152
1153
|
yield self if block_given?
|
1153
1154
|
end
|
@@ -1225,6 +1226,9 @@ XXX
|
|
1225
1226
|
# abbreviated long option as short option).
|
1226
1227
|
attr_accessor :require_exact
|
1227
1228
|
|
1229
|
+
# Whether to raise at unknown option.
|
1230
|
+
attr_accessor :raise_unknown
|
1231
|
+
|
1228
1232
|
#
|
1229
1233
|
# Heading banner preceding summary.
|
1230
1234
|
#
|
@@ -1502,7 +1506,7 @@ XXX
|
|
1502
1506
|
style = notwice(default_style.guess(arg = o), style, 'style')
|
1503
1507
|
default_pattern, conv = search(:atype, Object) unless default_pattern
|
1504
1508
|
else
|
1505
|
-
desc.push(o)
|
1509
|
+
desc.push(o) if o && !o.empty?
|
1506
1510
|
end
|
1507
1511
|
end
|
1508
1512
|
|
@@ -1639,9 +1643,11 @@ XXX
|
|
1639
1643
|
begin
|
1640
1644
|
sw, = complete(:long, opt, true)
|
1641
1645
|
if require_exact && !sw.long.include?(arg)
|
1646
|
+
throw :terminate, arg unless raise_unknown
|
1642
1647
|
raise InvalidOption, arg
|
1643
1648
|
end
|
1644
1649
|
rescue ParseError
|
1650
|
+
throw :terminate, arg unless raise_unknown
|
1645
1651
|
raise $!.set_option(arg, true)
|
1646
1652
|
end
|
1647
1653
|
begin
|
@@ -1673,6 +1679,7 @@ XXX
|
|
1673
1679
|
end
|
1674
1680
|
end
|
1675
1681
|
rescue ParseError
|
1682
|
+
throw :terminate, arg unless raise_unknown
|
1676
1683
|
raise $!.set_option(arg, true)
|
1677
1684
|
end
|
1678
1685
|
begin
|
@@ -1862,12 +1869,7 @@ XXX
|
|
1862
1869
|
end
|
1863
1870
|
all_candidates.select! {|cand| cand.is_a?(String) }
|
1864
1871
|
checker = DidYouMean::SpellChecker.new(dictionary: all_candidates)
|
1865
|
-
|
1866
|
-
if DidYouMean.respond_to?(:formatter)
|
1867
|
-
DidYouMean.formatter.message_for(suggestions)
|
1868
|
-
else
|
1869
|
-
"\nDid you mean? #{suggestions.join("\n ")}"
|
1870
|
-
end
|
1872
|
+
DidYouMean.formatter.message_for(all_candidates & checker.correct(opt))
|
1871
1873
|
end
|
1872
1874
|
|
1873
1875
|
def candidate(word)
|
@@ -1908,10 +1910,13 @@ XXX
|
|
1908
1910
|
# directory ~/.options, then the basename with '.options' suffix
|
1909
1911
|
# under XDG and Haiku standard places.
|
1910
1912
|
#
|
1911
|
-
|
1913
|
+
# The optional +into+ keyword argument works exactly like that accepted in
|
1914
|
+
# method #parse.
|
1915
|
+
#
|
1916
|
+
def load(filename = nil, into: nil)
|
1912
1917
|
unless filename
|
1913
1918
|
basename = File.basename($0, '.*')
|
1914
|
-
return true if load(File.expand_path(basename, '~/.options')) rescue nil
|
1919
|
+
return true if load(File.expand_path(basename, '~/.options'), into: into) rescue nil
|
1915
1920
|
basename << ".options"
|
1916
1921
|
return [
|
1917
1922
|
# XDG
|
@@ -1923,11 +1928,11 @@ XXX
|
|
1923
1928
|
'~/config/settings',
|
1924
1929
|
].any? {|dir|
|
1925
1930
|
next if !dir or dir.empty?
|
1926
|
-
load(File.expand_path(basename, dir)) rescue nil
|
1931
|
+
load(File.expand_path(basename, dir), into: into) rescue nil
|
1927
1932
|
}
|
1928
1933
|
end
|
1929
1934
|
begin
|
1930
|
-
parse(*
|
1935
|
+
parse(*File.readlines(filename, chomp: true), into: into)
|
1931
1936
|
true
|
1932
1937
|
rescue Errno::ENOENT, Errno::ENOTDIR
|
1933
1938
|
false
|
data/lib/rubygems/package/old.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
#--
|
3
4
|
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
|
4
5
|
# See LICENSE.txt for additional licensing information.
|
@@ -103,22 +104,22 @@ class Gem::Package::TarHeader
|
|
103
104
|
|
104
105
|
fields = header.unpack UNPACK_FORMAT
|
105
106
|
|
106
|
-
new :name
|
107
|
-
:mode
|
108
|
-
:uid
|
109
|
-
:gid
|
110
|
-
:size
|
111
|
-
:mtime
|
107
|
+
new :name => fields.shift,
|
108
|
+
:mode => strict_oct(fields.shift),
|
109
|
+
:uid => oct_or_256based(fields.shift),
|
110
|
+
:gid => oct_or_256based(fields.shift),
|
111
|
+
:size => strict_oct(fields.shift),
|
112
|
+
:mtime => strict_oct(fields.shift),
|
112
113
|
:checksum => strict_oct(fields.shift),
|
113
114
|
:typeflag => fields.shift,
|
114
115
|
:linkname => fields.shift,
|
115
|
-
:magic
|
116
|
-
:version
|
117
|
-
:uname
|
118
|
-
:gname
|
116
|
+
:magic => fields.shift,
|
117
|
+
:version => strict_oct(fields.shift),
|
118
|
+
:uname => fields.shift,
|
119
|
+
:gname => fields.shift,
|
119
120
|
:devmajor => strict_oct(fields.shift),
|
120
121
|
:devminor => strict_oct(fields.shift),
|
121
|
-
:prefix
|
122
|
+
:prefix => fields.shift,
|
122
123
|
|
123
124
|
:empty => empty
|
124
125
|
end
|
@@ -208,7 +209,7 @@ class Gem::Package::TarHeader
|
|
208
209
|
private
|
209
210
|
|
210
211
|
def calculate_checksum(header)
|
211
|
-
header.
|
212
|
+
header.sum(0)
|
212
213
|
end
|
213
214
|
|
214
215
|
def header(checksum = @checksum)
|