@@ -9,7 +9,6 @@ class TestGemRemoteFetcherS3 < Gem::TestCase
9
9
include Gem ::DefaultUserInteraction
10
10
11
11
class FakeGemRequest < Gem ::Request
12
-
13
12
attr_reader :last_request , :uri
14
13
15
14
# Override perform_request to stub things
@@ -52,12 +51,13 @@ def ec2_iam_request(uri, verb)
52
51
53
52
case uri . to_s
54
53
when "http://169.254.169.254/latest/api/token"
55
- res = Gem ::Net ::HTTPOK . new nil , 200 , nil
56
- def res . body
57
- "mysecrettoken"
54
+ if $imdsv2_token_failure
55
+ res = Gem ::Net ::HTTPUnauthorized . new nil , 401 , nil
56
+ def res . body = "you got a 401! panic!"
57
+ else
58
+ res = Gem ::Net ::HTTPOK . new nil , 200 , nil
59
+ def res . body = "mysecrettoken"
58
60
end
59
- fake_s3_request . set_response ( res )
60
-
61
61
when "http://169.254.169.254/latest/meta-data/iam/info"
62
62
res = Gem ::Net ::HTTPOK . new nil , 200 , nil
63
63
def res . body
@@ -70,33 +70,26 @@ def res.body
70
70
}
71
71
JSON
72
72
end
73
- fake_s3_request . set_response ( res )
74
73
75
74
when "http://169.254.169.254/latest/meta-data/iam/security-credentials/TestRole"
76
75
res = Gem ::Net ::HTTPOK . new nil , 200 , nil
77
- def res . body
78
- $instance_profile
79
- end
80
- fake_s3_request . set_response ( res )
81
-
76
+ def res . body = $instance_profile
82
77
else
83
78
raise "Unexpected request to #{ uri } "
84
79
end
85
80
81
+ fake_s3_request . set_response ( res )
86
82
fake_s3_request
87
83
end
88
84
end
89
85
90
86
class FakeGemFetcher < Gem ::RemoteFetcher
91
-
92
87
attr_reader :fetched_uri , :last_s3_uri_signer
93
88
94
89
def request ( uri , request_class , last_modified = nil )
95
90
@fetched_uri = uri
96
91
res = Gem ::Net ::HTTPOK . new nil , 200 , nil
97
- def res . body
98
- "success"
99
- end
92
+ def res . body = "success"
100
93
res
101
94
end
102
95
@@ -132,10 +125,33 @@ def assert_fetched_s3_with_imds_v2
132
125
assert_equal ( expected . strip , recent_aws_query_logs . strip )
133
126
end
134
127
135
- def assert_fetch_s3 ( url :, signature :, token : nil , region : "us-east-1" , instance_profile_json : nil , method : "GET" )
136
- @fetcher = FakeGemFetcher . new nil
128
+ def assert_fetched_s3_with_imds_v1
129
+ # Three API requests:
130
+ # 1. Get the token (which fails)
131
+ # 2. Lookup profile details without token
132
+ # 3. Query the credentials without token
133
+ expected = <<~TEXT
134
+ PUT http://169.254.169.254/latest/api/token
135
+ x-aws-ec2-metadata-token-ttl-seconds=60
136
+ GET http://169.254.169.254/latest/meta-data/iam/info
137
+ GET http://169.254.169.254/latest/meta-data/iam/security-credentials/TestRole
138
+ TEXT
139
+ recent_aws_query_logs = @fetcher . last_s3_uri_signer . recent_aws_query_logs
140
+ assert_equal ( expected . strip , recent_aws_query_logs . strip )
141
+ end
142
+
143
+ def with_imds_v2_failure
144
+ $imdsv2_token_failure = true
145
+ yield ( fetcher )
146
+ ensure
147
+ $imdsv2_token_failure = nil
148
+ end
149
+
150
+ def assert_fetch_s3 ( url :, signature :, token : nil , region : "us-east-1" , instance_profile_json : nil , fetcher : nil , method : "GET" )
151
+ @fetcher = fetcher || FakeGemFetcher . new ( nil )
137
152
$instance_profile = instance_profile_json
138
- res = fetcher . fetch_s3 Gem ::URI . parse ( url ) , nil , ( method == "HEAD" )
153
+ res = @fetcher . fetch_s3 Gem ::URI . parse ( url ) , nil , ( method == "HEAD" )
154
+ $imdsv2_token_failure ||= nil
139
155
140
156
assert_equal "https://my-bucket.s3.#{ region } .amazonaws.com/gems/specs.4.8.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=testuser%2F20190624%2F#{ region } %2Fs3%2Faws4_request&X-Amz-Date=20190624T051941Z&X-Amz-Expires=86400#{ token ? "&X-Amz-Security-Token=" + token : "" } &X-Amz-SignedHeaders=host&X-Amz-Signature=#{ signature } " , @fetcher . fetched_uri . to_s
141
157
if method == "HEAD"
@@ -373,14 +389,16 @@ def test_fetch_s3_instance_profile_creds_with_fallback
373
389
374
390
url = "s3://my-bucket/gems/specs.4.8.gz"
375
391
Time . stub :now , Time . at ( 1_561_353_581 ) do
376
- assert_fetch_s3 (
377
- url : url ,
378
- signature : "e709338735f9077edf8f6b94b247171c266a9605975e08e4a519a123c3322625" ,
379
- token : "testtoken" ,
380
- region : "us-east-1" ,
381
- instance_profile_json : '{"AccessKeyId": "testuser", "SecretAccessKey": "testpass", "Token": "testtoken"}'
382
- )
383
- assert_fetched_s3_with_imds_v2
392
+ with_imds_v2_failure do
393
+ assert_fetch_s3 (
394
+ url : url ,
395
+ signature : "e709338735f9077edf8f6b94b247171c266a9605975e08e4a519a123c3322625" ,
396
+ token : "testtoken" ,
397
+ region : "us-east-1" ,
398
+ instance_profile_json : '{"AccessKeyId": "testuser", "SecretAccessKey": "testpass", "Token": "testtoken"}'
399
+ )
400
+ assert_fetched_s3_with_imds_v1
401
+ end
384
402
end
385
403
ensure
386
404
Gem . configuration [ :s3_source ] = nil
0 commit comments