Skip to content

Commit

Permalink
Merge 70565e6 into 328fed6
Browse files Browse the repository at this point in the history
  • Loading branch information
blowmage committed Nov 10, 2017
2 parents 328fed6 + 70565e6 commit f8788f1
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 2 deletions.
5 changes: 4 additions & 1 deletion lib/googleauth/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def self.default(options = {})
client ||= from_json_vars(scope)

# 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
client ||= from_application_default(scope)
Expand All @@ -99,6 +99,7 @@ def self.from_path_vars(scope)
.each do |file|
return new file, scope: scope
end
nil
end

def self.from_json_vars(scope)
Expand All @@ -114,6 +115,7 @@ def self.from_json_vars(scope)
self::JSON_ENV_VARS.map(&json).compact.each do |hash|
return new hash, scope: scope
end
nil
end

def self.from_default_paths(scope)
Expand All @@ -122,6 +124,7 @@ def self.from_default_paths(scope)
.each do |file|
return new file, scope: scope
end
nil
end

def self.from_application_default(scope)
Expand Down
133 changes: 132 additions & 1 deletion spec/googleauth/credentials_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,137 @@ class TestCredentials < Google::Auth::Credentials
mocked_signet
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_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_TEST') { 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_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_TEST') { 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
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
include RSpec::LoggingHelper
config.capture_log_messages
config.include WebMock::API
config.filter_run focus: true
config.run_all_when_everything_filtered = true
end

module TestHelpers
Expand Down

0 comments on commit f8788f1

Please sign in to comment.