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.
Files changed (376) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Manifest.txt +7 -4
  4. data/POLICIES.md +2 -2
  5. data/bundler/CHANGELOG.md +30 -0
  6. data/bundler/lib/bundler/build_metadata.rb +2 -2
  7. data/bundler/lib/bundler/cli/binstubs.rb +1 -1
  8. data/bundler/lib/bundler/cli/info.rb +1 -1
  9. data/bundler/lib/bundler/cli/install.rb +1 -1
  10. data/bundler/lib/bundler/cli/outdated.rb +1 -1
  11. data/bundler/lib/bundler/cli/platform.rb +7 -5
  12. data/bundler/lib/bundler/definition.rb +25 -20
  13. data/bundler/lib/bundler/dsl.rb +1 -1
  14. data/bundler/lib/bundler/env.rb +1 -1
  15. data/bundler/lib/bundler/fetcher/compact_index.rb +3 -3
  16. data/bundler/lib/bundler/fetcher/downloader.rb +2 -0
  17. data/bundler/lib/bundler/fetcher/index.rb +1 -2
  18. data/bundler/lib/bundler/fetcher.rb +11 -1
  19. data/bundler/lib/bundler/friendly_errors.rb +1 -1
  20. data/bundler/lib/bundler/gem_helper.rb +3 -4
  21. data/bundler/lib/bundler/installer/parallel_installer.rb +1 -1
  22. data/bundler/lib/bundler/man/bundle-add.1 +1 -1
  23. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  24. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  25. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  26. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  27. data/bundler/lib/bundler/man/bundle-config.1 +1 -1
  28. data/bundler/lib/bundler/man/bundle-console.1 +1 -1
  29. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  30. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  31. data/bundler/lib/bundler/man/bundle-gem.1 +1 -1
  32. data/bundler/lib/bundler/man/bundle-help.1 +1 -1
  33. data/bundler/lib/bundler/man/bundle-info.1 +3 -3
  34. data/bundler/lib/bundler/man/bundle-info.1.ronn +3 -3
  35. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  36. data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
  37. data/bundler/lib/bundler/man/bundle-install.1 +1 -1
  38. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  39. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  40. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  41. data/bundler/lib/bundler/man/bundle-outdated.1 +13 -9
  42. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +12 -9
  43. data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
  44. data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
  45. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  46. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  47. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  48. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  49. data/bundler/lib/bundler/man/bundle-version.1 +1 -1
  50. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  51. data/bundler/lib/bundler/man/bundle.1 +1 -1
  52. data/bundler/lib/bundler/man/gemfile.5 +14 -1
  53. data/bundler/lib/bundler/man/gemfile.5.ronn +5 -0
  54. data/bundler/lib/bundler/plugin/index.rb +1 -1
  55. data/bundler/lib/bundler/ruby_dsl.rb +6 -0
  56. data/bundler/lib/bundler/ruby_version.rb +2 -2
  57. data/bundler/lib/bundler/rubygems_integration.rb +1 -1
  58. data/bundler/lib/bundler/source/git.rb +7 -0
  59. data/bundler/lib/bundler/source_list.rb +0 -4
  60. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
  61. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +4 -4
  62. data/bundler/lib/bundler/ui/rg_proxy.rb +1 -1
  63. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1 -1
  64. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +2 -2
  65. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -1
  66. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  67. data/bundler/lib/bundler/version.rb +1 -1
  68. data/bundler/lib/bundler.rb +1 -1
  69. data/{bin → exe}/gem +2 -0
  70. data/{bin → exe}/update_rubygems +7 -5
  71. data/lib/rubygems/available_set.rb +1 -0
  72. data/lib/rubygems/basic_specification.rb +1 -0
  73. data/lib/rubygems/bundler_version_finder.rb +1 -1
  74. data/lib/rubygems/command.rb +1 -0
  75. data/lib/rubygems/command_manager.rb +1 -0
  76. data/lib/rubygems/commands/build_command.rb +1 -0
  77. data/lib/rubygems/commands/cert_command.rb +1 -0
  78. data/lib/rubygems/commands/check_command.rb +1 -0
  79. data/lib/rubygems/commands/cleanup_command.rb +1 -0
  80. data/lib/rubygems/commands/contents_command.rb +1 -0
  81. data/lib/rubygems/commands/dependency_command.rb +1 -0
  82. data/lib/rubygems/commands/environment_command.rb +1 -0
  83. data/lib/rubygems/commands/exec_command.rb +1 -0
  84. data/lib/rubygems/commands/fetch_command.rb +1 -0
  85. data/lib/rubygems/commands/generate_index_command.rb +1 -0
  86. data/lib/rubygems/commands/help_command.rb +1 -0
  87. data/lib/rubygems/commands/install_command.rb +1 -0
  88. data/lib/rubygems/commands/list_command.rb +1 -0
  89. data/lib/rubygems/commands/lock_command.rb +1 -0
  90. data/lib/rubygems/commands/mirror_command.rb +1 -0
  91. data/lib/rubygems/commands/open_command.rb +1 -0
  92. data/lib/rubygems/commands/outdated_command.rb +1 -0
  93. data/lib/rubygems/commands/owner_command.rb +1 -0
  94. data/lib/rubygems/commands/pristine_command.rb +1 -0
  95. data/lib/rubygems/commands/push_command.rb +1 -0
  96. data/lib/rubygems/commands/query_command.rb +1 -0
  97. data/lib/rubygems/commands/rdoc_command.rb +1 -0
  98. data/lib/rubygems/commands/search_command.rb +1 -0
  99. data/lib/rubygems/commands/server_command.rb +1 -0
  100. data/lib/rubygems/commands/setup_command.rb +2 -1
  101. data/lib/rubygems/commands/signin_command.rb +1 -0
  102. data/lib/rubygems/commands/signout_command.rb +1 -0
  103. data/lib/rubygems/commands/sources_command.rb +1 -0
  104. data/lib/rubygems/commands/specification_command.rb +1 -0
  105. data/lib/rubygems/commands/stale_command.rb +1 -0
  106. data/lib/rubygems/commands/uninstall_command.rb +1 -0
  107. data/lib/rubygems/commands/unpack_command.rb +1 -0
  108. data/lib/rubygems/commands/update_command.rb +1 -0
  109. data/lib/rubygems/commands/which_command.rb +1 -0
  110. data/lib/rubygems/commands/yank_command.rb +1 -0
  111. data/lib/rubygems/config_file.rb +1 -0
  112. data/lib/rubygems/core_ext/kernel_require.rb +1 -0
  113. data/lib/rubygems/core_ext/tcpsocket_init.rb +2 -0
  114. data/lib/rubygems/defaults.rb +1 -0
  115. data/lib/rubygems/dependency.rb +1 -0
  116. data/lib/rubygems/dependency_installer.rb +1 -0
  117. data/lib/rubygems/dependency_list.rb +1 -0
  118. data/lib/rubygems/deprecate.rb +1 -0
  119. data/lib/rubygems/doctor.rb +1 -0
  120. data/lib/rubygems/errors.rb +1 -0
  121. data/lib/rubygems/ext/build_error.rb +1 -0
  122. data/lib/rubygems/ext/builder.rb +1 -0
  123. data/lib/rubygems/ext/configure_builder.rb +1 -0
  124. data/lib/rubygems/ext/ext_conf_builder.rb +1 -0
  125. data/lib/rubygems/ext.rb +1 -0
  126. data/lib/rubygems/gem_runner.rb +1 -0
  127. data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +163 -0
  128. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +105 -0
  129. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +78 -0
  130. data/lib/rubygems/gemcutter_utilities.rb +30 -26
  131. data/lib/rubygems/indexer.rb +1 -0
  132. data/lib/rubygems/install_default_message.rb +1 -0
  133. data/lib/rubygems/install_message.rb +1 -0
  134. data/lib/rubygems/install_update_options.rb +1 -0
  135. data/lib/rubygems/installer.rb +1 -0
  136. data/lib/rubygems/local_remote_options.rb +1 -0
  137. data/lib/rubygems/mock_gem_ui.rb +1 -0
  138. data/lib/rubygems/name_tuple.rb +1 -0
  139. data/lib/rubygems/package/digest_io.rb +1 -0
  140. data/lib/rubygems/package/file_source.rb +1 -0
  141. data/lib/rubygems/package/io_source.rb +1 -0
  142. data/lib/rubygems/package/old.rb +1 -0
  143. data/lib/rubygems/package/source.rb +1 -0
  144. data/lib/rubygems/package/tar_header.rb +1 -0
  145. data/lib/rubygems/package/tar_reader/entry.rb +1 -0
  146. data/lib/rubygems/package/tar_reader.rb +1 -0
  147. data/lib/rubygems/package/tar_writer.rb +1 -0
  148. data/lib/rubygems/package.rb +2 -2
  149. data/lib/rubygems/package_task.rb +1 -0
  150. data/lib/rubygems/path_support.rb +1 -0
  151. data/lib/rubygems/platform.rb +1 -0
  152. data/lib/rubygems/psych_tree.rb +1 -0
  153. data/lib/rubygems/rdoc.rb +1 -0
  154. data/lib/rubygems/remote_fetcher.rb +1 -0
  155. data/lib/rubygems/request/http_pool.rb +1 -0
  156. data/lib/rubygems/request/https_pool.rb +1 -0
  157. data/lib/rubygems/request.rb +1 -0
  158. data/lib/rubygems/request_set/gem_dependency_api.rb +1 -0
  159. data/lib/rubygems/request_set/lockfile/parser.rb +2 -1
  160. data/lib/rubygems/request_set/lockfile/tokenizer.rb +2 -0
  161. data/lib/rubygems/request_set/lockfile.rb +1 -0
  162. data/lib/rubygems/request_set.rb +1 -0
  163. data/lib/rubygems/requirement.rb +1 -0
  164. data/lib/rubygems/resolver/activation_request.rb +1 -0
  165. data/lib/rubygems/resolver/api_set.rb +1 -0
  166. data/lib/rubygems/resolver/api_specification.rb +1 -0
  167. data/lib/rubygems/resolver/best_set.rb +1 -0
  168. data/lib/rubygems/resolver/composed_set.rb +1 -0
  169. data/lib/rubygems/resolver/conflict.rb +1 -0
  170. data/lib/rubygems/resolver/current_set.rb +1 -0
  171. data/lib/rubygems/resolver/dependency_request.rb +1 -0
  172. data/lib/rubygems/resolver/git_set.rb +1 -0
  173. data/lib/rubygems/resolver/git_specification.rb +1 -0
  174. data/lib/rubygems/resolver/index_set.rb +1 -0
  175. data/lib/rubygems/resolver/index_specification.rb +1 -0
  176. data/lib/rubygems/resolver/installed_specification.rb +1 -0
  177. data/lib/rubygems/resolver/installer_set.rb +1 -0
  178. data/lib/rubygems/resolver/local_specification.rb +1 -0
  179. data/lib/rubygems/resolver/lock_set.rb +1 -0
  180. data/lib/rubygems/resolver/lock_specification.rb +1 -0
  181. data/lib/rubygems/resolver/molinillo.rb +1 -0
  182. data/lib/rubygems/resolver/requirement_list.rb +1 -0
  183. data/lib/rubygems/resolver/set.rb +1 -0
  184. data/lib/rubygems/resolver/source_set.rb +2 -0
  185. data/lib/rubygems/resolver/spec_specification.rb +1 -0
  186. data/lib/rubygems/resolver/specification.rb +1 -0
  187. data/lib/rubygems/resolver/stats.rb +1 -0
  188. data/lib/rubygems/resolver/vendor_set.rb +1 -0
  189. data/lib/rubygems/resolver/vendor_specification.rb +1 -0
  190. data/lib/rubygems/resolver.rb +1 -0
  191. data/lib/rubygems/s3_uri_signer.rb +4 -2
  192. data/lib/rubygems/safe_yaml.rb +2 -0
  193. data/lib/rubygems/security/policies.rb +1 -0
  194. data/lib/rubygems/security/policy.rb +1 -0
  195. data/lib/rubygems/security/signer.rb +1 -0
  196. data/lib/rubygems/security/trust_dir.rb +1 -0
  197. data/lib/rubygems/security.rb +1 -0
  198. data/lib/rubygems/security_option.rb +1 -0
  199. data/lib/rubygems/source/installed.rb +1 -0
  200. data/lib/rubygems/source/local.rb +1 -0
  201. data/lib/rubygems/source/lock.rb +1 -0
  202. data/lib/rubygems/source/specific_file.rb +1 -0
  203. data/lib/rubygems/source/vendor.rb +1 -0
  204. data/lib/rubygems/spec_fetcher.rb +1 -0
  205. data/lib/rubygems/specification.rb +11 -3
  206. data/lib/rubygems/specification_policy.rb +2 -0
  207. data/lib/rubygems/stub_specification.rb +1 -0
  208. data/lib/rubygems/uninstaller.rb +1 -0
  209. data/lib/rubygems/user_interaction.rb +4 -2
  210. data/lib/rubygems/util/licenses.rb +1 -0
  211. data/lib/rubygems/util/list.rb +1 -0
  212. data/lib/rubygems/util.rb +1 -0
  213. data/lib/rubygems/validator.rb +1 -0
  214. data/lib/rubygems/version_option.rb +1 -0
  215. data/lib/rubygems.rb +3 -3
  216. data/rubygems-update.gemspec +5 -4
  217. data/setup.rb +1 -0
  218. data/test/rubygems/bad_rake.rb +1 -0
  219. data/test/rubygems/bundler_test_gem.rb +3 -1
  220. data/test/rubygems/fake_certlib/openssl.rb +1 -0
  221. data/test/rubygems/good_rake.rb +1 -0
  222. data/test/rubygems/helper.rb +1 -1
  223. data/test/rubygems/installer_test_case.rb +1 -0
  224. data/test/rubygems/multifactor_auth_utilities.rb +111 -0
  225. data/test/rubygems/package/tar_test_case.rb +1 -0
  226. data/test/rubygems/plugin/exception/rubygems_plugin.rb +1 -0
  227. data/test/rubygems/plugin/load/rubygems_plugin.rb +1 -0
  228. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +1 -0
  229. data/test/rubygems/rubygems/commands/crash_command.rb +1 -0
  230. data/test/rubygems/rubygems_plugin.rb +1 -0
  231. data/test/rubygems/simple_gem.rb +1 -0
  232. data/test/rubygems/specifications/bar-0.0.2.gemspec +2 -0
  233. data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +2 -0
  234. data/test/rubygems/test_bundled_ca.rb +1 -0
  235. data/test/rubygems/test_config.rb +1 -0
  236. data/test/rubygems/test_deprecate.rb +1 -0
  237. data/test/rubygems/test_gem.rb +1 -0
  238. data/test/rubygems/test_gem_available_set.rb +1 -0
  239. data/test/rubygems/test_gem_bundler_version_finder.rb +1 -0
  240. data/test/rubygems/test_gem_command.rb +1 -0
  241. data/test/rubygems/test_gem_command_manager.rb +1 -0
  242. data/test/rubygems/test_gem_commands_build_command.rb +1 -0
  243. data/test/rubygems/test_gem_commands_cert_command.rb +1 -0
  244. data/test/rubygems/test_gem_commands_check_command.rb +1 -0
  245. data/test/rubygems/test_gem_commands_cleanup_command.rb +1 -0
  246. data/test/rubygems/test_gem_commands_contents_command.rb +1 -0
  247. data/test/rubygems/test_gem_commands_dependency_command.rb +1 -0
  248. data/test/rubygems/test_gem_commands_environment_command.rb +1 -0
  249. data/test/rubygems/test_gem_commands_exec_command.rb +2 -0
  250. data/test/rubygems/test_gem_commands_fetch_command.rb +1 -0
  251. data/test/rubygems/test_gem_commands_generate_index_command.rb +1 -0
  252. data/test/rubygems/test_gem_commands_help_command.rb +1 -0
  253. data/test/rubygems/test_gem_commands_info_command.rb +1 -0
  254. data/test/rubygems/test_gem_commands_install_command.rb +1 -0
  255. data/test/rubygems/test_gem_commands_list_command.rb +1 -0
  256. data/test/rubygems/test_gem_commands_lock_command.rb +1 -0
  257. data/test/rubygems/test_gem_commands_mirror.rb +1 -0
  258. data/test/rubygems/test_gem_commands_open_command.rb +1 -0
  259. data/test/rubygems/test_gem_commands_outdated_command.rb +1 -0
  260. data/test/rubygems/test_gem_commands_owner_command.rb +68 -39
  261. data/test/rubygems/test_gem_commands_pristine_command.rb +1 -0
  262. data/test/rubygems/test_gem_commands_push_command.rb +68 -37
  263. data/test/rubygems/test_gem_commands_query_command.rb +1 -0
  264. data/test/rubygems/test_gem_commands_search_command.rb +1 -0
  265. data/test/rubygems/test_gem_commands_server_command.rb +1 -0
  266. data/test/rubygems/test_gem_commands_setup_command.rb +1 -1
  267. data/test/rubygems/test_gem_commands_signin_command.rb +1 -0
  268. data/test/rubygems/test_gem_commands_sources_command.rb +1 -0
  269. data/test/rubygems/test_gem_commands_specification_command.rb +1 -0
  270. data/test/rubygems/test_gem_commands_stale_command.rb +1 -0
  271. data/test/rubygems/test_gem_commands_uninstall_command.rb +1 -0
  272. data/test/rubygems/test_gem_commands_unpack_command.rb +1 -0
  273. data/test/rubygems/test_gem_commands_update_command.rb +1 -0
  274. data/test/rubygems/test_gem_commands_which_command.rb +1 -0
  275. data/test/rubygems/test_gem_commands_yank_command.rb +76 -41
  276. data/test/rubygems/test_gem_config_file.rb +1 -0
  277. data/test/rubygems/test_gem_dependency.rb +1 -0
  278. data/test/rubygems/test_gem_dependency_installer.rb +1 -0
  279. data/test/rubygems/test_gem_dependency_list.rb +1 -0
  280. data/test/rubygems/test_gem_dependency_resolution_error.rb +1 -0
  281. data/test/rubygems/test_gem_doctor.rb +1 -0
  282. data/test/rubygems/test_gem_ext_builder.rb +4 -3
  283. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +2 -0
  284. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +2 -0
  285. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +2 -0
  286. data/test/rubygems/test_gem_ext_cargo_builder.rb +2 -2
  287. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +1 -0
  288. data/test/rubygems/test_gem_ext_cmake_builder.rb +1 -0
  289. data/test/rubygems/test_gem_ext_configure_builder.rb +1 -0
  290. data/test/rubygems/test_gem_ext_rake_builder.rb +1 -0
  291. data/test/rubygems/test_gem_gem_runner.rb +1 -0
  292. data/test/rubygems/test_gem_gemcutter_utilities.rb +106 -92
  293. data/test/rubygems/test_gem_impossible_dependencies_error.rb +1 -0
  294. data/test/rubygems/test_gem_indexer.rb +1 -0
  295. data/test/rubygems/test_gem_install_update_options.rb +1 -0
  296. data/test/rubygems/test_gem_installer.rb +2 -1
  297. data/test/rubygems/test_gem_local_remote_options.rb +1 -0
  298. data/test/rubygems/test_gem_name_tuple.rb +1 -0
  299. data/test/rubygems/test_gem_package_old.rb +1 -0
  300. data/test/rubygems/test_gem_package_tar_header.rb +1 -0
  301. data/test/rubygems/test_gem_package_tar_reader.rb +1 -0
  302. data/test/rubygems/test_gem_package_tar_reader_entry.rb +1 -0
  303. data/test/rubygems/test_gem_package_tar_writer.rb +1 -0
  304. data/test/rubygems/test_gem_package_task.rb +1 -0
  305. data/test/rubygems/test_gem_path_support.rb +1 -0
  306. data/test/rubygems/test_gem_platform.rb +1 -0
  307. data/test/rubygems/test_gem_rdoc.rb +1 -0
  308. data/test/rubygems/test_gem_remote_fetcher.rb +1 -0
  309. data/test/rubygems/test_gem_request.rb +1 -0
  310. data/test/rubygems/test_gem_request_connection_pools.rb +1 -0
  311. data/test/rubygems/test_gem_request_set.rb +1 -0
  312. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +1 -0
  313. data/test/rubygems/test_gem_request_set_lockfile.rb +1 -0
  314. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +1 -0
  315. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +1 -0
  316. data/test/rubygems/test_gem_requirement.rb +1 -0
  317. data/test/rubygems/test_gem_resolver.rb +1 -0
  318. data/test/rubygems/test_gem_resolver_activation_request.rb +1 -0
  319. data/test/rubygems/test_gem_resolver_api_set.rb +1 -0
  320. data/test/rubygems/test_gem_resolver_api_specification.rb +1 -0
  321. data/test/rubygems/test_gem_resolver_best_set.rb +1 -0
  322. data/test/rubygems/test_gem_resolver_composed_set.rb +1 -0
  323. data/test/rubygems/test_gem_resolver_conflict.rb +1 -0
  324. data/test/rubygems/test_gem_resolver_dependency_request.rb +1 -0
  325. data/test/rubygems/test_gem_resolver_git_set.rb +1 -0
  326. data/test/rubygems/test_gem_resolver_git_specification.rb +2 -1
  327. data/test/rubygems/test_gem_resolver_index_set.rb +1 -0
  328. data/test/rubygems/test_gem_resolver_index_specification.rb +1 -0
  329. data/test/rubygems/test_gem_resolver_installed_specification.rb +1 -0
  330. data/test/rubygems/test_gem_resolver_installer_set.rb +1 -0
  331. data/test/rubygems/test_gem_resolver_local_specification.rb +1 -0
  332. data/test/rubygems/test_gem_resolver_lock_set.rb +1 -0
  333. data/test/rubygems/test_gem_resolver_lock_specification.rb +1 -0
  334. data/test/rubygems/test_gem_resolver_requirement_list.rb +1 -0
  335. data/test/rubygems/test_gem_resolver_specification.rb +1 -0
  336. data/test/rubygems/test_gem_resolver_vendor_set.rb +1 -0
  337. data/test/rubygems/test_gem_resolver_vendor_specification.rb +1 -0
  338. data/test/rubygems/test_gem_security.rb +1 -0
  339. data/test/rubygems/test_gem_security_signer.rb +1 -0
  340. data/test/rubygems/test_gem_security_trust_dir.rb +1 -0
  341. data/test/rubygems/test_gem_silent_ui.rb +1 -0
  342. data/test/rubygems/test_gem_source.rb +1 -0
  343. data/test/rubygems/test_gem_source_fetch_problem.rb +1 -0
  344. data/test/rubygems/test_gem_source_git.rb +1 -0
  345. data/test/rubygems/test_gem_source_installed.rb +1 -0
  346. data/test/rubygems/test_gem_source_list.rb +1 -0
  347. data/test/rubygems/test_gem_source_local.rb +1 -0
  348. data/test/rubygems/test_gem_source_lock.rb +1 -0
  349. data/test/rubygems/test_gem_source_specific_file.rb +1 -0
  350. data/test/rubygems/test_gem_source_subpath_problem.rb +1 -0
  351. data/test/rubygems/test_gem_source_vendor.rb +1 -0
  352. data/test/rubygems/test_gem_spec_fetcher.rb +1 -0
  353. data/test/rubygems/test_gem_specification.rb +9 -0
  354. data/test/rubygems/test_gem_stream_ui.rb +34 -3
  355. data/test/rubygems/test_gem_stub_specification.rb +1 -0
  356. data/test/rubygems/test_gem_text.rb +1 -0
  357. data/test/rubygems/test_gem_uninstaller.rb +1 -0
  358. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +1 -0
  359. data/test/rubygems/test_gem_update_suggestion.rb +1 -0
  360. data/test/rubygems/test_gem_uri.rb +2 -0
  361. data/test/rubygems/test_gem_uri_formatter.rb +1 -0
  362. data/test/rubygems/test_gem_util.rb +1 -0
  363. data/test/rubygems/test_gem_version.rb +1 -0
  364. data/test/rubygems/test_gem_version_option.rb +1 -0
  365. data/test/rubygems/test_kernel.rb +1 -0
  366. data/test/rubygems/test_remote_fetch_error.rb +1 -0
  367. data/test/rubygems/test_require.rb +1 -0
  368. data/test/rubygems/test_rubygems.rb +2 -0
  369. data/test/rubygems/test_webauthn_listener.rb +29 -6
  370. data/test/rubygems/test_webauthn_listener_response.rb +8 -8
  371. data/test/rubygems/test_webauthn_poller.rb +124 -0
  372. data/test/rubygems/utilities.rb +1 -0
  373. data/test/test_changelog_generator.rb +1 -1
  374. metadata +39 -10
  375. data/lib/rubygems/webauthn_listener/response.rb +0 -161
  376. 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/dependency_list"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
 
4
5
  class TestGemDependencyResolutionError < Gem::TestCase
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/doctor"
4
5
 
@@ -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 if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
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 if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
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 if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
165
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
165
166
 
166
167
  @spec.extensions << "ext/extconf.rb"
167
168
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = "custom_name"
3
5
  s.version = "0.1.0"
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "custom_name_lib/custom_name_ext"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = "rust_ruby_example"
3
5
  s.version = "0.1.0"
@@ -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("../../bin/gem", __dir__)]
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("../../bin/gem", __dir__)]
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,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/ext"
4
5
  require "rubygems/ext/cargo_builder/link_flag_converter"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/ext"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/ext"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/ext"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
 
4
5
  class TestGemGemRunner < Gem::TestCase
@@ -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
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
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
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
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
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
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
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
136
- util_sign_in HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK"), "http://example.com"
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
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
149
- Gem.configuration.rubygems_api_key = api_key
148
+ Gem.configuration.rubygems_api_key = @fetcher.api_key
150
149
 
151
- util_sign_in HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
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 HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
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 HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
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 HTTPResponseFactory.create(body: "Access Denied.", code: 403, msg: "Forbidden")
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 HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
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
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
203
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
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 HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized"), nil, [], "111111\n"
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
- webauthn_verification_url = "rubygems.org/api/v1/webauthn_verification/odow34b93t6aPCdY"
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(:wait_for_otp_code, "Uvh6T57tkWuUnWYo") do
242
- util_sign_in(proc do
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
- url_with_port = "#{webauthn_verification_url}?port=#{port}"
256
- assert_match "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.", @sign_in_ui.output
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
- webauthn_verification_url = "rubygems.org/api/v1/webauthn_verification/odow34b93t6aPCdY"
263
- response_fail = "You have enabled multifactor authentication"
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(:wait_for_otp_code, raise_error) do
272
- util_sign_in(proc do
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
- url_with_port = "#{webauthn_verification_url}?port=#{port}"
288
- assert_match "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.", @sign_in_ui.output
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 util_sign_in(response, host = nil, args = [], extra_input = "", webauthn_url = nil)
295
- email = "you@example.com"
296
- password = "secret"
297
- profile_response = HTTPResponseFactory.create(body: "mfa: disabled\n", code: 200, msg: "OK")
298
- webauthn_response =
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
- if host
306
- ENV["RUBYGEMS_HOST"] = host
307
- else
308
- host = Gem.host
269
+ TCPServer.stub(:new, server) do
270
+ util_sign_in
309
271
  end
310
272
 
311
- @fetcher = Gem::FakeFetcher.new
312
- @fetcher.data["#{host}/api/v1/api_key"] = response
313
- @fetcher.data["#{host}/api/v1/profile/me.yaml"] = profile_response
314
- @fetcher.data["#{host}/api/v1/webauthn_verification"] = webauthn_response
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 "helper"
3
4
 
4
5
  class TestGemImpossibleDependenciesError < Gem::TestCase
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/indexer"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "installer_test_case"
3
4
  require "rubygems/install_update_options"
4
5
  require "rubygems/command"
@@ -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 if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
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,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/local_remote_options"
4
5
  require "rubygems/command"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/name_tuple"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
 
4
5
  unless Gem.java_platform? # jruby can't require the simple_gem file
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "package/tar_test_case"
3
4
  require "rubygems/package"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "package/tar_test_case"
3
4
  require "rubygems/package"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "package/tar_test_case"
3
4
  require "rubygems/package"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "package/tar_test_case"
3
4
  require "rubygems/package/tar_writer"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems"
4
5
  require "fileutils"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/platform"
4
5
  require "rbconfig"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "rubygems"
3
4
  require_relative "helper"
4
5
  require "rubygems/rdoc"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
 
4
5
  require "webrick"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request"
4
5
  require "ostruct"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request"
4
5
  require "timeout"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request_set"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request_set"
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request_set"
4
5
  require "rubygems/request_set/lockfile"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request_set"
4
5
  require "rubygems/request_set/lockfile"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/request_set"
4
5
  require "rubygems/request_set/lockfile"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "helper"
3
4
  require "rubygems/requirement"
4
5