rubygems-update 2.0.0.rc.1 → 2.0.0.rc.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/History.txt +165 -3
- data/Manifest.txt +1 -0
- data/lib/rubygems.rb +19 -37
- data/lib/rubygems/commands/push_command.rb +18 -11
- data/lib/rubygems/compatibility.rb +5 -1
- data/lib/rubygems/config_file.rb +42 -1
- data/lib/rubygems/dependency_installer.rb +7 -8
- data/lib/rubygems/errors.rb +2 -1
- data/lib/rubygems/ext/builder.rb +13 -6
- data/lib/rubygems/gemcutter_utilities.rb +12 -4
- data/lib/rubygems/package.rb +10 -2
- data/lib/rubygems/package/old.rb +37 -6
- data/lib/rubygems/security/policy.rb +44 -10
- data/lib/rubygems/specification.rb +7 -1
- data/lib/rubygems/ssl_certs/.document +1 -0
- data/lib/rubygems/test_case.rb +19 -5
- data/test/rubygems/test_gem.rb +42 -2
- data/test/rubygems/test_gem_commands_push_command.rb +2 -1
- data/test/rubygems/test_gem_config_file.rb +98 -34
- data/test/rubygems/test_gem_dependency_installer.rb +34 -2
- data/test/rubygems/test_gem_gemcutter_utilities.rb +23 -4
- data/test/rubygems/test_gem_installer.rb +27 -0
- data/test/rubygems/test_gem_package.rb +54 -3
- data/test/rubygems/test_gem_package_old.rb +42 -0
- data/test/rubygems/test_gem_security_policy.rb +144 -32
- data/test/rubygems/test_gem_specification.rb +9 -0
- metadata +136 -165
- metadata.gz.sig +0 -0
@@ -46,6 +46,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
|
|
46
46
|
|
47
47
|
def send_battery
|
48
48
|
use_ui @ui do
|
49
|
+
@cmd.instance_variable_set :@host, @host
|
49
50
|
@cmd.send_gem(@path)
|
50
51
|
end
|
51
52
|
|
@@ -133,7 +134,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
|
|
133
134
|
end
|
134
135
|
|
135
136
|
def test_raises_error_with_no_arguments
|
136
|
-
def @cmd.sign_in; end
|
137
|
+
def @cmd.sign_in(*); end
|
137
138
|
assert_raises Gem::CommandLineError do
|
138
139
|
@cmd.execute
|
139
140
|
end
|
@@ -164,6 +164,38 @@ class TestGemConfigFile < Gem::TestCase
|
|
164
164
|
assert_equal 2048, @cfg.bulk_threshold
|
165
165
|
end
|
166
166
|
|
167
|
+
def test_check_credentials_permissions
|
168
|
+
skip 'chmod not supported' if win_platform?
|
169
|
+
|
170
|
+
@cfg.rubygems_api_key = 'x'
|
171
|
+
|
172
|
+
File.chmod 0644, @cfg.credentials_path
|
173
|
+
|
174
|
+
use_ui @ui do
|
175
|
+
assert_raises Gem::MockGemUi::TermError do
|
176
|
+
@cfg.load_api_keys
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
assert_empty @ui.output
|
181
|
+
|
182
|
+
expected = <<-EXPECTED
|
183
|
+
ERROR: Your gem push credentials file located at:
|
184
|
+
|
185
|
+
\t#{@cfg.credentials_path}
|
186
|
+
|
187
|
+
has file permissions of 0644 but 0600 is required.
|
188
|
+
|
189
|
+
You should reset your credentials at:
|
190
|
+
|
191
|
+
\thttps://rubygems.org/profile/edit
|
192
|
+
|
193
|
+
if you believe they were disclosed to a third party.
|
194
|
+
EXPECTED
|
195
|
+
|
196
|
+
assert_equal expected, @ui.error
|
197
|
+
end
|
198
|
+
|
167
199
|
def test_handle_arguments
|
168
200
|
args = %w[--backtrace --bunch --of --args here]
|
169
201
|
|
@@ -215,6 +247,32 @@ class TestGemConfigFile < Gem::TestCase
|
|
215
247
|
assert_equal true, @cfg.backtrace
|
216
248
|
end
|
217
249
|
|
250
|
+
def test_load_api_keys
|
251
|
+
temp_cred = File.join Gem.user_home, '.gem', 'credentials'
|
252
|
+
FileUtils.mkdir File.dirname(temp_cred)
|
253
|
+
File.open temp_cred, 'w', 0600 do |fp|
|
254
|
+
fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
|
255
|
+
fp.puts ":other: a5fdbb6ba150cbb83aad2bb2fede64c"
|
256
|
+
end
|
257
|
+
|
258
|
+
util_config_file
|
259
|
+
|
260
|
+
assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97',
|
261
|
+
:other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys)
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_load_api_keys_bad_permission
|
265
|
+
skip 'chmod not supported' if win_platform?
|
266
|
+
|
267
|
+
@cfg.rubygems_api_key = 'x'
|
268
|
+
|
269
|
+
File.chmod 0644, @cfg.credentials_path
|
270
|
+
|
271
|
+
assert_raises Gem::MockGemUi::TermError do
|
272
|
+
@cfg.load_api_keys
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
218
276
|
def test_really_verbose
|
219
277
|
assert_equal false, @cfg.really_verbose
|
220
278
|
|
@@ -227,6 +285,46 @@ class TestGemConfigFile < Gem::TestCase
|
|
227
285
|
assert_equal true, @cfg.really_verbose
|
228
286
|
end
|
229
287
|
|
288
|
+
def test_rubygems_api_key_equals
|
289
|
+
@cfg.rubygems_api_key = 'x'
|
290
|
+
|
291
|
+
assert_equal 'x', @cfg.rubygems_api_key
|
292
|
+
|
293
|
+
expected = {
|
294
|
+
:rubygems_api_key => 'x',
|
295
|
+
}
|
296
|
+
|
297
|
+
assert_equal expected, YAML.load_file(@cfg.credentials_path)
|
298
|
+
|
299
|
+
unless win_platform? then
|
300
|
+
stat = File.stat @cfg.credentials_path
|
301
|
+
|
302
|
+
assert_equal 0600, stat.mode & 0600
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_rubygems_api_key_equals_bad_permission
|
307
|
+
skip 'chmod not supported' if win_platform?
|
308
|
+
|
309
|
+
@cfg.rubygems_api_key = 'x'
|
310
|
+
|
311
|
+
File.chmod 0644, @cfg.credentials_path
|
312
|
+
|
313
|
+
assert_raises Gem::MockGemUi::TermError do
|
314
|
+
@cfg.rubygems_api_key = 'y'
|
315
|
+
end
|
316
|
+
|
317
|
+
expected = {
|
318
|
+
:rubygems_api_key => 'x',
|
319
|
+
}
|
320
|
+
|
321
|
+
assert_equal expected, YAML.load_file(@cfg.credentials_path)
|
322
|
+
|
323
|
+
stat = File.stat @cfg.credentials_path
|
324
|
+
|
325
|
+
assert_equal 0644, stat.mode & 0644
|
326
|
+
end
|
327
|
+
|
230
328
|
def test_write
|
231
329
|
@cfg.backtrace = true
|
232
330
|
@cfg.update_sources = false
|
@@ -287,40 +385,6 @@ class TestGemConfigFile < Gem::TestCase
|
|
287
385
|
assert_equal %w[http://even-more-gems.example.com], Gem.sources
|
288
386
|
end
|
289
387
|
|
290
|
-
def test_load_rubygems_api_key_from_credentials
|
291
|
-
temp_cred = File.join Gem.user_home, '.gem', 'credentials'
|
292
|
-
FileUtils.mkdir File.dirname(temp_cred)
|
293
|
-
File.open temp_cred, 'w' do |fp|
|
294
|
-
fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
|
295
|
-
end
|
296
|
-
|
297
|
-
util_config_file
|
298
|
-
|
299
|
-
assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key
|
300
|
-
end
|
301
|
-
|
302
|
-
def test_load_api_keys_from_config
|
303
|
-
temp_cred = File.join Gem.user_home, '.gem', 'credentials'
|
304
|
-
FileUtils.mkdir File.dirname(temp_cred)
|
305
|
-
File.open temp_cred, 'w' do |fp|
|
306
|
-
fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
|
307
|
-
fp.puts ":other: a5fdbb6ba150cbb83aad2bb2fede64c"
|
308
|
-
end
|
309
|
-
|
310
|
-
util_config_file
|
311
|
-
|
312
|
-
assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97',
|
313
|
-
:other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys)
|
314
|
-
end
|
315
|
-
|
316
|
-
def test_save_credentials_file_with_strict_permissions
|
317
|
-
util_config_file
|
318
|
-
FileUtils.mkdir File.dirname(@cfg.credentials_path)
|
319
|
-
@cfg.rubygems_api_key = '701229f217cdf23b1344c7b4b54ca97'
|
320
|
-
mode = 0100600 & (~File.umask)
|
321
|
-
assert_equal mode, File.stat(@cfg.credentials_path).mode unless win_platform?
|
322
|
-
end
|
323
|
-
|
324
388
|
def test_ignore_invalid_config_file
|
325
389
|
File.open @temp_conf, 'w' do |fp|
|
326
390
|
fp.puts "some-non-yaml-hash-string"
|
@@ -500,16 +500,21 @@ class TestGemDependencyInstaller < Gem::TestCase
|
|
500
500
|
util_setup_gems
|
501
501
|
|
502
502
|
FileUtils.mv @a1_gem, @tempdir
|
503
|
+
FileUtils.mv @b1_gem, @tempdir
|
504
|
+
|
505
|
+
inst = Gem::Installer.new @a1.file_name
|
506
|
+
inst.install
|
507
|
+
|
503
508
|
gemhome2 = File.join @tempdir, 'gemhome2'
|
504
509
|
Dir.mkdir gemhome2
|
505
510
|
inst = nil
|
506
511
|
|
507
512
|
Dir.chdir @tempdir do
|
508
513
|
inst = Gem::DependencyInstaller.new :install_dir => gemhome2
|
509
|
-
inst.install '
|
514
|
+
inst.install 'b'
|
510
515
|
end
|
511
516
|
|
512
|
-
assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
|
517
|
+
assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
|
513
518
|
|
514
519
|
assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name))
|
515
520
|
assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name))
|
@@ -794,6 +799,19 @@ class TestGemDependencyInstaller < Gem::TestCase
|
|
794
799
|
assert_equal Gem::Source.new(@gem_repo), s.source
|
795
800
|
end
|
796
801
|
|
802
|
+
def test_find_spec_by_name_and_version_bad_gem
|
803
|
+
FileUtils.touch 'rdoc.gem'
|
804
|
+
|
805
|
+
inst = Gem::DependencyInstaller.new
|
806
|
+
|
807
|
+
e = assert_raises Gem::Package::FormatError do
|
808
|
+
inst.find_spec_by_name_and_version 'rdoc.gem'
|
809
|
+
end
|
810
|
+
|
811
|
+
full_path = File.join @tempdir, 'rdoc.gem'
|
812
|
+
assert_equal "package metadata is missing in #{full_path}", e.message
|
813
|
+
end
|
814
|
+
|
797
815
|
def test_find_spec_by_name_and_version_directory
|
798
816
|
Dir.mkdir 'rdoc'
|
799
817
|
|
@@ -808,6 +826,20 @@ class TestGemDependencyInstaller < Gem::TestCase
|
|
808
826
|
e.message
|
809
827
|
end
|
810
828
|
|
829
|
+
def test_find_spec_by_name_and_version_file
|
830
|
+
FileUtils.touch 'rdoc'
|
831
|
+
|
832
|
+
inst = Gem::DependencyInstaller.new
|
833
|
+
|
834
|
+
e = assert_raises Gem::SpecificGemNotFoundException do
|
835
|
+
inst.find_spec_by_name_and_version 'rdoc'
|
836
|
+
end
|
837
|
+
|
838
|
+
assert_equal "Could not find a valid gem 'rdoc' (>= 0) " +
|
839
|
+
"locally or in a repository",
|
840
|
+
e.message
|
841
|
+
end
|
842
|
+
|
811
843
|
def test_find_gems_with_sources_local
|
812
844
|
util_setup_gems
|
813
845
|
|
@@ -77,9 +77,24 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
77
77
|
|
78
78
|
def test_sign_in_with_host
|
79
79
|
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
80
|
+
|
81
|
+
util_sign_in [api_key, 200, 'OK'], 'http://example.com', :param
|
82
|
+
|
83
|
+
assert_match "Enter your http://example.com credentials.",
|
84
|
+
@sign_in_ui.output
|
85
|
+
assert @fetcher.last_request["authorization"]
|
86
|
+
assert_match %r{Signed in.}, @sign_in_ui.output
|
87
|
+
|
88
|
+
credentials = YAML.load_file Gem.configuration.credentials_path
|
89
|
+
assert_equal api_key, credentials[:rubygems_api_key]
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_sign_in_with_host_ENV
|
93
|
+
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
80
94
|
util_sign_in [api_key, 200, 'OK'], 'http://example.com'
|
81
95
|
|
82
|
-
assert_match
|
96
|
+
assert_match "Enter your http://example.com credentials.",
|
97
|
+
@sign_in_ui.output
|
83
98
|
assert @fetcher.last_request["authorization"]
|
84
99
|
assert_match %r{Signed in.}, @sign_in_ui.output
|
85
100
|
|
@@ -125,14 +140,14 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
125
140
|
assert_match %r{Access Denied.}, @sign_in_ui.output
|
126
141
|
end
|
127
142
|
|
128
|
-
def util_sign_in response, host = nil
|
143
|
+
def util_sign_in response, host = nil, style = :ENV
|
129
144
|
skip 'Always uses $stdin on windows' if Gem.win_platform?
|
130
145
|
|
131
146
|
email = 'you@example.com'
|
132
147
|
password = 'secret'
|
133
148
|
|
134
149
|
if host
|
135
|
-
ENV['RUBYGEMS_HOST'] = host
|
150
|
+
ENV['RUBYGEMS_HOST'] = host if style == :ENV
|
136
151
|
else
|
137
152
|
host = Gem.host
|
138
153
|
end
|
@@ -144,7 +159,11 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|
144
159
|
@sign_in_ui = Gem::MockGemUi.new "#{email}\n#{password}\n"
|
145
160
|
|
146
161
|
use_ui @sign_in_ui do
|
147
|
-
|
162
|
+
if style == :param then
|
163
|
+
@cmd.sign_in host
|
164
|
+
else
|
165
|
+
@cmd.sign_in
|
166
|
+
end
|
148
167
|
end
|
149
168
|
end
|
150
169
|
|
@@ -964,6 +964,33 @@ load Gem.bin_path('a', 'executable', version)
|
|
964
964
|
assert_match %r|I am a shiny gem!|, @ui.output
|
965
965
|
end
|
966
966
|
|
967
|
+
def test_install_extension_and_script
|
968
|
+
@spec.extensions << "extconf.rb"
|
969
|
+
write_file File.join(@tempdir, "extconf.rb") do |io|
|
970
|
+
io.write <<-RUBY
|
971
|
+
require "mkmf"
|
972
|
+
create_makefile("#{@spec.name}")
|
973
|
+
RUBY
|
974
|
+
end
|
975
|
+
|
976
|
+
rb = File.join("lib", "#{@spec.name}.rb")
|
977
|
+
@spec.files += [rb]
|
978
|
+
write_file File.join(@tempdir, rb) do |io|
|
979
|
+
io.write <<-RUBY
|
980
|
+
# #{@spec.name}.rb
|
981
|
+
RUBY
|
982
|
+
end
|
983
|
+
|
984
|
+
assert !File.exist?(File.join(@spec.gem_dir, rb))
|
985
|
+
use_ui @ui do
|
986
|
+
path = Gem::Package.build @spec
|
987
|
+
|
988
|
+
@installer = Gem::Installer.new path
|
989
|
+
@installer.install
|
990
|
+
end
|
991
|
+
assert File.exist?(File.join(@spec.gem_dir, rb))
|
992
|
+
end
|
993
|
+
|
967
994
|
def test_installation_satisfies_dependency_eh
|
968
995
|
quick_spec 'a'
|
969
996
|
|
@@ -429,10 +429,17 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
429
429
|
|
430
430
|
digest = OpenSSL::Digest::SHA1.new
|
431
431
|
digest << metadata_gz
|
432
|
-
checksum = "#{digest.name}\t#{digest.hexdigest}\n"
|
433
432
|
|
434
|
-
|
435
|
-
|
433
|
+
checksums = {
|
434
|
+
'SHA1' => {
|
435
|
+
'metadata.gz' => digest.hexdigest,
|
436
|
+
},
|
437
|
+
}
|
438
|
+
|
439
|
+
tar.add_file 'checksums.yaml.gz', 0444 do |io|
|
440
|
+
Zlib::GzipWriter.wrap io do |gz_io|
|
441
|
+
gz_io.write YAML.dump checksums
|
442
|
+
end
|
436
443
|
end
|
437
444
|
|
438
445
|
tar.add_file 'data.tar.gz', 0444 do |io|
|
@@ -499,6 +506,50 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
499
506
|
|
500
507
|
assert_equal 'unsigned gems are not allowed by the High Security policy',
|
501
508
|
e.message
|
509
|
+
|
510
|
+
refute package.instance_variable_get(:@spec), '@spec must not be loaded'
|
511
|
+
assert_empty package.instance_variable_get(:@files), '@files must empty'
|
512
|
+
end
|
513
|
+
|
514
|
+
def test_verify_security_policy_checksum_missing
|
515
|
+
@spec.cert_chain = [PUBLIC_CERT.to_pem]
|
516
|
+
@spec.signing_key = PRIVATE_KEY
|
517
|
+
|
518
|
+
build = Gem::Package.new @gem
|
519
|
+
build.spec = @spec
|
520
|
+
build.setup_signer
|
521
|
+
|
522
|
+
FileUtils.mkdir 'lib'
|
523
|
+
FileUtils.touch 'lib/code.rb'
|
524
|
+
|
525
|
+
open @gem, 'wb' do |gem_io|
|
526
|
+
Gem::Package::TarWriter.new gem_io do |gem|
|
527
|
+
build.add_metadata gem
|
528
|
+
build.add_contents gem
|
529
|
+
|
530
|
+
# write bogus data.tar.gz to foil signature
|
531
|
+
bogus_data = Gem.gzip 'hello'
|
532
|
+
gem.add_file_simple 'data.tar.gz', 0444, bogus_data.length do |io|
|
533
|
+
io.write bogus_data
|
534
|
+
end
|
535
|
+
|
536
|
+
# pre rubygems 2.0 gems do not add checksums
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
541
|
+
|
542
|
+
package = Gem::Package.new @gem
|
543
|
+
package.security_policy = Gem::Security::HighSecurity
|
544
|
+
|
545
|
+
e = assert_raises Gem::Security::Exception do
|
546
|
+
package.verify
|
547
|
+
end
|
548
|
+
|
549
|
+
assert_equal 'invalid signature', e.message
|
550
|
+
|
551
|
+
refute package.instance_variable_get(:@spec), '@spec must not be loaded'
|
552
|
+
assert_empty package.instance_variable_get(:@files), '@files must empty'
|
502
553
|
end
|
503
554
|
|
504
555
|
def test_verify_truncate
|
@@ -18,6 +18,14 @@ class TestGemPackageOld < Gem::TestCase
|
|
18
18
|
assert_equal %w[lib/foo.rb lib/test.rb lib/test/wow.rb], @package.contents
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_contents_security_policy
|
22
|
+
@package.security_policy = Gem::Security::AlmostNoSecurity
|
23
|
+
|
24
|
+
assert_raises Gem::Security::Exception do
|
25
|
+
@package.contents
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
21
29
|
def test_extract_files
|
22
30
|
@package.extract_files @destination
|
23
31
|
|
@@ -29,9 +37,43 @@ class TestGemPackageOld < Gem::TestCase
|
|
29
37
|
assert_equal mask, File.stat(extracted).mode unless win_platform?
|
30
38
|
end
|
31
39
|
|
40
|
+
def test_extract_files_security_policy
|
41
|
+
@package.security_policy = Gem::Security::AlmostNoSecurity
|
42
|
+
|
43
|
+
assert_raises Gem::Security::Exception do
|
44
|
+
@package.extract_files @destination
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
32
48
|
def test_spec
|
33
49
|
assert_equal 'testing', @package.spec.name
|
34
50
|
end
|
35
51
|
|
52
|
+
def test_spec_security_policy
|
53
|
+
@package.security_policy = Gem::Security::AlmostNoSecurity
|
54
|
+
|
55
|
+
assert_raises Gem::Security::Exception do
|
56
|
+
@package.spec
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_verify
|
61
|
+
assert @package.verify
|
62
|
+
|
63
|
+
@package.security_policy = Gem::Security::NoSecurity
|
64
|
+
|
65
|
+
assert @package.verify
|
66
|
+
|
67
|
+
@package.security_policy = Gem::Security::AlmostNoSecurity
|
68
|
+
|
69
|
+
e = assert_raises Gem::Security::Exception do
|
70
|
+
@package.verify
|
71
|
+
end
|
72
|
+
|
73
|
+
assert_equal 'old format gems do not contain signatures ' +
|
74
|
+
'and cannot be verified',
|
75
|
+
e.message
|
76
|
+
end
|
77
|
+
|
36
78
|
end
|
37
79
|
|