Enables reading credentials from env vars.

- ServiceAccountCredentials, ServiceAccountJwtHeaderCredentials
and UserRefreshCredentials initializers now take keyword args
via options hash.

- In `credentials_loader.rb`, refactored env var checking into
private methods

- Updated tests & added new tests.

- Fixed existing test for #from_well_known_path 'fails if
the file is invalid', where `from_env` was called instead of
`from_well_known_path`.

- Fixed rubocop errors I introduced, but two existing ones remain.

- Added entry to changelog.

- Fixed rubocop errors from code containing parallel assignments

- Updated rubocop_todo.yml to ignore parallel assignments and
trailing underscore assignments.
This commit is contained in:
Herbert Siojo 2015-05-21 13:38:19 -07:00
parent 133e05cf4a
commit 5061fb5add
9 changed files with 227 additions and 71 deletions

View File

@ -1,5 +1,5 @@
# This configuration was generated by `rubocop --auto-gen-config` # This configuration was generated by `rubocop --auto-gen-config`
# on 2015-04-23 11:18:24 -0700 using RuboCop version 0.30.0. # on 2015-05-18 09:38:28 -0700 using RuboCop version 0.31.0.
# The point is for the user to remove these configuration records # The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base. # one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
@ -9,7 +9,17 @@
Metrics/AbcSize: Metrics/AbcSize:
Max: 24 Max: 24
# Offense count: 6 # Offense count: 10
# Configuration parameters: CountComments. # Configuration parameters: CountComments.
Metrics/MethodLength: Metrics/MethodLength:
Max: 13 Max: 13
# Offense count: 1
# Cop supports --auto-correct.
Performance/ParallelAssignment:
Enabled: false
# Offense count: 1
# Cop supports --auto-correct.
Style/TrailingUnderscoreVariable:
Enabled: false

View File

@ -1,3 +1,8 @@
### Changes
* Enables passing credentials via environment variables. ([@haabaato][])
[#27](https://github.com/google/google-auth-library-ruby/issues/27)
## 0.4.1 (25/04/2015) ## 0.4.1 (25/04/2015)
### Changes ### Changes
@ -20,3 +25,4 @@
[@tbetbetbe]: https://github.com/tbetbetbe [@tbetbetbe]: https://github.com/tbetbetbe
[@joneslee85]: https://github.com/joneslee85 [@joneslee85]: https://github.com/joneslee85
[@haabaato]: https://github.com/haabaato

View File

@ -52,16 +52,38 @@ END
# override CredentialsLoader#make_creds to use the class determined by # override CredentialsLoader#make_creds to use the class determined by
# loading the json. # loading the json.
def self.make_creds(json_key_io, scope = nil) def self.make_creds(options = {})
json_key_io, scope = options.values_at(:json_key_io, :scope)
if json_key_io
json_key, clz = determine_creds_class(json_key_io) json_key, clz = determine_creds_class(json_key_io)
clz.new(StringIO.new(MultiJson.dump(json_key)), scope) clz.new(json_key_io: StringIO.new(MultiJson.dump(json_key)),
scope: scope)
else
clz = read_creds
clz.new(scope: scope)
end
end
def self.read_creds
env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
type = ENV[env_var]
fail "#{ACCOUNT_TYPE_VAR} is undefined in env" unless type
case type
when 'service_account'
ServiceAccountCredentials
when 'authorized_user'
UserRefreshCredentials
else
fail "credentials type '#{type}' is not supported"
end
end end
# Reads the input json and determines which creds class to use. # Reads the input json and determines which creds class to use.
def self.determine_creds_class(json_key_io) def self.determine_creds_class(json_key_io)
json_key = MultiJson.load(json_key_io.read) json_key = MultiJson.load(json_key_io.read)
fail "the json is missing the #{key} field" unless json_key.key?('type') key = 'type'
type = json_key['type'] fail "the json is missing the '#{key}' field" unless json_key.key?(key)
type = json_key[key]
case type case type
when 'service_account' when 'service_account'
[json_key, ServiceAccountCredentials] [json_key, ServiceAccountCredentials]

View File

@ -39,6 +39,14 @@ module Google
module CredentialsLoader module CredentialsLoader
extend Memoist extend Memoist
ENV_VAR = 'GOOGLE_APPLICATION_CREDENTIALS' ENV_VAR = 'GOOGLE_APPLICATION_CREDENTIALS'
PRIVATE_KEY_VAR = 'GOOGLE_PRIVATE_KEY'
CLIENT_EMAIL_VAR = 'GOOGLE_CLIENT_EMAIL'
CLIENT_ID_VAR = 'GOOGLE_CLIENT_ID'
CLIENT_SECRET_VAR = 'GOOGLE_CLIENT_SECRET'
REFRESH_TOKEN_VAR = 'GOOGLE_REFRESH_TOKEN'
ACCOUNT_TYPE_VAR = 'GOOGLE_ACCOUNT_TYPE'
NOT_FOUND_ERROR = NOT_FOUND_ERROR =
"Unable to read the credential file specified by #{ENV_VAR}" "Unable to read the credential file specified by #{ENV_VAR}"
WELL_KNOWN_PATH = 'gcloud/application_default_credentials.json' WELL_KNOWN_PATH = 'gcloud/application_default_credentials.json'
@ -63,11 +71,14 @@ module Google
# #
# @param scope [string|array|nil] the scope(s) to access # @param scope [string|array|nil] the scope(s) to access
def from_env(scope = nil) def from_env(scope = nil)
return nil unless ENV.key?(ENV_VAR) if ENV.key?(ENV_VAR)
path = ENV[ENV_VAR] path = ENV[ENV_VAR]
fail 'file #{path} does not exist' unless File.exist?(path) fail "file #{path} does not exist" unless File.exist?(path)
File.open(path) do |f| File.open(path) do |f|
return make_creds(f, scope) return make_creds(json_key_io: f, scope: scope)
end
elsif service_account_env_vars? || authorized_user_env_vars?
return make_creds(scope: scope)
end end
rescue StandardError => e rescue StandardError => e
raise "#{NOT_FOUND_ERROR}: #{e}" raise "#{NOT_FOUND_ERROR}: #{e}"
@ -83,11 +94,22 @@ module Google
path = File.join(root, base) path = File.join(root, base)
return nil unless File.exist?(path) return nil unless File.exist?(path)
File.open(path) do |f| File.open(path) do |f|
return make_creds(f, scope) return make_creds(json_key_io: f, scope: scope)
end end
rescue StandardError => e rescue StandardError => e
raise "#{WELL_KNOWN_ERROR}: #{e}" raise "#{WELL_KNOWN_ERROR}: #{e}"
end end
private
def service_account_env_vars?
([PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR] - ENV.keys).empty?
end
def authorized_user_env_vars?
([CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR] -
ENV.keys).empty?
end
end end
end end
end end

View File

@ -62,8 +62,15 @@ module Google
# #
# @param json_key_io [IO] an IO from which the JSON key can be read # @param json_key_io [IO] an IO from which the JSON key can be read
# @param scope [string|array|nil] the scope(s) to access # @param scope [string|array|nil] the scope(s) to access
def initialize(json_key_io, scope = nil) def initialize(options = {})
json_key_io, scope = options.values_at(:json_key_io, :scope)
if json_key_io
private_key, client_email = self.class.read_json_key(json_key_io) private_key, client_email = self.class.read_json_key(json_key_io)
else
private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
end
super(token_credential_uri: TOKEN_CRED_URI, super(token_credential_uri: TOKEN_CRED_URI,
audience: TOKEN_CRED_URI, audience: TOKEN_CRED_URI,
scope: scope, scope: scope,
@ -90,7 +97,7 @@ module Google
client_email: @issuer client_email: @issuer
} }
alt_clz = ServiceAccountJwtHeaderCredentials alt_clz = ServiceAccountJwtHeaderCredentials
alt = alt_clz.new(StringIO.new(MultiJson.dump(cred_json))) alt = alt_clz.new(json_key_io: StringIO.new(MultiJson.dump(cred_json)))
alt.apply!(a_hash) alt.apply!(a_hash)
end end
end end
@ -120,7 +127,7 @@ module Google
# optional scope. Here's the constructor only has one param, so # optional scope. Here's the constructor only has one param, so
# we modify make_creds to reflect this. # we modify make_creds to reflect this.
def self.make_creds(*args) def self.make_creds(*args)
new(args[0]) new(json_key_io: args[0][:json_key_io])
end end
# Reads the private key and client email fields from the service account # Reads the private key and client email fields from the service account
@ -135,8 +142,14 @@ module Google
# Initializes a ServiceAccountJwtHeaderCredentials. # Initializes a ServiceAccountJwtHeaderCredentials.
# #
# @param json_key_io [IO] an IO from which the JSON key can be read # @param json_key_io [IO] an IO from which the JSON key can be read
def initialize(json_key_io) def initialize(options = {})
json_key_io = options[:json_key_io]
if json_key_io
private_key, client_email = self.class.read_json_key(json_key_io) private_key, client_email = self.class.read_json_key(json_key_io)
else
private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
end
@private_key = private_key @private_key = private_key
@issuer = client_email @issuer = client_email
@signing_key = OpenSSL::PKey::RSA.new(private_key) @signing_key = OpenSSL::PKey::RSA.new(private_key)

View File

@ -63,8 +63,15 @@ module Google
# #
# @param json_key_io [IO] an IO from which the JSON key can be read # @param json_key_io [IO] an IO from which the JSON key can be read
# @param scope [string|array|nil] the scope(s) to access # @param scope [string|array|nil] the scope(s) to access
def initialize(json_key_io, scope = nil) def initialize(options = {})
user_creds = self.class.read_json_key(json_key_io) json_key_io, scope = options.values_at(:json_key_io, :scope)
user_creds = self.class.read_json_key(json_key_io) if json_key_io
user_creds ||= {
client_id: ENV[CredentialsLoader::CLIENT_ID_VAR],
client_secret: ENV[CredentialsLoader::CLIENT_SECRET_VAR],
refresh_token: ENV[CredentialsLoader::REFRESH_TOKEN_VAR]
}
super(token_credential_uri: TOKEN_CRED_URI, super(token_credential_uri: TOKEN_CRED_URI,
client_id: user_creds['client_id'], client_id: user_creds['client_id'],
client_secret: user_creds['client_secret'], client_secret: user_creds['client_secret'],

View File

@ -38,14 +38,18 @@ require 'spec_helper'
describe '#get_application_default' do describe '#get_application_default' do
before(:example) do before(:example) do
@key = OpenSSL::PKey::RSA.new(2048) @key = OpenSSL::PKey::RSA.new(2048)
@var_name = CredentialsLoader::ENV_VAR @var_name = ENV_VAR
@orig = ENV[@var_name] @credential_vars = [
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, CLIENT_ID_VAR,
CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR, ACCOUNT_TYPE_VAR]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
@home = ENV['HOME'] @home = ENV['HOME']
@scope = 'https://www.googleapis.com/auth/userinfo.profile' @scope = 'https://www.googleapis.com/auth/userinfo.profile'
end end
after(:example) do after(:example) do
ENV[@var_name] = @orig unless @orig.nil? @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
ENV['HOME'] = @home unless @home == ENV['HOME'] ENV['HOME'] = @home unless @home == ENV['HOME']
end end
@ -95,8 +99,7 @@ describe '#get_application_default' do
it 'succeeds with default file without GOOGLE_APPLICATION_CREDENTIALS' do it 'succeeds with default file without GOOGLE_APPLICATION_CREDENTIALS' do
ENV.delete(@var_name) unless ENV[@var_name].nil? ENV.delete(@var_name) unless ENV[@var_name].nil?
Dir.mktmpdir do |dir| Dir.mktmpdir do |dir|
key_path = File.join(dir, '.config', key_path = File.join(dir, '.config', WELL_KNOWN_PATH)
CredentialsLoader::WELL_KNOWN_PATH)
FileUtils.mkdir_p(File.dirname(key_path)) FileUtils.mkdir_p(File.dirname(key_path))
File.write(key_path, cred_json_text) File.write(key_path, cred_json_text)
ENV['HOME'] = dir ENV['HOME'] = dir
@ -107,8 +110,7 @@ describe '#get_application_default' do
it 'succeeds with default file without a scope' do it 'succeeds with default file without a scope' do
ENV.delete(@var_name) unless ENV[@var_name].nil? ENV.delete(@var_name) unless ENV[@var_name].nil?
Dir.mktmpdir do |dir| Dir.mktmpdir do |dir|
key_path = File.join(dir, '.config', key_path = File.join(dir, '.config', WELL_KNOWN_PATH)
CredentialsLoader::WELL_KNOWN_PATH)
FileUtils.mkdir_p(File.dirname(key_path)) FileUtils.mkdir_p(File.dirname(key_path))
File.write(key_path, cred_json_text) File.write(key_path, cred_json_text)
ENV['HOME'] = dir ENV['HOME'] = dir
@ -137,17 +139,31 @@ describe '#get_application_default' do
end end
stubs.verify_stubbed_calls stubs.verify_stubbed_calls
end end
it 'succeeds if environment vars are valid' do
ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
ENV[CLIENT_ID_VAR] = cred_json[:client_id]
ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
expect(Google::Auth.get_application_default(@scope)).to_not be_nil
end
end end
describe 'when credential type is service account' do describe 'when credential type is service account' do
def cred_json_text let(:cred_json) do
cred_json = { {
private_key_id: 'a_private_key_id', private_key_id: 'a_private_key_id',
private_key: @key.to_pem, private_key: @key.to_pem,
client_email: 'app@developer.gserviceaccount.com', client_email: 'app@developer.gserviceaccount.com',
client_id: 'app.apps.googleusercontent.com', client_id: 'app.apps.googleusercontent.com',
type: 'service_account' type: 'service_account'
} }
end
def cred_json_text
MultiJson.dump(cred_json) MultiJson.dump(cred_json)
end end
@ -156,13 +172,16 @@ describe '#get_application_default' do
end end
describe 'when credential type is authorized_user' do describe 'when credential type is authorized_user' do
def cred_json_text let(:cred_json) do
cred_json = { {
client_secret: 'privatekey', client_secret: 'privatekey',
refresh_token: 'refreshtoken', refresh_token: 'refreshtoken',
client_id: 'app.apps.googleusercontent.com', client_id: 'app.apps.googleusercontent.com',
type: 'authorized_user' type: 'authorized_user'
} }
end
def cred_json_text
MultiJson.dump(cred_json) MultiJson.dump(cred_json)
end end
@ -171,13 +190,16 @@ describe '#get_application_default' do
end end
describe 'when credential type is unknown' do describe 'when credential type is unknown' do
def cred_json_text let(:cred_json) do
cred_json = { {
client_secret: 'privatekey', client_secret: 'privatekey',
refresh_token: 'refreshtoken', refresh_token: 'refreshtoken',
client_id: 'app.apps.googleusercontent.com', client_id: 'app.apps.googleusercontent.com',
type: 'not_known_type' type: 'not_known_type'
} }
end
def cred_json_text
MultiJson.dump(cred_json) MultiJson.dump(cred_json)
end end
@ -197,8 +219,7 @@ describe '#get_application_default' do
it 'fails if the well known file contains the creds' do it 'fails if the well known file contains the creds' do
ENV.delete(@var_name) unless ENV[@var_name].nil? ENV.delete(@var_name) unless ENV[@var_name].nil?
Dir.mktmpdir do |dir| Dir.mktmpdir do |dir|
key_path = File.join(dir, '.config', key_path = File.join(dir, '.config', WELL_KNOWN_PATH)
CredentialsLoader::WELL_KNOWN_PATH)
FileUtils.mkdir_p(File.dirname(key_path)) FileUtils.mkdir_p(File.dirname(key_path))
File.write(key_path, cred_json_text) File.write(key_path, cred_json_text)
ENV['HOME'] = dir ENV['HOME'] = dir
@ -208,5 +229,14 @@ describe '#get_application_default' do
expect(&blk).to raise_error RuntimeError expect(&blk).to raise_error RuntimeError
end end
end end
it 'fails if env vars are set' do
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
blk = proc do
Google::Auth.get_application_default(@scope)
end
expect(&blk).to raise_error RuntimeError
end
end end
end end

View File

@ -108,12 +108,22 @@ end
describe Google::Auth::ServiceAccountCredentials do describe Google::Auth::ServiceAccountCredentials do
ServiceAccountCredentials = Google::Auth::ServiceAccountCredentials ServiceAccountCredentials = Google::Auth::ServiceAccountCredentials
let(:client_email) { 'app@developer.gserviceaccount.com' } let(:client_email) { 'app@developer.gserviceaccount.com' }
let(:cred_json) do
{
private_key_id: 'a_private_key_id',
private_key: @key.to_pem,
client_email: client_email,
client_id: 'app.apps.googleusercontent.com',
type: 'service_account'
}
end
before(:example) do before(:example) do
@key = OpenSSL::PKey::RSA.new(2048) @key = OpenSSL::PKey::RSA.new(2048)
@client = ServiceAccountCredentials.new( @client = ServiceAccountCredentials.new(
StringIO.new(cred_json_text), json_key_io: StringIO.new(cred_json_text),
'https://www.googleapis.com/auth/userinfo.profile') scope: 'https://www.googleapis.com/auth/userinfo.profile'
)
end end
def make_auth_stubs(opts = {}) def make_auth_stubs(opts = {})
@ -131,13 +141,6 @@ describe Google::Auth::ServiceAccountCredentials do
end end
def cred_json_text def cred_json_text
cred_json = {
private_key_id: 'a_private_key_id',
private_key: @key.to_pem,
client_email: client_email,
client_id: 'app.apps.googleusercontent.com',
type: 'service_account'
}
MultiJson.dump(cred_json) MultiJson.dump(cred_json)
end end
@ -154,13 +157,18 @@ describe Google::Auth::ServiceAccountCredentials do
describe '#from_env' do describe '#from_env' do
before(:example) do before(:example) do
@var_name = ENV_VAR @var_name = ENV_VAR
@orig = ENV[@var_name] @credential_vars = [
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
@scope = 'https://www.googleapis.com/auth/userinfo.profile' @scope = 'https://www.googleapis.com/auth/userinfo.profile'
@clz = ServiceAccountCredentials @clz = ServiceAccountCredentials
end end
after(:example) do after(:example) do
ENV[@var_name] = @orig unless @orig.nil? @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
end end
it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
@ -187,6 +195,13 @@ describe Google::Auth::ServiceAccountCredentials do
expect(@clz.from_env(@scope)).to_not be_nil expect(@clz.from_env(@scope)).to_not be_nil
end end
end end
it 'succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are'\
' valid' do
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
expect(@clz.from_env(@scope)).to_not be_nil
end
end end
describe '#from_well_known_path' do describe '#from_well_known_path' do
@ -224,20 +239,22 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
let(:client_email) { 'app@developer.gserviceaccount.com' } let(:client_email) { 'app@developer.gserviceaccount.com' }
let(:clz) { Google::Auth::ServiceAccountJwtHeaderCredentials } let(:clz) { Google::Auth::ServiceAccountJwtHeaderCredentials }
let(:cred_json) do
before(:example) do {
@key = OpenSSL::PKey::RSA.new(2048)
@client = clz.new(StringIO.new(cred_json_text))
end
def cred_json_text
cred_json = {
private_key_id: 'a_private_key_id', private_key_id: 'a_private_key_id',
private_key: @key.to_pem, private_key: @key.to_pem,
client_email: client_email, client_email: client_email,
client_id: 'app.apps.googleusercontent.com', client_id: 'app.apps.googleusercontent.com',
type: 'service_account' type: 'service_account'
} }
end
before(:example) do
@key = OpenSSL::PKey::RSA.new(2048)
@client = clz.new(json_key_io: StringIO.new(cred_json_text))
end
def cred_json_text
MultiJson.dump(cred_json) MultiJson.dump(cred_json)
end end
@ -246,11 +263,15 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
describe '#from_env' do describe '#from_env' do
before(:example) do before(:example) do
@var_name = ENV_VAR @var_name = ENV_VAR
@orig = ENV[@var_name] @credential_vars = [
ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
end end
after(:example) do after(:example) do
ENV[@var_name] = @orig unless @orig.nil? @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
end end
it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
@ -277,6 +298,13 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
expect(clz.from_env).to_not be_nil expect(clz.from_env).to_not be_nil
end end
end end
it 'succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are'\
' valid' do
ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
expect(clz.from_env(@scope)).to_not be_nil
end
end end
describe '#from_well_known_path' do describe '#from_well_known_path' do

View File

@ -40,15 +40,26 @@ require 'openssl'
require 'spec_helper' require 'spec_helper'
require 'tmpdir' require 'tmpdir'
include Google::Auth::CredentialsLoader
describe Google::Auth::UserRefreshCredentials do describe Google::Auth::UserRefreshCredentials do
UserRefreshCredentials = Google::Auth::UserRefreshCredentials UserRefreshCredentials = Google::Auth::UserRefreshCredentials
CredentialsLoader = Google::Auth::CredentialsLoader
let(:cred_json) do
{
client_secret: 'privatekey',
client_id: 'client123',
refresh_token: 'refreshtoken',
type: 'authorized_user'
}
end
before(:example) do before(:example) do
@key = OpenSSL::PKey::RSA.new(2048) @key = OpenSSL::PKey::RSA.new(2048)
@client = UserRefreshCredentials.new( @client = UserRefreshCredentials.new(
StringIO.new(cred_json_text), json_key_io: StringIO.new(cred_json_text),
'https://www.googleapis.com/auth/userinfo.profile') scope: 'https://www.googleapis.com/auth/userinfo.profile'
)
end end
def make_auth_stubs(opts = {}) def make_auth_stubs(opts = {})
@ -64,12 +75,6 @@ describe Google::Auth::UserRefreshCredentials do
end end
def cred_json_text(missing = nil) def cred_json_text(missing = nil)
cred_json = {
client_secret: 'privatekey',
client_id: 'client123',
refresh_token: 'refreshtoken',
type: 'authorized_user'
}
cred_json.delete(missing.to_sym) unless missing.nil? cred_json.delete(missing.to_sym) unless missing.nil?
MultiJson.dump(cred_json) MultiJson.dump(cred_json)
end end
@ -78,14 +83,18 @@ describe Google::Auth::UserRefreshCredentials do
describe '#from_env' do describe '#from_env' do
before(:example) do before(:example) do
@var_name = CredentialsLoader::ENV_VAR @var_name = ENV_VAR
@orig = ENV[@var_name] @credential_vars = [
ENV_VAR, CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR,
ACCOUNT_TYPE_VAR]
@original_env_vals = {}
@credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
@scope = 'https://www.googleapis.com/auth/userinfo.profile' @scope = 'https://www.googleapis.com/auth/userinfo.profile'
@clz = UserRefreshCredentials @clz = UserRefreshCredentials
end end
after(:example) do after(:example) do
ENV[@var_name] = @orig unless @orig.nil? @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
end end
it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
@ -125,13 +134,22 @@ describe Google::Auth::UserRefreshCredentials do
expect(@clz.from_env(@scope)).to_not be_nil expect(@clz.from_env(@scope)).to_not be_nil
end end
end end
it 'succeeds when GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and '\
'GOOGLE_REFRESH_TOKEN env vars are valid' do
ENV[CLIENT_ID_VAR] = cred_json[:client_id]
ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
expect(@clz.from_env(@scope)).to_not be_nil
end
end end
describe '#from_well_known_path' do describe '#from_well_known_path' do
before(:example) do before(:example) do
@home = ENV['HOME'] @home = ENV['HOME']
@scope = 'https://www.googleapis.com/auth/userinfo.profile' @scope = 'https://www.googleapis.com/auth/userinfo.profile'
@known_path = CredentialsLoader::WELL_KNOWN_PATH @known_path = WELL_KNOWN_PATH
@clz = UserRefreshCredentials @clz = UserRefreshCredentials
end end
@ -152,7 +170,7 @@ describe Google::Auth::UserRefreshCredentials do
FileUtils.mkdir_p(File.dirname(key_path)) FileUtils.mkdir_p(File.dirname(key_path))
File.write(key_path, cred_json_text(missing)) File.write(key_path, cred_json_text(missing))
ENV['HOME'] = dir ENV['HOME'] = dir
expect { @clz.from_env(@scope) }.to raise_error expect { @clz.from_well_known_path(@scope) }.to raise_error
end end
end end
end end