rubygems-update 3.4.10 → 3.4.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/Manifest.txt +5 -0
  4. data/bundler/CHANGELOG.md +48 -0
  5. data/bundler/exe/bundle +5 -13
  6. data/bundler/lib/bundler/build_metadata.rb +2 -2
  7. data/bundler/lib/bundler/definition.rb +14 -6
  8. data/bundler/lib/bundler/gem_version_promoter.rb +1 -1
  9. data/bundler/lib/bundler/installer.rb +1 -1
  10. data/bundler/lib/bundler/lazy_specification.rb +1 -1
  11. data/bundler/lib/bundler/lockfile_parser.rb +1 -0
  12. data/bundler/lib/bundler/man/bundle-cache.1 +2 -2
  13. data/bundler/lib/bundler/man/bundle-cache.1.ronn +2 -2
  14. data/bundler/lib/bundler/resolver/base.rb +1 -3
  15. data/bundler/lib/bundler/ruby_version.rb +1 -1
  16. data/bundler/lib/bundler/rubygems_ext.rb +5 -3
  17. data/bundler/lib/bundler/safe_marshal.rb +31 -0
  18. data/bundler/lib/bundler/settings.rb +3 -2
  19. data/bundler/lib/bundler/source/rubygems.rb +12 -12
  20. data/bundler/lib/bundler/spec_set.rb +2 -2
  21. data/bundler/lib/bundler/templates/newgem/bin/console.tt +0 -4
  22. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +5 -0
  23. data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +1 -1
  24. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -1
  25. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +9 -4
  26. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +2 -2
  27. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  28. data/bundler/lib/bundler/version.rb +1 -1
  29. data/bundler/lib/bundler.rb +8 -16
  30. data/lib/rubygems/command_manager.rb +2 -2
  31. data/lib/rubygems/commands/owner_command.rb +4 -2
  32. data/lib/rubygems/exceptions.rb +10 -0
  33. data/lib/rubygems/gemcutter_utilities.rb +48 -6
  34. data/lib/rubygems/installer.rb +16 -1
  35. data/lib/rubygems/request_set.rb +2 -2
  36. data/lib/rubygems/specification.rb +3 -1
  37. data/lib/rubygems/stub_specification.rb +2 -1
  38. data/lib/rubygems/webauthn_listener/response.rb +161 -0
  39. data/lib/rubygems/webauthn_listener.rb +92 -0
  40. data/lib/rubygems.rb +1 -1
  41. data/rubygems-update.gemspec +4 -3
  42. data/test/rubygems/helper.rb +14 -0
  43. data/test/rubygems/test_bundled_ca.rb +1 -1
  44. data/test/rubygems/test_config.rb +1 -1
  45. data/test/rubygems/test_deprecate.rb +1 -1
  46. data/test/rubygems/test_exit.rb +1 -1
  47. data/test/rubygems/test_gem.rb +7 -0
  48. data/test/rubygems/test_gem_commands_owner_command.rb +67 -0
  49. data/test/rubygems/test_gem_commands_pristine_command.rb +1 -1
  50. data/test/rubygems/test_gem_commands_push_command.rb +73 -0
  51. data/test/rubygems/test_gem_commands_setup_command.rb +1 -1
  52. data/test/rubygems/test_gem_commands_yank_command.rb +84 -0
  53. data/test/rubygems/test_gem_ext_cargo_builder.rb +1 -0
  54. data/test/rubygems/test_gem_gem_runner.rb +5 -5
  55. data/test/rubygems/test_gem_gemcutter_utilities.rb +72 -4
  56. data/test/rubygems/test_gem_installer.rb +50 -2
  57. data/test/rubygems/test_gem_uninstaller.rb +4 -4
  58. data/test/rubygems/test_kernel.rb +1 -1
  59. data/test/rubygems/test_project_sanity.rb +32 -3
  60. data/test/rubygems/test_remote_fetch_error.rb +1 -1
  61. data/test/rubygems/test_webauthn_listener.rb +120 -0
  62. data/test/rubygems/test_webauthn_listener_response.rb +93 -0
  63. data/test/rubygems/utilities.rb +43 -3
  64. metadata +13 -6
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
4
+ require "rubygems/webauthn_listener"
5
+
6
+ class WebauthnListenerTest < Gem::TestCase
7
+ def setup
8
+ super
9
+ @server = TCPServer.new 0
10
+ @port = @server.addr[1].to_s
11
+ end
12
+
13
+ def test_wait_for_otp_code_get_follows_options
14
+ wait_for_otp_code
15
+ assert Gem::MockBrowser.options(URI("http://localhost:#{@port}?code=xyz")).is_a? Net::HTTPNoContent
16
+ assert Gem::MockBrowser.get(URI("http://localhost:#{@port}?code=xyz")).is_a? Net::HTTPOK
17
+ end
18
+
19
+ def test_wait_for_otp_code_options_request
20
+ wait_for_otp_code
21
+ response = Gem::MockBrowser.options URI("http://localhost:#{@port}?code=xyz")
22
+
23
+ assert response.is_a? Net::HTTPNoContent
24
+ assert_equal Gem.host, response["access-control-allow-origin"]
25
+ assert_equal "POST", response["access-control-allow-methods"]
26
+ assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"]
27
+ assert_equal "close", response["Connection"]
28
+ end
29
+
30
+ def test_wait_for_otp_code_get_request
31
+ wait_for_otp_code
32
+ response = Gem::MockBrowser.get URI("http://localhost:#{@port}?code=xyz")
33
+
34
+ assert response.is_a? Net::HTTPOK
35
+ assert_equal "text/plain", response["Content-Type"]
36
+ assert_equal "7", response["Content-Length"]
37
+ assert_equal Gem.host, response["access-control-allow-origin"]
38
+ assert_equal "POST", response["access-control-allow-methods"]
39
+ assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"]
40
+ assert_equal "close", response["Connection"]
41
+ assert_equal "success", response.body
42
+
43
+ @thread.join
44
+ assert_equal "xyz", @thread[:otp]
45
+ end
46
+
47
+ def test_wait_for_otp_code_invalid_post_req_method
48
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Invalid HTTP method POST received.")
49
+ response = Gem::MockBrowser.post URI("http://localhost:#{@port}?code=xyz")
50
+
51
+ assert response
52
+ assert response.is_a? Net::HTTPMethodNotAllowed
53
+ assert_equal "GET, OPTIONS", response["allow"]
54
+ assert_equal "close", response["Connection"]
55
+
56
+ @thread.join
57
+ assert_nil @thread[:otp]
58
+ end
59
+
60
+ def test_wait_for_otp_code_incorrect_path
61
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Page at /path not found.")
62
+ response = Gem::MockBrowser.post URI("http://localhost:#{@port}/path?code=xyz")
63
+
64
+ assert response.is_a? Net::HTTPNotFound
65
+ assert_equal "close", response["Connection"]
66
+
67
+ @thread.join
68
+ assert_nil @thread[:otp]
69
+ end
70
+
71
+ def test_wait_for_otp_code_no_params_response
72
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.")
73
+ response = Gem::MockBrowser.get URI("http://localhost:#{@port}")
74
+
75
+ assert response.is_a? Net::HTTPBadRequest
76
+ assert_equal "text/plain", response["Content-Type"]
77
+ assert_equal "22", response["Content-Length"]
78
+ assert_equal "close", response["Connection"]
79
+ assert_equal "missing code parameter", response.body
80
+
81
+ @thread.join
82
+ assert_nil @thread[:otp]
83
+ end
84
+
85
+ def test_wait_for_otp_code_incorrect_params
86
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.")
87
+ response = Gem::MockBrowser.get URI("http://localhost:#{@port}?param=xyz")
88
+
89
+ assert response.is_a? Net::HTTPBadRequest
90
+ assert_equal "text/plain", response["Content-Type"]
91
+ assert_equal "22", response["Content-Length"]
92
+ assert_equal "close", response["Connection"]
93
+ assert_equal "missing code parameter", response.body
94
+
95
+ @thread.join
96
+ assert_nil @thread[:otp]
97
+ end
98
+
99
+ private
100
+
101
+ def wait_for_otp_code
102
+ @thread = Thread.new do
103
+ Thread.current[:otp] = Gem::WebauthnListener.wait_for_otp_code(Gem.host, @server)
104
+ end
105
+ @thread.abort_on_exception = true
106
+ @thread.report_on_exception = false
107
+ end
108
+
109
+ def wait_for_otp_code_expect_error_with_message(message)
110
+ @thread = Thread.new do
111
+ error = assert_raise Gem::WebauthnVerificationError do
112
+ Thread.current[:otp] = Gem::WebauthnListener.wait_for_otp_code(Gem.host, @server)
113
+ end
114
+
115
+ assert_equal message, error.message
116
+ end
117
+ @thread.abort_on_exception = true
118
+ @thread.report_on_exception = false
119
+ end
120
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
4
+ require "rubygems/webauthn_listener/response"
5
+
6
+ class WebauthnListenerResponseTest < Gem::TestCase
7
+ def setup
8
+ super
9
+ @host = "rubygems.example"
10
+ end
11
+
12
+ def test_ok_response_to_s
13
+ to_s = Gem::WebauthnListener::OkResponse.new(@host).to_s
14
+
15
+ expected_to_s = <<~RESPONSE
16
+ HTTP/1.1 200 OK\r
17
+ connection: close\r
18
+ access-control-allow-origin: rubygems.example\r
19
+ access-control-allow-methods: POST\r
20
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
21
+ content-type: text/plain\r
22
+ content-length: 7\r
23
+ \r
24
+ success
25
+ RESPONSE
26
+
27
+ assert_equal expected_to_s, to_s
28
+ end
29
+
30
+ def test_no_to_s_response_to_s
31
+ to_s = Gem::WebauthnListener::NoContentResponse.new(@host).to_s
32
+
33
+ expected_to_s = <<~RESPONSE
34
+ HTTP/1.1 204 No Content\r
35
+ connection: close\r
36
+ access-control-allow-origin: rubygems.example\r
37
+ access-control-allow-methods: POST\r
38
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
39
+ \r
40
+ RESPONSE
41
+
42
+ assert_equal expected_to_s, to_s
43
+ end
44
+
45
+ def test_method_not_allowed_response_to_s
46
+ to_s = Gem::WebauthnListener::MethodNotAllowedResponse.new(@host).to_s
47
+
48
+ expected_to_s = <<~RESPONSE
49
+ HTTP/1.1 405 Method Not Allowed\r
50
+ connection: close\r
51
+ access-control-allow-origin: rubygems.example\r
52
+ access-control-allow-methods: POST\r
53
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
54
+ allow: GET, OPTIONS\r
55
+ \r
56
+ RESPONSE
57
+
58
+ assert_equal expected_to_s, to_s
59
+ end
60
+
61
+ def test_method_not_found_response_to_s
62
+ to_s = Gem::WebauthnListener::NotFoundResponse.new(@host).to_s
63
+
64
+ expected_to_s = <<~RESPONSE
65
+ HTTP/1.1 404 Not Found\r
66
+ connection: close\r
67
+ access-control-allow-origin: rubygems.example\r
68
+ access-control-allow-methods: POST\r
69
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
70
+ \r
71
+ RESPONSE
72
+
73
+ assert_equal expected_to_s, to_s
74
+ end
75
+
76
+ def test_bad_request_response_to_s
77
+ to_s = Gem::WebauthnListener::BadRequestResponse.new(@host).to_s
78
+
79
+ expected_to_s = <<~RESPONSE
80
+ HTTP/1.1 400 Bad Request\r
81
+ connection: close\r
82
+ access-control-allow-origin: rubygems.example\r
83
+ access-control-allow-methods: POST\r
84
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
85
+ content-type: text/plain\r
86
+ content-length: 22\r
87
+ \r
88
+ missing code parameter
89
+ RESPONSE
90
+
91
+ assert_equal expected_to_s, to_s
92
+ end
93
+ end
@@ -167,7 +167,7 @@ end
167
167
  #
168
168
  # Example:
169
169
  #
170
- # HTTPResponseFactory.create(
170
+ # Gem::HTTPResponseFactory.create(
171
171
  # body: "",
172
172
  # code: 301,
173
173
  # msg: "Moved Permanently",
@@ -175,7 +175,7 @@ end
175
175
  # )
176
176
  #
177
177
 
178
- class HTTPResponseFactory
178
+ class Gem::HTTPResponseFactory
179
179
  def self.create(body:, code:, msg:, headers: {})
180
180
  response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
181
181
  response.instance_variable_set(:@body, body)
@@ -186,6 +186,41 @@ class HTTPResponseFactory
186
186
  end
187
187
  end
188
188
 
189
+ ##
190
+ # A Gem::MockBrowser is used in tests to mock a browser in that it can
191
+ # send HTTP requests to the defined URI.
192
+ #
193
+ # Example:
194
+ #
195
+ # # Sends a get request to http://localhost:5678
196
+ # Gem::MockBrowser.get URI("http://localhost:5678")
197
+ #
198
+ # See RubyGems' tests for more examples of MockBrowser.
199
+ #
200
+
201
+ class Gem::MockBrowser
202
+ def self.options(uri)
203
+ options = Net::HTTP::Options.new(uri)
204
+ Net::HTTP.start(uri.hostname, uri.port) do |http|
205
+ http.request(options)
206
+ end
207
+ end
208
+
209
+ def self.get(uri)
210
+ get = Net::HTTP::Get.new(uri)
211
+ Net::HTTP.start(uri.hostname, uri.port) do |http|
212
+ http.request(get)
213
+ end
214
+ end
215
+
216
+ def self.post(uri)
217
+ post = Net::HTTP::Post.new(uri)
218
+ Net::HTTP.start(uri.hostname, uri.port) do |http|
219
+ http.request(post)
220
+ end
221
+ end
222
+ end
223
+
189
224
  # :stopdoc:
190
225
  class Gem::RemoteFetcher
191
226
  def self.fetcher=(fetcher)
@@ -372,7 +407,7 @@ end
372
407
  #
373
408
  # This class was added to flush out problems in Rubinius' IO implementation.
374
409
 
375
- class TempIO < Tempfile
410
+ class Gem::TempIO < Tempfile
376
411
  ##
377
412
  # Creates a new TempIO that will be initialized to contain +string+.
378
413
 
@@ -391,3 +426,8 @@ class TempIO < Tempfile
391
426
  Gem.read_binary path
392
427
  end
393
428
  end
429
+
430
+ class Gem::TestCase
431
+ TempIO = Gem::TempIO
432
+ HTTPResponseFactory = Gem::HTTPResponseFactory
433
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubygems-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.10
4
+ version: 3.4.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2023-03-27 00:00:00.000000000 Z
19
+ date: 2023-06-12 00:00:00.000000000 Z
20
20
  dependencies: []
21
21
  description: |-
22
22
  A package (also known as a library) contains a set of functionality
@@ -236,6 +236,7 @@ files:
236
236
  - bundler/lib/bundler/rubygems_gem_installer.rb
237
237
  - bundler/lib/bundler/rubygems_integration.rb
238
238
  - bundler/lib/bundler/runtime.rb
239
+ - bundler/lib/bundler/safe_marshal.rb
239
240
  - bundler/lib/bundler/self_manager.rb
240
241
  - bundler/lib/bundler/settings.rb
241
242
  - bundler/lib/bundler/settings/validator.rb
@@ -596,6 +597,8 @@ files:
596
597
  - lib/rubygems/validator.rb
597
598
  - lib/rubygems/version.rb
598
599
  - lib/rubygems/version_option.rb
600
+ - lib/rubygems/webauthn_listener.rb
601
+ - lib/rubygems/webauthn_listener/response.rb
599
602
  - rubygems-update.gemspec
600
603
  - setup.rb
601
604
  - test/rubygems/alternate_cert.pem
@@ -809,15 +812,18 @@ files:
809
812
  - test/rubygems/test_remote_fetch_error.rb
810
813
  - test/rubygems/test_require.rb
811
814
  - test/rubygems/test_rubygems.rb
815
+ - test/rubygems/test_webauthn_listener.rb
816
+ - test/rubygems/test_webauthn_listener_response.rb
812
817
  - test/rubygems/utilities.rb
813
818
  - test/rubygems/wrong_key_cert.pem
814
819
  - test/rubygems/wrong_key_cert_32.pem
815
820
  - test/test_changelog_generator.rb
816
- homepage: https://rubygems.org
821
+ homepage: https://guides.rubygems.org
817
822
  licenses:
818
823
  - Ruby
819
824
  - MIT
820
- metadata: {}
825
+ metadata:
826
+ source_code_uri: https://github.com/rubygems/rubygems
821
827
  post_install_message:
822
828
  rdoc_options:
823
829
  - "--main"
@@ -836,8 +842,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
836
842
  - !ruby/object:Gem::Version
837
843
  version: '0'
838
844
  requirements: []
839
- rubygems_version: 3.4.10
845
+ rubygems_version: 3.4.14
840
846
  signing_key:
841
847
  specification_version: 4
842
- summary: RubyGems is a package management framework for Ruby.
848
+ summary: RubyGems is a package management framework for Ruby. This gem is downloaded
849
+ and installed by `gem update --system`, so that the `gem` CLI can update itself.
843
850
  test_files: []