Merge pull request #25 from tbetbetbe/ruby-auth-check-404-on-compute

Adds more robust checking of the status code during compute engine auth.
This commit is contained in:
Steve Bazyl 2015-04-23 11:49:07 -07:00
commit b5ff47fecb
3 changed files with 61 additions and 6 deletions

View File

@ -1,5 +1,5 @@
# This configuration was generated by `rubocop --auto-gen-config`
# on 2015-03-06 19:51:00 -0800 using RuboCop version 0.28.0.
# on 2015-04-23 11:18:24 -0700 using RuboCop version 0.30.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@ -9,7 +9,7 @@
Metrics/AbcSize:
Max: 24
# Offense count: 3
# Offense count: 6
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 11
Max: 13

View File

@ -35,13 +35,24 @@ module Google
# Module Auth provides classes that provide Google-specific authorization
# used to access Google APIs.
module Auth
NO_METADATA_SERVER_ERROR = <<END
Error code 404 trying to get security access token
from Compute Engine metadata for the default service account. This
may be because the virtual machine instance does not have permission
scopes specified.
END
UNEXPECTED_ERROR_SUFFIX = <<END
trying to get security access token from Compute Engine metadata for
the default service account
END
# Extends Signet::OAuth2::Client so that the auth token is obtained from
# the GCE metadata server.
class GCECredentials < Signet::OAuth2::Client
# The IP Address is used in the URIs to speed up failures on non-GCE
# systems.
COMPUTE_AUTH_TOKEN_URI = 'http://169.254.169.254/computeMetadata/v1/'\
'instance/service-accounts/default/token'
'instance/service-accounts/default/token'
COMPUTE_CHECK_URI = 'http://169.254.169.254'
class << self
@ -78,8 +89,16 @@ module Google
c = options[:connection] || Faraday.default_connection
c.headers = { 'Metadata-Flavor' => 'Google' }
resp = c.get(COMPUTE_AUTH_TOKEN_URI)
Signet::OAuth2.parse_credentials(resp.body,
resp.headers['content-type'])
case resp.status
when 200
Signet::OAuth2.parse_credentials(resp.body,
resp.headers['content-type'])
when 404
fail(Signet::AuthorizationError, NO_METADATA_SERVER_ERROR)
else
msg = "Unexpected error code #{resp.status}" + UNEXPECTED_ERROR_SUFFIX
fail(Signet::AuthorizationError, msg)
end
end
end
end

View File

@ -60,6 +60,42 @@ describe Google::Auth::GCECredentials do
it_behaves_like 'apply/apply! are OK'
context 'metadata is unavailable' do
describe '#fetch_access_token' do
it 'should fail if the metadata request returns a 404' do
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get(MD_URI) do |_env|
[404,
{ 'Metadata-Flavor' => 'Google' },
'']
end
end
c = Faraday.new do |b|
b.adapter(:test, stubs)
end
blk = proc { @client.fetch_access_token!(connection: c) }
expect(&blk).to raise_error Signet::AuthorizationError
stubs.verify_stubbed_calls
end
it 'should fail if the metadata request returns an unexpected code' do
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get(MD_URI) do |_env|
[503,
{ 'Metadata-Flavor' => 'Google' },
'']
end
end
c = Faraday.new do |b|
b.adapter(:test, stubs)
end
blk = proc { @client.fetch_access_token!(connection: c) }
expect(&blk).to raise_error Signet::AuthorizationError
stubs.verify_stubbed_calls
end
end
end
describe '#on_gce?' do
it 'should be true when Metadata-Flavor is Google' do
stubs = Faraday::Adapter::Test::Stubs.new do |stub|