googleauth 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e62231971bac1c91acd998f3c70095834c4f4b6c
4
- data.tar.gz: dc687953a02e4c2eca85dbf044bcab4be46e69fd
3
+ metadata.gz: adef96ddcbbab3bf0cdf0bcb5e2772bbf3de2f04
4
+ data.tar.gz: ab58fe380898294110ec76ac571a22ef411efe6b
5
5
  SHA512:
6
- metadata.gz: e18ff4154e5f66978e93156551804699cd3a62d4ae920893a94178ad276495130bbb0711b1e6284ab35eef04191f306c0c457aeedfad3b68e0612529daaf3b86
7
- data.tar.gz: 4835734c63b673c62fcfbea1ee6407f2ffb1a7cc3c05d5bffecfbe8293e186b9f8a7d594d1722097d552b205e64fa3d4ff6e566ceadc8035c9e7a0c5c8c9bb59
6
+ metadata.gz: 5ad82896ca3cac5f605ece8cf51c512bc4625c782045452fee044064ae4d751e33e29101f6c9caef569f08816b1b1066626000a3b541c30dc02033a70cbebe7c
7
+ data.tar.gz: cd31e77291d39c9cf44c6ffa39a3e939274a5ca9834d6ee558f2e5ec4d5b575d6c8d29655cbaa4b25dc8e5ca89330a5f87d61dd1eea302398ac388c27f56aa46
@@ -1,5 +1,5 @@
1
1
  # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2015-04-23 11:18:24 -0700 using RuboCop version 0.30.0.
2
+ # on 2015-05-18 09:38:28 -0700 using RuboCop version 0.31.0.
3
3
  # The point is for the user to remove these configuration records
4
4
  # one by one as the offenses are removed from the code base.
5
5
  # Note that changes in the inspected code, or installation of new
@@ -9,7 +9,7 @@
9
9
  Metrics/AbcSize:
10
10
  Max: 24
11
11
 
12
- # Offense count: 6
12
+ # Offense count: 10
13
13
  # Configuration parameters: CountComments.
14
14
  Metrics/MethodLength:
15
15
  Max: 13
@@ -1,3 +1,4 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
4
  - 2.2
@@ -7,9 +8,24 @@ rvm:
7
8
  - rbx-2
8
9
  - jruby
9
10
  script: "bundle exec rake"
11
+ addons:
12
+ apt:
13
+ packages:
14
+ - idn
15
+ - build-essential # this and below attempt allow rubinius to be setup ok
16
+ - bison
17
+ - ruby-dev
18
+ - rake zlib1g-dev
19
+ - libyaml-dev
20
+ - libssl-dev
21
+ - libreadline-dev
22
+ - libncurses5-dev
23
+ - llvm
24
+ - llvm-dev
25
+ - libeditline-dev
26
+ - libedit-dev
10
27
  before_install:
11
- - sudo apt-get update
12
- - sudo apt-get install idn
28
+ - gem update bundler
13
29
  notifications:
14
30
  email:
15
31
  recipients:
@@ -1,3 +1,24 @@
1
+ ## 0.4.2 (05/08/2015)
2
+
3
+ ### Changes
4
+
5
+ * Updated UserRefreshCredentials hash to use string keys ([@haabator][])
6
+ [#36](https://github.com/google/google-auth-library-ruby/issues/36)
7
+
8
+ * Add support for a system default credentials file. ([@mr-salty][])
9
+ [#33](https://github.com/google/google-auth-library-ruby/issues/33)
10
+
11
+ * Fix bug when loading credentials from ENV ([@dwilkie][])
12
+ [#31](https://github.com/google/google-auth-library-ruby/issues/31)
13
+
14
+ * Relax the constraint of dependent version of multi_json ([@igrep][])
15
+ [#30](https://github.com/google/google-auth-library-ruby/issues/30)
16
+
17
+ ### Changes
18
+
19
+ * Enables passing credentials via environment variables. ([@haabaato][])
20
+ [#27](https://github.com/google/google-auth-library-ruby/issues/27)
21
+
1
22
  ## 0.4.1 (25/04/2015)
2
23
 
3
24
  ### Changes
@@ -18,5 +39,9 @@
18
39
  * makes the scope parameter's optional in all APIs. ([@tbetbetbe][])
19
40
  * changes the scope parameter's position in various constructors. ([@tbetbetbe][])
20
41
 
21
- [@tbetbetbe]: https://github.com/tbetbetbe
42
+ [@dwilkie]: https://github.com/dwilkie
43
+ [@haabaato]: https://github.com/haabaato
44
+ [@igrep]: https://github.com/igrep
22
45
  [@joneslee85]: https://github.com/joneslee85
46
+ [@mr-salty]: https://github.com/mr-salty
47
+ [@tbetbetbe]: https://github.com/tbetbetbe
@@ -29,12 +29,13 @@ Gem::Specification.new do |s|
29
29
  s.add_dependency 'logging', '~> 2.0'
30
30
  s.add_dependency 'jwt', '~> 1.4'
31
31
  s.add_dependency 'memoist', '~> 0.12'
32
- s.add_dependency 'multi_json', '1.11'
32
+ s.add_dependency 'multi_json', '~> 1.11'
33
33
  s.add_dependency 'signet', '~> 0.6'
34
34
 
35
35
  s.add_development_dependency 'bundler', '~> 1.9'
36
36
  s.add_development_dependency 'simplecov', '~> 0.9'
37
37
  s.add_development_dependency 'coveralls', '~> 0.7'
38
+ s.add_development_dependency 'fakefs', '~> 0.6'
38
39
  s.add_development_dependency 'rake', '~> 10.0'
39
40
  s.add_development_dependency 'rubocop', '~> 0.30'
40
41
  s.add_development_dependency 'rspec', '~> 3.0'
@@ -52,16 +52,38 @@ END
52
52
 
53
53
  # override CredentialsLoader#make_creds to use the class determined by
54
54
  # loading the json.
55
- def self.make_creds(json_key_io, scope = nil)
56
- json_key, clz = determine_creds_class(json_key_io)
57
- clz.new(StringIO.new(MultiJson.dump(json_key)), scope)
55
+ def self.make_creds(options = {})
56
+ json_key_io, scope = options.values_at(:json_key_io, :scope)
57
+ if json_key_io
58
+ json_key, clz = determine_creds_class(json_key_io)
59
+ clz.new(json_key_io: StringIO.new(MultiJson.dump(json_key)),
60
+ scope: scope)
61
+ else
62
+ clz = read_creds
63
+ clz.new(scope: scope)
64
+ end
65
+ end
66
+
67
+ def self.read_creds
68
+ env_var = CredentialsLoader::ACCOUNT_TYPE_VAR
69
+ type = ENV[env_var]
70
+ fail "#{ACCOUNT_TYPE_VAR} is undefined in env" unless type
71
+ case type
72
+ when 'service_account'
73
+ ServiceAccountCredentials
74
+ when 'authorized_user'
75
+ UserRefreshCredentials
76
+ else
77
+ fail "credentials type '#{type}' is not supported"
78
+ end
58
79
  end
59
80
 
60
81
  # Reads the input json and determines which creds class to use.
61
82
  def self.determine_creds_class(json_key_io)
62
83
  json_key = MultiJson.load(json_key_io.read)
63
- fail "the json is missing the #{key} field" unless json_key.key?('type')
64
- type = json_key['type']
84
+ key = 'type'
85
+ fail "the json is missing the '#{key}' field" unless json_key.key?(key)
86
+ type = json_key[key]
65
87
  case type
66
88
  when 'service_account'
67
89
  [json_key, ServiceAccountCredentials]
@@ -88,7 +110,8 @@ END
88
110
  # @param options [hash] allows override of the connection being used
89
111
  def get_application_default(scope = nil, options = {})
90
112
  creds = DefaultCredentials.from_env(scope) ||
91
- DefaultCredentials.from_well_known_path(scope)
113
+ DefaultCredentials.from_well_known_path(scope) ||
114
+ DefaultCredentials.from_system_default_path(scope)
92
115
  return creds unless creds.nil?
93
116
  fail NOT_FOUND_ERROR unless GCECredentials.on_gce?(options)
94
117
  GCECredentials.new
@@ -39,11 +39,22 @@ module Google
39
39
  module CredentialsLoader
40
40
  extend Memoist
41
41
  ENV_VAR = 'GOOGLE_APPLICATION_CREDENTIALS'
42
+
43
+ PRIVATE_KEY_VAR = 'GOOGLE_PRIVATE_KEY'
44
+ CLIENT_EMAIL_VAR = 'GOOGLE_CLIENT_EMAIL'
45
+ CLIENT_ID_VAR = 'GOOGLE_CLIENT_ID'
46
+ CLIENT_SECRET_VAR = 'GOOGLE_CLIENT_SECRET'
47
+ REFRESH_TOKEN_VAR = 'GOOGLE_REFRESH_TOKEN'
48
+ ACCOUNT_TYPE_VAR = 'GOOGLE_ACCOUNT_TYPE'
49
+
50
+ CREDENTIALS_FILE_NAME = 'application_default_credentials.json'
42
51
  NOT_FOUND_ERROR =
43
52
  "Unable to read the credential file specified by #{ENV_VAR}"
44
- WELL_KNOWN_PATH = 'gcloud/application_default_credentials.json'
53
+ WELL_KNOWN_PATH = "gcloud/#{CREDENTIALS_FILE_NAME}"
45
54
  WELL_KNOWN_ERROR = 'Unable to read the default credential file'
46
55
 
56
+ SYSTEM_DEFAULT_ERROR = 'Unable to read the system default credential file'
57
+
47
58
  # determines if the current OS is windows
48
59
  def windows?
49
60
  RbConfig::CONFIG['host_os'] =~ /Windows|mswin/
@@ -63,11 +74,14 @@ module Google
63
74
  #
64
75
  # @param scope [string|array|nil] the scope(s) to access
65
76
  def from_env(scope = nil)
66
- return nil unless ENV.key?(ENV_VAR)
67
- path = ENV[ENV_VAR]
68
- fail 'file #{path} does not exist' unless File.exist?(path)
69
- File.open(path) do |f|
70
- return make_creds(f, scope)
77
+ if ENV.key?(ENV_VAR)
78
+ path = ENV[ENV_VAR]
79
+ fail "file #{path} does not exist" unless File.exist?(path)
80
+ File.open(path) do |f|
81
+ return make_creds(json_key_io: f, scope: scope)
82
+ end
83
+ elsif service_account_env_vars? || authorized_user_env_vars?
84
+ return make_creds(scope: scope)
71
85
  end
72
86
  rescue StandardError => e
73
87
  raise "#{NOT_FOUND_ERROR}: #{e}"
@@ -77,17 +91,48 @@ module Google
77
91
  #
78
92
  # @param scope [string|array|nil] the scope(s) to access
79
93
  def from_well_known_path(scope = nil)
80
- home_var, base = windows? ? 'APPDATA' : 'HOME', WELL_KNOWN_PATH
94
+ home_var = windows? ? 'APPDATA' : 'HOME'
95
+ base = WELL_KNOWN_PATH
81
96
  root = ENV[home_var].nil? ? '' : ENV[home_var]
82
97
  base = File.join('.config', base) unless windows?
83
98
  path = File.join(root, base)
84
99
  return nil unless File.exist?(path)
85
100
  File.open(path) do |f|
86
- return make_creds(f, scope)
101
+ return make_creds(json_key_io: f, scope: scope)
87
102
  end
88
103
  rescue StandardError => e
89
104
  raise "#{WELL_KNOWN_ERROR}: #{e}"
90
105
  end
106
+
107
+ # Creates an instance from the system default path
108
+ #
109
+ # @param scope [string|array|nil] the scope(s) to access
110
+ def from_system_default_path(scope = nil)
111
+ if windows?
112
+ return nil unless ENV['ProgramData']
113
+ prefix = File.join(ENV['ProgramData'], 'Google/Auth')
114
+ else
115
+ prefix = '/etc/google/auth/'
116
+ end
117
+ path = File.join(prefix, CREDENTIALS_FILE_NAME)
118
+ return nil unless File.exist?(path)
119
+ File.open(path) do |f|
120
+ return make_creds(json_key_io: f, scope: scope)
121
+ end
122
+ rescue StandardError => e
123
+ raise "#{SYSTEM_DEFAULT_ERROR}: #{e}"
124
+ end
125
+
126
+ private
127
+
128
+ def service_account_env_vars?
129
+ ([PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR] - ENV.keys).empty?
130
+ end
131
+
132
+ def authorized_user_env_vars?
133
+ ([CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR] -
134
+ ENV.keys).empty?
135
+ end
91
136
  end
92
137
  end
93
138
  end
@@ -0,0 +1,75 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'googleauth/signet'
31
+ require 'googleauth/credentials_loader'
32
+ require 'multi_json'
33
+
34
+ module Google
35
+ # Module Auth provides classes that provide Google-specific authorization
36
+ # used to access Google APIs.
37
+ module Auth
38
+ # Authenticates requests using IAM credentials.
39
+ class IAMCredentials
40
+ SELECTOR_KEY = 'x-goog-iam-authority-selector'
41
+ TOKEN_KEY = 'x-goog-iam-authorization-token'
42
+
43
+ # Initializes an IAMCredentials.
44
+ #
45
+ # @param selector the IAM selector.
46
+ # @param token the IAM token.
47
+ def initialize(selector, token)
48
+ fail TypeError unless selector.is_a? String
49
+ fail TypeError unless token.is_a? String
50
+ @selector = selector
51
+ @token = token
52
+ end
53
+
54
+ # Adds the credential fields to the hash.
55
+ def apply!(a_hash)
56
+ a_hash[SELECTOR_KEY] = @selector
57
+ a_hash[TOKEN_KEY] = @token
58
+ a_hash
59
+ end
60
+
61
+ # Returns a clone of a_hash updated with the authoriation header
62
+ def apply(a_hash)
63
+ a_copy = a_hash.clone
64
+ apply!(a_copy)
65
+ a_copy
66
+ end
67
+
68
+ # Returns a reference to the #apply method, suitable for passing as
69
+ # a closure
70
+ def updater_proc
71
+ lambda(&method(:apply))
72
+ end
73
+ end
74
+ end
75
+ end
@@ -62,8 +62,15 @@ module Google
62
62
  #
63
63
  # @param json_key_io [IO] an IO from which the JSON key can be read
64
64
  # @param scope [string|array|nil] the scope(s) to access
65
- def initialize(json_key_io, scope = nil)
66
- private_key, client_email = self.class.read_json_key(json_key_io)
65
+ def initialize(options = {})
66
+ json_key_io, scope = options.values_at(:json_key_io, :scope)
67
+ if json_key_io
68
+ private_key, client_email = self.class.read_json_key(json_key_io)
69
+ else
70
+ private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
71
+ client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
72
+ end
73
+
67
74
  super(token_credential_uri: TOKEN_CRED_URI,
68
75
  audience: TOKEN_CRED_URI,
69
76
  scope: scope,
@@ -90,7 +97,7 @@ module Google
90
97
  client_email: @issuer
91
98
  }
92
99
  alt_clz = ServiceAccountJwtHeaderCredentials
93
- alt = alt_clz.new(StringIO.new(MultiJson.dump(cred_json)))
100
+ alt = alt_clz.new(json_key_io: StringIO.new(MultiJson.dump(cred_json)))
94
101
  alt.apply!(a_hash)
95
102
  end
96
103
  end
@@ -120,7 +127,7 @@ module Google
120
127
  # optional scope. Here's the constructor only has one param, so
121
128
  # we modify make_creds to reflect this.
122
129
  def self.make_creds(*args)
123
- new(args[0])
130
+ new(json_key_io: args[0][:json_key_io])
124
131
  end
125
132
 
126
133
  # Reads the private key and client email fields from the service account
@@ -135,8 +142,14 @@ module Google
135
142
  # Initializes a ServiceAccountJwtHeaderCredentials.
136
143
  #
137
144
  # @param json_key_io [IO] an IO from which the JSON key can be read
138
- def initialize(json_key_io)
139
- private_key, client_email = self.class.read_json_key(json_key_io)
145
+ def initialize(options = {})
146
+ json_key_io = options[:json_key_io]
147
+ if json_key_io
148
+ private_key, client_email = self.class.read_json_key(json_key_io)
149
+ else
150
+ private_key = ENV[CredentialsLoader::PRIVATE_KEY_VAR]
151
+ client_email = ENV[CredentialsLoader::CLIENT_EMAIL_VAR]
152
+ end
140
153
  @private_key = private_key
141
154
  @issuer = client_email
142
155
  @signing_key = OpenSSL::PKey::RSA.new(private_key)
@@ -63,8 +63,15 @@ module Google
63
63
  #
64
64
  # @param json_key_io [IO] an IO from which the JSON key can be read
65
65
  # @param scope [string|array|nil] the scope(s) to access
66
- def initialize(json_key_io, scope = nil)
67
- user_creds = self.class.read_json_key(json_key_io)
66
+ def initialize(options = {})
67
+ json_key_io, scope = options.values_at(:json_key_io, :scope)
68
+ user_creds = self.class.read_json_key(json_key_io) if json_key_io
69
+ user_creds ||= {
70
+ 'client_id' => ENV[CredentialsLoader::CLIENT_ID_VAR],
71
+ 'client_secret' => ENV[CredentialsLoader::CLIENT_SECRET_VAR],
72
+ 'refresh_token' => ENV[CredentialsLoader::REFRESH_TOKEN_VAR]
73
+ }
74
+
68
75
  super(token_credential_uri: TOKEN_CRED_URI,
69
76
  client_id: user_creds['client_id'],
70
77
  client_secret: user_creds['client_secret'],
@@ -31,6 +31,6 @@ module Google
31
31
  # Module Auth provides classes that provide Google-specific authorization
32
32
  # used to access Google APIs.
33
33
  module Auth
34
- VERSION = '0.4.1'
34
+ VERSION = '0.4.2'
35
35
  end
36
36
  end
@@ -32,20 +32,25 @@ $LOAD_PATH.unshift(spec_dir)
32
32
  $LOAD_PATH.uniq!
33
33
 
34
34
  require 'faraday'
35
+ require 'fakefs/safe'
35
36
  require 'googleauth'
36
37
  require 'spec_helper'
37
38
 
38
39
  describe '#get_application_default' do
39
40
  before(:example) do
40
41
  @key = OpenSSL::PKey::RSA.new(2048)
41
- @var_name = CredentialsLoader::ENV_VAR
42
- @orig = ENV[@var_name]
42
+ @var_name = ENV_VAR
43
+ @credential_vars = [
44
+ ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, CLIENT_ID_VAR,
45
+ CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR, ACCOUNT_TYPE_VAR]
46
+ @original_env_vals = {}
47
+ @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
43
48
  @home = ENV['HOME']
44
49
  @scope = 'https://www.googleapis.com/auth/userinfo.profile'
45
50
  end
46
51
 
47
52
  after(:example) do
48
- ENV[@var_name] = @orig unless @orig.nil?
53
+ @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
49
54
  ENV['HOME'] = @home unless @home == ENV['HOME']
50
55
  end
51
56
 
@@ -54,7 +59,8 @@ describe '#get_application_default' do
54
59
  Dir.mktmpdir do |dir|
55
60
  key_path = File.join(dir, 'does-not-exist')
56
61
  ENV[@var_name] = key_path
57
- expect { Google::Auth.get_application_default(@scope) }.to raise_error
62
+ expect { Google::Auth.get_application_default(@scope) }
63
+ .to raise_error RuntimeError
58
64
  end
59
65
  end
60
66
 
@@ -65,17 +71,17 @@ describe '#get_application_default' do
65
71
  { 'Metadata-Flavor' => 'Google' },
66
72
  '']
67
73
  end
68
- end # GCE not detected
74
+ end # GCE not detected
69
75
  Dir.mktmpdir do |dir|
70
76
  ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
71
- ENV['HOME'] = dir # no config present in this tmp dir
77
+ ENV['HOME'] = dir # no config present in this tmp dir
72
78
  c = Faraday.new do |b|
73
79
  b.adapter(:test, stubs)
74
80
  end
75
81
  blk = proc do
76
82
  Google::Auth.get_application_default(@scope, connection: c)
77
83
  end
78
- expect(&blk).to raise_error
84
+ expect(&blk).to raise_error RuntimeError
79
85
  end
80
86
  stubs.verify_stubbed_calls
81
87
  end
@@ -95,8 +101,7 @@ describe '#get_application_default' do
95
101
  it 'succeeds with default file without GOOGLE_APPLICATION_CREDENTIALS' do
96
102
  ENV.delete(@var_name) unless ENV[@var_name].nil?
97
103
  Dir.mktmpdir do |dir|
98
- key_path = File.join(dir, '.config',
99
- CredentialsLoader::WELL_KNOWN_PATH)
104
+ key_path = File.join(dir, '.config', WELL_KNOWN_PATH)
100
105
  FileUtils.mkdir_p(File.dirname(key_path))
101
106
  File.write(key_path, cred_json_text)
102
107
  ENV['HOME'] = dir
@@ -107,8 +112,7 @@ describe '#get_application_default' do
107
112
  it 'succeeds with default file without a scope' do
108
113
  ENV.delete(@var_name) unless ENV[@var_name].nil?
109
114
  Dir.mktmpdir do |dir|
110
- key_path = File.join(dir, '.config',
111
- CredentialsLoader::WELL_KNOWN_PATH)
115
+ key_path = File.join(dir, '.config', WELL_KNOWN_PATH)
112
116
  FileUtils.mkdir_p(File.dirname(key_path))
113
117
  File.write(key_path, cred_json_text)
114
118
  ENV['HOME'] = dir
@@ -123,10 +127,10 @@ describe '#get_application_default' do
123
127
  { 'Metadata-Flavor' => 'Google' },
124
128
  '']
125
129
  end
126
- end # GCE detected
130
+ end # GCE detected
127
131
  Dir.mktmpdir do |dir|
128
132
  ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
129
- ENV['HOME'] = dir # no config present in this tmp dir
133
+ ENV['HOME'] = dir # no config present in this tmp dir
130
134
  c = Faraday.new do |b|
131
135
  b.adapter(:test, stubs)
132
136
  end
@@ -137,17 +141,42 @@ describe '#get_application_default' do
137
141
  end
138
142
  stubs.verify_stubbed_calls
139
143
  end
144
+
145
+ it 'succeeds with system default file' do
146
+ ENV.delete(@var_name) unless ENV[@var_name].nil?
147
+ FakeFS do
148
+ key_path = File.join('/etc/google/auth/', CREDENTIALS_FILE_NAME)
149
+ FileUtils.mkdir_p(File.dirname(key_path))
150
+ File.write(key_path, cred_json_text)
151
+ expect(Google::Auth.get_application_default(@scope)).to_not be_nil
152
+ File.delete(key_path)
153
+ end
154
+ end
155
+
156
+ it 'succeeds if environment vars are valid' do
157
+ ENV.delete(@var_name) unless ENV[@var_name].nil? # no env var
158
+ ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
159
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
160
+ ENV[CLIENT_ID_VAR] = cred_json[:client_id]
161
+ ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
162
+ ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
163
+ ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
164
+ expect(Google::Auth.get_application_default(@scope)).to_not be_nil
165
+ end
140
166
  end
141
167
 
142
168
  describe 'when credential type is service account' do
143
- def cred_json_text
144
- cred_json = {
169
+ let(:cred_json) do
170
+ {
145
171
  private_key_id: 'a_private_key_id',
146
172
  private_key: @key.to_pem,
147
173
  client_email: 'app@developer.gserviceaccount.com',
148
174
  client_id: 'app.apps.googleusercontent.com',
149
175
  type: 'service_account'
150
176
  }
177
+ end
178
+
179
+ def cred_json_text
151
180
  MultiJson.dump(cred_json)
152
181
  end
153
182
 
@@ -156,13 +185,16 @@ describe '#get_application_default' do
156
185
  end
157
186
 
158
187
  describe 'when credential type is authorized_user' do
159
- def cred_json_text
160
- cred_json = {
188
+ let(:cred_json) do
189
+ {
161
190
  client_secret: 'privatekey',
162
191
  refresh_token: 'refreshtoken',
163
192
  client_id: 'app.apps.googleusercontent.com',
164
193
  type: 'authorized_user'
165
194
  }
195
+ end
196
+
197
+ def cred_json_text
166
198
  MultiJson.dump(cred_json)
167
199
  end
168
200
 
@@ -171,13 +203,18 @@ describe '#get_application_default' do
171
203
  end
172
204
 
173
205
  describe 'when credential type is unknown' do
174
- def cred_json_text
175
- cred_json = {
206
+ let(:cred_json) do
207
+ {
176
208
  client_secret: 'privatekey',
177
209
  refresh_token: 'refreshtoken',
178
210
  client_id: 'app.apps.googleusercontent.com',
211
+ private_key: @key.to_pem,
212
+ client_email: 'app@developer.gserviceaccount.com',
179
213
  type: 'not_known_type'
180
214
  }
215
+ end
216
+
217
+ def cred_json_text
181
218
  MultiJson.dump(cred_json)
182
219
  end
183
220
 
@@ -197,8 +234,7 @@ describe '#get_application_default' do
197
234
  it 'fails if the well known file contains the creds' do
198
235
  ENV.delete(@var_name) unless ENV[@var_name].nil?
199
236
  Dir.mktmpdir do |dir|
200
- key_path = File.join(dir, '.config',
201
- CredentialsLoader::WELL_KNOWN_PATH)
237
+ key_path = File.join(dir, '.config', WELL_KNOWN_PATH)
202
238
  FileUtils.mkdir_p(File.dirname(key_path))
203
239
  File.write(key_path, cred_json_text)
204
240
  ENV['HOME'] = dir
@@ -208,5 +244,14 @@ describe '#get_application_default' do
208
244
  expect(&blk).to raise_error RuntimeError
209
245
  end
210
246
  end
247
+
248
+ it 'fails if env vars are set' do
249
+ ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
250
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
251
+ blk = proc do
252
+ Google::Auth.get_application_default(@scope)
253
+ end
254
+ expect(&blk).to raise_error RuntimeError
255
+ end
211
256
  end
212
257
  end
@@ -0,0 +1,80 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
31
+ $LOAD_PATH.unshift(spec_dir)
32
+ $LOAD_PATH.uniq!
33
+
34
+ require 'googleauth/iam'
35
+
36
+ describe Google::Auth::IAMCredentials do
37
+ IAMCredentials = Google::Auth::IAMCredentials
38
+ let(:test_selector) { 'the-test-selector' }
39
+ let(:test_token) { 'the-test-token' }
40
+ let(:test_creds) { IAMCredentials.new(test_selector, test_token) }
41
+
42
+ describe '#apply!' do
43
+ it 'should update the target hash with the iam values' do
44
+ md = { foo: 'bar' }
45
+ test_creds.apply!(md)
46
+ expect(md[IAMCredentials::SELECTOR_KEY]).to eq test_selector
47
+ expect(md[IAMCredentials::TOKEN_KEY]).to eq test_token
48
+ expect(md[:foo]).to eq 'bar'
49
+ end
50
+ end
51
+
52
+ describe 'updater_proc' do
53
+ it 'should provide a proc that updates a hash with the iam values' do
54
+ md = { foo: 'bar' }
55
+ the_proc = test_creds.updater_proc
56
+ got = the_proc.call(md)
57
+ expect(got[IAMCredentials::SELECTOR_KEY]).to eq test_selector
58
+ expect(got[IAMCredentials::TOKEN_KEY]).to eq test_token
59
+ expect(got[:foo]).to eq 'bar'
60
+ end
61
+ end
62
+
63
+ describe '#apply' do
64
+ it 'should not update the original hash with the iam values' do
65
+ md = { foo: 'bar' }
66
+ test_creds.apply(md)
67
+ expect(md[IAMCredentials::SELECTOR_KEY]).to be_nil
68
+ expect(md[IAMCredentials::TOKEN_KEY]).to be_nil
69
+ expect(md[:foo]).to eq 'bar'
70
+ end
71
+
72
+ it 'should return a with the iam values' do
73
+ md = { foo: 'bar' }
74
+ got = test_creds.apply(md)
75
+ expect(got[IAMCredentials::SELECTOR_KEY]).to eq test_selector
76
+ expect(got[IAMCredentials::TOKEN_KEY]).to eq test_token
77
+ expect(got[:foo]).to eq 'bar'
78
+ end
79
+ end
80
+ end
@@ -32,6 +32,7 @@ $LOAD_PATH.unshift(spec_dir)
32
32
  $LOAD_PATH.uniq!
33
33
 
34
34
  require 'apply_auth_examples'
35
+ require 'fakefs/safe'
35
36
  require 'fileutils'
36
37
  require 'googleauth/service_account'
37
38
  require 'jwt'
@@ -53,7 +54,7 @@ shared_examples 'jwt header auth' do
53
54
  expect(hdr).to_not be_nil
54
55
  expect(hdr.start_with?(auth_prefix)).to be true
55
56
  authorization = hdr[auth_prefix.length..-1]
56
- payload, _ = JWT.decode(authorization, @key.public_key)
57
+ payload, = JWT.decode(authorization, @key.public_key)
57
58
  expect(payload['aud']).to eq(test_uri)
58
59
  expect(payload['iss']).to eq(client_email)
59
60
  end
@@ -108,12 +109,22 @@ end
108
109
  describe Google::Auth::ServiceAccountCredentials do
109
110
  ServiceAccountCredentials = Google::Auth::ServiceAccountCredentials
110
111
  let(:client_email) { 'app@developer.gserviceaccount.com' }
112
+ let(:cred_json) do
113
+ {
114
+ private_key_id: 'a_private_key_id',
115
+ private_key: @key.to_pem,
116
+ client_email: client_email,
117
+ client_id: 'app.apps.googleusercontent.com',
118
+ type: 'service_account'
119
+ }
120
+ end
111
121
 
112
122
  before(:example) do
113
123
  @key = OpenSSL::PKey::RSA.new(2048)
114
124
  @client = ServiceAccountCredentials.new(
115
- StringIO.new(cred_json_text),
116
- 'https://www.googleapis.com/auth/userinfo.profile')
125
+ json_key_io: StringIO.new(cred_json_text),
126
+ scope: 'https://www.googleapis.com/auth/userinfo.profile'
127
+ )
117
128
  end
118
129
 
119
130
  def make_auth_stubs(opts = {})
@@ -131,13 +142,6 @@ describe Google::Auth::ServiceAccountCredentials do
131
142
  end
132
143
 
133
144
  def cred_json_text
134
- cred_json = {
135
- private_key_id: 'a_private_key_id',
136
- private_key: @key.to_pem,
137
- client_email: client_email,
138
- client_id: 'app.apps.googleusercontent.com',
139
- type: 'service_account'
140
- }
141
145
  MultiJson.dump(cred_json)
142
146
  end
143
147
 
@@ -154,13 +158,18 @@ describe Google::Auth::ServiceAccountCredentials do
154
158
  describe '#from_env' do
155
159
  before(:example) do
156
160
  @var_name = ENV_VAR
157
- @orig = ENV[@var_name]
161
+ @credential_vars = [
162
+ ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR]
163
+ @original_env_vals = {}
164
+ @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
165
+ ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
166
+
158
167
  @scope = 'https://www.googleapis.com/auth/userinfo.profile'
159
168
  @clz = ServiceAccountCredentials
160
169
  end
161
170
 
162
171
  after(:example) do
163
- ENV[@var_name] = @orig unless @orig.nil?
172
+ @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
164
173
  end
165
174
 
166
175
  it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
@@ -174,7 +183,7 @@ describe Google::Auth::ServiceAccountCredentials do
174
183
  Dir.mktmpdir do |dir|
175
184
  key_path = File.join(dir, 'does-not-exist')
176
185
  ENV[@var_name] = key_path
177
- expect { @clz.from_env(@scope) }.to raise_error
186
+ expect { @clz.from_env(@scope) }.to raise_error RuntimeError
178
187
  end
179
188
  end
180
189
 
@@ -187,6 +196,13 @@ describe Google::Auth::ServiceAccountCredentials do
187
196
  expect(@clz.from_env(@scope)).to_not be_nil
188
197
  end
189
198
  end
199
+
200
+ it 'succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are'\
201
+ ' valid' do
202
+ ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
203
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
204
+ expect(@clz.from_env(@scope)).to_not be_nil
205
+ end
190
206
  end
191
207
 
192
208
  describe '#from_well_known_path' do
@@ -216,6 +232,30 @@ describe Google::Auth::ServiceAccountCredentials do
216
232
  end
217
233
  end
218
234
  end
235
+
236
+ describe '#from_system_default_path' do
237
+ before(:example) do
238
+ @scope = 'https://www.googleapis.com/auth/userinfo.profile'
239
+ @path = File.join('/etc/google/auth/', CREDENTIALS_FILE_NAME)
240
+ @clz = ServiceAccountCredentials
241
+ end
242
+
243
+ it 'is nil if no file exists' do
244
+ FakeFS do
245
+ expect(ServiceAccountCredentials.from_system_default_path(@scope))
246
+ .to be_nil
247
+ end
248
+ end
249
+
250
+ it 'successfully loads the file when it is present' do
251
+ FakeFS do
252
+ FileUtils.mkdir_p(File.dirname(@path))
253
+ File.write(@path, cred_json_text)
254
+ expect(@clz.from_system_default_path(@scope)).to_not be_nil
255
+ File.delete(@path)
256
+ end
257
+ end
258
+ end
219
259
  end
220
260
 
221
261
  describe Google::Auth::ServiceAccountJwtHeaderCredentials do
@@ -224,20 +264,22 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
224
264
 
225
265
  let(:client_email) { 'app@developer.gserviceaccount.com' }
226
266
  let(:clz) { Google::Auth::ServiceAccountJwtHeaderCredentials }
227
-
228
- before(:example) do
229
- @key = OpenSSL::PKey::RSA.new(2048)
230
- @client = clz.new(StringIO.new(cred_json_text))
231
- end
232
-
233
- def cred_json_text
234
- cred_json = {
267
+ let(:cred_json) do
268
+ {
235
269
  private_key_id: 'a_private_key_id',
236
270
  private_key: @key.to_pem,
237
271
  client_email: client_email,
238
272
  client_id: 'app.apps.googleusercontent.com',
239
273
  type: 'service_account'
240
274
  }
275
+ end
276
+
277
+ before(:example) do
278
+ @key = OpenSSL::PKey::RSA.new(2048)
279
+ @client = clz.new(json_key_io: StringIO.new(cred_json_text))
280
+ end
281
+
282
+ def cred_json_text
241
283
  MultiJson.dump(cred_json)
242
284
  end
243
285
 
@@ -246,11 +288,15 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
246
288
  describe '#from_env' do
247
289
  before(:example) do
248
290
  @var_name = ENV_VAR
249
- @orig = ENV[@var_name]
291
+ @credential_vars = [
292
+ ENV_VAR, PRIVATE_KEY_VAR, CLIENT_EMAIL_VAR, ACCOUNT_TYPE_VAR]
293
+ @original_env_vals = {}
294
+ @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
295
+ ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
250
296
  end
251
297
 
252
298
  after(:example) do
253
- ENV[@var_name] = @orig unless @orig.nil?
299
+ @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
254
300
  end
255
301
 
256
302
  it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
@@ -264,7 +310,7 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
264
310
  Dir.mktmpdir do |dir|
265
311
  key_path = File.join(dir, 'does-not-exist')
266
312
  ENV[@var_name] = key_path
267
- expect { clz.from_env }.to raise_error
313
+ expect { clz.from_env }.to raise_error RuntimeError
268
314
  end
269
315
  end
270
316
 
@@ -277,6 +323,13 @@ describe Google::Auth::ServiceAccountJwtHeaderCredentials do
277
323
  expect(clz.from_env).to_not be_nil
278
324
  end
279
325
  end
326
+
327
+ it 'succeeds when GOOGLE_PRIVATE_KEY and GOOGLE_CLIENT_EMAIL env vars are'\
328
+ ' valid' do
329
+ ENV[PRIVATE_KEY_VAR] = cred_json[:private_key]
330
+ ENV[CLIENT_EMAIL_VAR] = cred_json[:client_email]
331
+ expect(clz.from_env(@scope)).to_not be_nil
332
+ end
280
333
  end
281
334
 
282
335
  describe '#from_well_known_path' do
@@ -32,6 +32,7 @@ $LOAD_PATH.unshift(spec_dir)
32
32
  $LOAD_PATH.uniq!
33
33
 
34
34
  require 'apply_auth_examples'
35
+ require 'fakefs/safe'
35
36
  require 'fileutils'
36
37
  require 'googleauth/user_refresh'
37
38
  require 'jwt'
@@ -40,15 +41,26 @@ require 'openssl'
40
41
  require 'spec_helper'
41
42
  require 'tmpdir'
42
43
 
44
+ include Google::Auth::CredentialsLoader
45
+
43
46
  describe Google::Auth::UserRefreshCredentials do
44
47
  UserRefreshCredentials = Google::Auth::UserRefreshCredentials
45
- CredentialsLoader = Google::Auth::CredentialsLoader
48
+
49
+ let(:cred_json) do
50
+ {
51
+ client_secret: 'privatekey',
52
+ client_id: 'client123',
53
+ refresh_token: 'refreshtoken',
54
+ type: 'authorized_user'
55
+ }
56
+ end
46
57
 
47
58
  before(:example) do
48
59
  @key = OpenSSL::PKey::RSA.new(2048)
49
60
  @client = UserRefreshCredentials.new(
50
- StringIO.new(cred_json_text),
51
- 'https://www.googleapis.com/auth/userinfo.profile')
61
+ json_key_io: StringIO.new(cred_json_text),
62
+ scope: 'https://www.googleapis.com/auth/userinfo.profile'
63
+ )
52
64
  end
53
65
 
54
66
  def make_auth_stubs(opts = {})
@@ -64,12 +76,6 @@ describe Google::Auth::UserRefreshCredentials do
64
76
  end
65
77
 
66
78
  def cred_json_text(missing = nil)
67
- cred_json = {
68
- client_secret: 'privatekey',
69
- client_id: 'client123',
70
- refresh_token: 'refreshtoken',
71
- type: 'authorized_user'
72
- }
73
79
  cred_json.delete(missing.to_sym) unless missing.nil?
74
80
  MultiJson.dump(cred_json)
75
81
  end
@@ -78,14 +84,18 @@ describe Google::Auth::UserRefreshCredentials do
78
84
 
79
85
  describe '#from_env' do
80
86
  before(:example) do
81
- @var_name = CredentialsLoader::ENV_VAR
82
- @orig = ENV[@var_name]
87
+ @var_name = ENV_VAR
88
+ @credential_vars = [
89
+ ENV_VAR, CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR,
90
+ ACCOUNT_TYPE_VAR]
91
+ @original_env_vals = {}
92
+ @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
83
93
  @scope = 'https://www.googleapis.com/auth/userinfo.profile'
84
94
  @clz = UserRefreshCredentials
85
95
  end
86
96
 
87
97
  after(:example) do
88
- ENV[@var_name] = @orig unless @orig.nil?
98
+ @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
89
99
  end
90
100
 
91
101
  it 'returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset' do
@@ -99,7 +109,7 @@ describe Google::Auth::UserRefreshCredentials do
99
109
  Dir.mktmpdir do |dir|
100
110
  key_path = File.join(dir, 'does-not-exist')
101
111
  ENV[@var_name] = key_path
102
- expect { @clz.from_env(@scope) }.to raise_error
112
+ expect { @clz.from_env(@scope) }.to raise_error RuntimeError
103
113
  end
104
114
  end
105
115
 
@@ -111,7 +121,7 @@ describe Google::Auth::UserRefreshCredentials do
111
121
  FileUtils.mkdir_p(File.dirname(key_path))
112
122
  File.write(key_path, cred_json_text(missing))
113
123
  ENV[@var_name] = key_path
114
- expect { @clz.from_env(@scope) }.to raise_error
124
+ expect { @clz.from_env(@scope) }.to raise_error RuntimeError
115
125
  end
116
126
  end
117
127
  end
@@ -125,13 +135,25 @@ describe Google::Auth::UserRefreshCredentials do
125
135
  expect(@clz.from_env(@scope)).to_not be_nil
126
136
  end
127
137
  end
138
+
139
+ it 'succeeds when GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and '\
140
+ 'GOOGLE_REFRESH_TOKEN env vars are valid' do
141
+ ENV[CLIENT_ID_VAR] = cred_json[:client_id]
142
+ ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
143
+ ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
144
+ ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
145
+ expect(@clz.from_env(@scope)).to_not be_nil
146
+ expect(subject.client_id).to eq(cred_json[:client_id])
147
+ expect(subject.client_secret).to eq(cred_json[:client_secret])
148
+ expect(subject.refresh_token).to eq(cred_json[:refresh_token])
149
+ end
128
150
  end
129
151
 
130
152
  describe '#from_well_known_path' do
131
153
  before(:example) do
132
154
  @home = ENV['HOME']
133
155
  @scope = 'https://www.googleapis.com/auth/userinfo.profile'
134
- @known_path = CredentialsLoader::WELL_KNOWN_PATH
156
+ @known_path = WELL_KNOWN_PATH
135
157
  @clz = UserRefreshCredentials
136
158
  end
137
159
 
@@ -152,7 +174,8 @@ describe Google::Auth::UserRefreshCredentials do
152
174
  FileUtils.mkdir_p(File.dirname(key_path))
153
175
  File.write(key_path, cred_json_text(missing))
154
176
  ENV['HOME'] = dir
155
- expect { @clz.from_env(@scope) }.to raise_error
177
+ expect { @clz.from_well_known_path(@scope) }
178
+ .to raise_error RuntimeError
156
179
  end
157
180
  end
158
181
  end
@@ -167,4 +190,41 @@ describe Google::Auth::UserRefreshCredentials do
167
190
  end
168
191
  end
169
192
  end
193
+
194
+ describe '#from_system_default_path' do
195
+ before(:example) do
196
+ @scope = 'https://www.googleapis.com/auth/userinfo.profile'
197
+ @path = File.join('/etc/google/auth/', CREDENTIALS_FILE_NAME)
198
+ @clz = UserRefreshCredentials
199
+ end
200
+
201
+ it 'is nil if no file exists' do
202
+ FakeFS do
203
+ expect(UserRefreshCredentials.from_system_default_path(@scope))
204
+ .to be_nil
205
+ end
206
+ end
207
+
208
+ it 'fails if the file is invalid' do
209
+ needed = %w(client_id client_secret refresh_token)
210
+ needed.each do |missing|
211
+ FakeFS do
212
+ FileUtils.mkdir_p(File.dirname(@path))
213
+ File.write(@path, cred_json_text(missing))
214
+ expect { @clz.from_system_default_path(@scope) }
215
+ .to raise_error RuntimeError
216
+ File.delete(@path)
217
+ end
218
+ end
219
+ end
220
+
221
+ it 'successfully loads the file when it is present' do
222
+ FakeFS do
223
+ FileUtils.mkdir_p(File.dirname(@path))
224
+ File.write(@path, cred_json_text)
225
+ expect(@clz.from_system_default_path(@scope)).to_not be_nil
226
+ File.delete(@path)
227
+ end
228
+ end
229
+ end
170
230
  end
metadata CHANGED
@@ -1,178 +1,192 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: googleauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Emiola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-23 00:00:00.000000000 Z
11
+ date: 2015-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ type: :runtime
14
15
  name: faraday
16
+ prerelease: false
15
17
  requirement: !ruby/object:Gem::Requirement
16
18
  requirements:
17
19
  - - "~>"
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0.9'
20
- type: :runtime
21
- prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.9'
27
27
  - !ruby/object:Gem::Dependency
28
+ type: :runtime
28
29
  name: logging
30
+ prerelease: false
29
31
  requirement: !ruby/object:Gem::Requirement
30
32
  requirements:
31
33
  - - "~>"
32
34
  - !ruby/object:Gem::Version
33
35
  version: '2.0'
34
- type: :runtime
35
- prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
+ type: :runtime
42
43
  name: jwt
44
+ prerelease: false
43
45
  requirement: !ruby/object:Gem::Requirement
44
46
  requirements:
45
47
  - - "~>"
46
48
  - !ruby/object:Gem::Version
47
49
  version: '1.4'
48
- type: :runtime
49
- prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.4'
55
55
  - !ruby/object:Gem::Dependency
56
+ type: :runtime
56
57
  name: memoist
58
+ prerelease: false
57
59
  requirement: !ruby/object:Gem::Requirement
58
60
  requirements:
59
61
  - - "~>"
60
62
  - !ruby/object:Gem::Version
61
63
  version: '0.12'
62
- type: :runtime
63
- prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.12'
69
69
  - !ruby/object:Gem::Dependency
70
+ type: :runtime
70
71
  name: multi_json
72
+ prerelease: false
71
73
  requirement: !ruby/object:Gem::Requirement
72
74
  requirements:
73
- - - '='
75
+ - - "~>"
74
76
  - !ruby/object:Gem::Version
75
77
  version: '1.11'
76
- type: :runtime
77
- prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '='
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.11'
83
83
  - !ruby/object:Gem::Dependency
84
+ type: :runtime
84
85
  name: signet
86
+ prerelease: false
85
87
  requirement: !ruby/object:Gem::Requirement
86
88
  requirements:
87
89
  - - "~>"
88
90
  - !ruby/object:Gem::Version
89
91
  version: '0.6'
90
- type: :runtime
91
- prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.6'
97
97
  - !ruby/object:Gem::Dependency
98
+ type: :development
98
99
  name: bundler
100
+ prerelease: false
99
101
  requirement: !ruby/object:Gem::Requirement
100
102
  requirements:
101
103
  - - "~>"
102
104
  - !ruby/object:Gem::Version
103
105
  version: '1.9'
104
- type: :development
105
- prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.9'
111
111
  - !ruby/object:Gem::Dependency
112
+ type: :development
112
113
  name: simplecov
114
+ prerelease: false
113
115
  requirement: !ruby/object:Gem::Requirement
114
116
  requirements:
115
117
  - - "~>"
116
118
  - !ruby/object:Gem::Version
117
119
  version: '0.9'
118
- type: :development
119
- prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.9'
125
125
  - !ruby/object:Gem::Dependency
126
+ type: :development
126
127
  name: coveralls
128
+ prerelease: false
127
129
  requirement: !ruby/object:Gem::Requirement
128
130
  requirements:
129
131
  - - "~>"
130
132
  - !ruby/object:Gem::Version
131
133
  version: '0.7'
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.7'
139
+ - !ruby/object:Gem::Dependency
132
140
  type: :development
141
+ name: fakefs
133
142
  prerelease: false
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: '0.6'
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '0.7'
152
+ version: '0.6'
139
153
  - !ruby/object:Gem::Dependency
154
+ type: :development
140
155
  name: rake
156
+ prerelease: false
141
157
  requirement: !ruby/object:Gem::Requirement
142
158
  requirements:
143
159
  - - "~>"
144
160
  - !ruby/object:Gem::Version
145
161
  version: '10.0'
146
- type: :development
147
- prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
166
  version: '10.0'
153
167
  - !ruby/object:Gem::Dependency
168
+ type: :development
154
169
  name: rubocop
170
+ prerelease: false
155
171
  requirement: !ruby/object:Gem::Requirement
156
172
  requirements:
157
173
  - - "~>"
158
174
  - !ruby/object:Gem::Version
159
175
  version: '0.30'
160
- type: :development
161
- prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
178
  - - "~>"
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0.30'
167
181
  - !ruby/object:Gem::Dependency
182
+ type: :development
168
183
  name: rspec
184
+ prerelease: false
169
185
  requirement: !ruby/object:Gem::Requirement
170
186
  requirements:
171
187
  - - "~>"
172
188
  - !ruby/object:Gem::Version
173
189
  version: '3.0'
174
- type: :development
175
- prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
192
  - - "~>"
@@ -202,6 +216,7 @@ files:
202
216
  - lib/googleauth.rb
203
217
  - lib/googleauth/compute_engine.rb
204
218
  - lib/googleauth/credentials_loader.rb
219
+ - lib/googleauth/iam.rb
205
220
  - lib/googleauth/service_account.rb
206
221
  - lib/googleauth/signet.rb
207
222
  - lib/googleauth/user_refresh.rb
@@ -209,6 +224,7 @@ files:
209
224
  - spec/googleauth/apply_auth_examples.rb
210
225
  - spec/googleauth/compute_engine_spec.rb
211
226
  - spec/googleauth/get_application_default_spec.rb
227
+ - spec/googleauth/iam_spec.rb
212
228
  - spec/googleauth/service_account_spec.rb
213
229
  - spec/googleauth/signet_spec.rb
214
230
  - spec/googleauth/user_refresh_spec.rb
@@ -233,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
233
249
  version: '0'
234
250
  requirements: []
235
251
  rubyforge_project:
236
- rubygems_version: 2.4.3
252
+ rubygems_version: 2.4.8
237
253
  signing_key:
238
254
  specification_version: 4
239
255
  summary: Google Auth Library for Ruby
@@ -241,6 +257,7 @@ test_files:
241
257
  - spec/googleauth/apply_auth_examples.rb
242
258
  - spec/googleauth/compute_engine_spec.rb
243
259
  - spec/googleauth/get_application_default_spec.rb
260
+ - spec/googleauth/iam_spec.rb
244
261
  - spec/googleauth/service_account_spec.rb
245
262
  - spec/googleauth/signet_spec.rb
246
263
  - spec/googleauth/user_refresh_spec.rb