Fix Credentials.default bug
If no PATH_ENV_VARS were found Credentials.default would return an empty array. Update each default lookup method to return nil if no match was found. Fix call to from_default_paths method, was calling from_default_vars instead. Add spec coverage for path, json, and default cases. Add spec coverage for application_default case. Fix spec coverage to check the return type from calling Credentials.default.
This commit is contained in:
parent
4c4e6cef21
commit
9f395a2338
|
@ -84,7 +84,7 @@ module Google
|
||||||
client ||= from_json_vars(scope)
|
client ||= from_json_vars(scope)
|
||||||
|
|
||||||
# Third try to find keyfile file from known file paths.
|
# Third try to find keyfile file from known file paths.
|
||||||
client ||= from_default_vars(scope)
|
client ||= from_default_paths(scope)
|
||||||
|
|
||||||
# Finally get instantiated client from Google::Auth
|
# Finally get instantiated client from Google::Auth
|
||||||
client ||= from_application_default(scope)
|
client ||= from_application_default(scope)
|
||||||
|
@ -99,6 +99,7 @@ module Google
|
||||||
.each do |file|
|
.each do |file|
|
||||||
return new file, scope: scope
|
return new file, scope: scope
|
||||||
end
|
end
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.from_json_vars(scope)
|
def self.from_json_vars(scope)
|
||||||
|
@ -114,6 +115,7 @@ module Google
|
||||||
self::JSON_ENV_VARS.map(&json).compact.each do |hash|
|
self::JSON_ENV_VARS.map(&json).compact.each do |hash|
|
||||||
return new hash, scope: scope
|
return new hash, scope: scope
|
||||||
end
|
end
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.from_default_paths(scope)
|
def self.from_default_paths(scope)
|
||||||
|
@ -122,6 +124,7 @@ module Google
|
||||||
.each do |file|
|
.each do |file|
|
||||||
return new file, scope: scope
|
return new file, scope: scope
|
||||||
end
|
end
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.from_application_default(scope)
|
def self.from_application_default(scope)
|
||||||
|
|
|
@ -103,6 +103,137 @@ describe Google::Auth::Credentials, :private do
|
||||||
mocked_signet
|
mocked_signet
|
||||||
end
|
end
|
||||||
|
|
||||||
TestCredentials.default
|
creds = TestCredentials.default
|
||||||
|
expect(creds).to be_a_kind_of(TestCredentials)
|
||||||
|
expect(creds.client).to eq(mocked_signet)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'subclasses can use PATH_ENV_VARS to get keyfile path' do
|
||||||
|
class TestCredentials < Google::Auth::Credentials
|
||||||
|
SCOPE = 'http://example.com/scope'.freeze
|
||||||
|
PATH_ENV_VARS = ['PATH_ENV_DUMMY', 'PATH_ENV_TEST'].freeze
|
||||||
|
JSON_ENV_VARS = ['JSON_ENV_DUMMY'].freeze
|
||||||
|
DEFAULT_PATHS = ['~/default/path/to/file.txt'].freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
allow(::ENV).to receive(:[]).with('PATH_ENV_DUMMY') { '/fake/path/to/file.txt' }
|
||||||
|
allow(::File).to receive(:file?).with('/fake/path/to/file.txt') { false }
|
||||||
|
allow(::ENV).to receive(:[]).with('PATH_ENV_TEST') { '/unknown/path/to/file.txt' }
|
||||||
|
allow(::File).to receive(:file?).with('/unknown/path/to/file.txt') { true }
|
||||||
|
allow(::File).to receive(:read).with('/unknown/path/to/file.txt') { JSON.generate(default_keyfile_hash) }
|
||||||
|
|
||||||
|
mocked_signet = double('Signet::OAuth2::Client')
|
||||||
|
allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
|
||||||
|
allow(Signet::OAuth2::Client).to receive(:new) do |options|
|
||||||
|
expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:scope]).to eq(['http://example.com/scope'])
|
||||||
|
expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
|
||||||
|
expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
|
||||||
|
|
||||||
|
mocked_signet
|
||||||
|
end
|
||||||
|
|
||||||
|
creds = TestCredentials.default
|
||||||
|
expect(creds).to be_a_kind_of(TestCredentials)
|
||||||
|
expect(creds.client).to eq(mocked_signet)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'subclasses can use JSON_ENV_VARS to get keyfile contents' do
|
||||||
|
class TestCredentials < Google::Auth::Credentials
|
||||||
|
SCOPE = 'http://example.com/scope'.freeze
|
||||||
|
PATH_ENV_VARS = ['PATH_ENV_DUMMY'].freeze
|
||||||
|
JSON_ENV_VARS = ['JSON_ENV_DUMMY', 'JSON_ENV_TEST'].freeze
|
||||||
|
DEFAULT_PATHS = ['~/default/path/to/file.txt'].freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
allow(::ENV).to receive(:[]).with('PATH_ENV_DUMMY') { '/fake/path/to/file.txt' }
|
||||||
|
allow(::File).to receive(:file?).with('/fake/path/to/file.txt') { false }
|
||||||
|
allow(::ENV).to receive(:[]).with('JSON_ENV_DUMMY') { nil }
|
||||||
|
allow(::ENV).to receive(:[]).with('JSON_ENV_TEST') { JSON.generate(default_keyfile_hash) }
|
||||||
|
|
||||||
|
mocked_signet = double('Signet::OAuth2::Client')
|
||||||
|
allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
|
||||||
|
allow(Signet::OAuth2::Client).to receive(:new) do |options|
|
||||||
|
expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:scope]).to eq(['http://example.com/scope'])
|
||||||
|
expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
|
||||||
|
expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
|
||||||
|
|
||||||
|
mocked_signet
|
||||||
|
end
|
||||||
|
|
||||||
|
creds = TestCredentials.default
|
||||||
|
expect(creds).to be_a_kind_of(TestCredentials)
|
||||||
|
expect(creds.client).to eq(mocked_signet)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'subclasses can use DEFAULT_PATHS to get keyfile path' do
|
||||||
|
class TestCredentials < Google::Auth::Credentials
|
||||||
|
SCOPE = 'http://example.com/scope'.freeze
|
||||||
|
PATH_ENV_VARS = ['PATH_ENV_DUMMY'].freeze
|
||||||
|
JSON_ENV_VARS = ['JSON_ENV_DUMMY'].freeze
|
||||||
|
DEFAULT_PATHS = ['~/default/path/to/file.txt'].freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
allow(::ENV).to receive(:[]).with('PATH_ENV_DUMMY') { '/fake/path/to/file.txt' }
|
||||||
|
allow(::File).to receive(:file?).with('/fake/path/to/file.txt') { false }
|
||||||
|
allow(::ENV).to receive(:[]).with('JSON_ENV_DUMMY') { nil }
|
||||||
|
allow(::File).to receive(:file?).with('~/default/path/to/file.txt') { true }
|
||||||
|
allow(::File).to receive(:read).with('~/default/path/to/file.txt') { JSON.generate(default_keyfile_hash) }
|
||||||
|
|
||||||
|
mocked_signet = double('Signet::OAuth2::Client')
|
||||||
|
allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
|
||||||
|
allow(Signet::OAuth2::Client).to receive(:new) do |options|
|
||||||
|
expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:scope]).to eq(['http://example.com/scope'])
|
||||||
|
expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
|
||||||
|
expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
|
||||||
|
|
||||||
|
mocked_signet
|
||||||
|
end
|
||||||
|
|
||||||
|
creds = TestCredentials.default
|
||||||
|
expect(creds).to be_a_kind_of(TestCredentials)
|
||||||
|
expect(creds.client).to eq(mocked_signet)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'subclasses that find no matches default to Google::Auth.get_application_default' do
|
||||||
|
class TestCredentials < Google::Auth::Credentials
|
||||||
|
SCOPE = 'http://example.com/scope'.freeze
|
||||||
|
PATH_ENV_VARS = ['PATH_ENV_DUMMY'].freeze
|
||||||
|
JSON_ENV_VARS = ['JSON_ENV_DUMMY'].freeze
|
||||||
|
DEFAULT_PATHS = ['~/default/path/to/file.txt'].freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
allow(::ENV).to receive(:[]).with('PATH_ENV_DUMMY') { '/fake/path/to/file.txt' }
|
||||||
|
allow(::File).to receive(:file?).with('/fake/path/to/file.txt') { false }
|
||||||
|
allow(::ENV).to receive(:[]).with('JSON_ENV_DUMMY') { nil }
|
||||||
|
allow(::File).to receive(:file?).with('~/default/path/to/file.txt') { false }
|
||||||
|
|
||||||
|
mocked_signet = double('Signet::OAuth2::Client')
|
||||||
|
allow(mocked_signet).to receive(:fetch_access_token!).and_return(true)
|
||||||
|
allow(Google::Auth).to receive(:get_application_default) do |scope|
|
||||||
|
expect(scope).to eq(TestCredentials::SCOPE)
|
||||||
|
|
||||||
|
# This should really be a Signet::OAuth2::Client object,
|
||||||
|
# but mocking is making that difficult, so return a valid hash instead.
|
||||||
|
default_keyfile_hash
|
||||||
|
end
|
||||||
|
allow(Signet::OAuth2::Client).to receive(:new) do |options|
|
||||||
|
expect(options[:token_credential_uri]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:audience]).to eq('https://accounts.google.com/o/oauth2/token')
|
||||||
|
expect(options[:scope]).to eq(['http://example.com/scope'])
|
||||||
|
expect(options[:issuer]).to eq(default_keyfile_hash['client_email'])
|
||||||
|
expect(options[:signing_key]).to be_a_kind_of(OpenSSL::PKey::RSA)
|
||||||
|
|
||||||
|
mocked_signet
|
||||||
|
end
|
||||||
|
|
||||||
|
creds = TestCredentials.default
|
||||||
|
expect(creds).to be_a_kind_of(TestCredentials)
|
||||||
|
expect(creds.client).to eq(mocked_signet)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue