googleauth 0.5.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +7 -0
  3. data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +5 -4
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  6. data/.github/ISSUE_TEMPLATE/support_request.md +7 -0
  7. data/.kokoro/build.bat +16 -0
  8. data/.kokoro/build.sh +4 -0
  9. data/.kokoro/continuous/common.cfg +24 -0
  10. data/.kokoro/continuous/linux.cfg +25 -0
  11. data/.kokoro/continuous/osx.cfg +8 -0
  12. data/.kokoro/continuous/post.cfg +30 -0
  13. data/.kokoro/continuous/windows.cfg +29 -0
  14. data/.kokoro/osx.sh +4 -0
  15. data/.kokoro/presubmit/common.cfg +24 -0
  16. data/.kokoro/presubmit/linux.cfg +24 -0
  17. data/.kokoro/presubmit/osx.cfg +8 -0
  18. data/.kokoro/presubmit/windows.cfg +29 -0
  19. data/.kokoro/release.cfg +94 -0
  20. data/.kokoro/trampoline.bat +10 -0
  21. data/.kokoro/trampoline.sh +4 -0
  22. data/.repo-metadata.json +5 -0
  23. data/.rubocop.yml +19 -1
  24. data/CHANGELOG.md +112 -19
  25. data/CODE_OF_CONDUCT.md +43 -0
  26. data/Gemfile +19 -13
  27. data/{COPYING → LICENSE} +0 -0
  28. data/README.md +58 -18
  29. data/Rakefile +126 -9
  30. data/googleauth.gemspec +28 -25
  31. data/integration/helper.rb +31 -0
  32. data/integration/id_tokens/key_source_test.rb +74 -0
  33. data/lib/googleauth.rb +7 -96
  34. data/lib/googleauth/application_default.rb +81 -0
  35. data/lib/googleauth/client_id.rb +21 -19
  36. data/lib/googleauth/compute_engine.rb +70 -43
  37. data/lib/googleauth/credentials.rb +442 -0
  38. data/lib/googleauth/credentials_loader.rb +117 -43
  39. data/lib/googleauth/default_credentials.rb +93 -0
  40. data/lib/googleauth/iam.rb +11 -11
  41. data/lib/googleauth/id_tokens.rb +233 -0
  42. data/lib/googleauth/id_tokens/errors.rb +71 -0
  43. data/lib/googleauth/id_tokens/key_sources.rb +394 -0
  44. data/lib/googleauth/id_tokens/verifier.rb +144 -0
  45. data/lib/googleauth/json_key_reader.rb +50 -0
  46. data/lib/googleauth/scope_util.rb +12 -12
  47. data/lib/googleauth/service_account.rb +74 -63
  48. data/lib/googleauth/signet.rb +55 -13
  49. data/lib/googleauth/stores/file_token_store.rb +8 -8
  50. data/lib/googleauth/stores/redis_token_store.rb +22 -22
  51. data/lib/googleauth/token_store.rb +6 -6
  52. data/lib/googleauth/user_authorizer.rb +80 -68
  53. data/lib/googleauth/user_refresh.rb +44 -35
  54. data/lib/googleauth/version.rb +1 -1
  55. data/lib/googleauth/web_user_authorizer.rb +77 -68
  56. data/rakelib/devsite_builder.rb +45 -0
  57. data/rakelib/link_checker.rb +64 -0
  58. data/rakelib/repo_metadata.rb +59 -0
  59. data/spec/googleauth/apply_auth_examples.rb +74 -50
  60. data/spec/googleauth/client_id_spec.rb +75 -55
  61. data/spec/googleauth/compute_engine_spec.rb +98 -46
  62. data/spec/googleauth/credentials_spec.rb +478 -0
  63. data/spec/googleauth/get_application_default_spec.rb +149 -111
  64. data/spec/googleauth/iam_spec.rb +25 -25
  65. data/spec/googleauth/scope_util_spec.rb +26 -24
  66. data/spec/googleauth/service_account_spec.rb +269 -144
  67. data/spec/googleauth/signet_spec.rb +101 -30
  68. data/spec/googleauth/stores/file_token_store_spec.rb +12 -13
  69. data/spec/googleauth/stores/redis_token_store_spec.rb +11 -11
  70. data/spec/googleauth/stores/store_examples.rb +16 -16
  71. data/spec/googleauth/user_authorizer_spec.rb +153 -124
  72. data/spec/googleauth/user_refresh_spec.rb +186 -121
  73. data/spec/googleauth/web_user_authorizer_spec.rb +82 -69
  74. data/spec/spec_helper.rb +21 -19
  75. data/test/helper.rb +33 -0
  76. data/test/id_tokens/key_sources_test.rb +240 -0
  77. data/test/id_tokens/verifier_test.rb +269 -0
  78. metadata +87 -34
  79. data/.rubocop_todo.yml +0 -32
  80. data/.travis.yml +0 -37
@@ -27,8 +27,8 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- require 'redis'
31
- require 'googleauth/token_store'
30
+ require "redis"
31
+ require "googleauth/token_store"
32
32
 
33
33
  module Google
34
34
  module Auth
@@ -37,7 +37,7 @@ module Google
37
37
  # are stored as JSON using the supplied key, prefixed with
38
38
  # `g-user-token:`
39
39
  class RedisTokenStore < Google::Auth::TokenStore
40
- DEFAULT_KEY_PREFIX = 'g-user-token:'
40
+ DEFAULT_KEY_PREFIX = "g-user-token:".freeze
41
41
 
42
42
  # Create a new store with the supplied redis client.
43
43
  #
@@ -48,34 +48,34 @@ module Google
48
48
  # @note If no redis instance is provided, a new one is created and
49
49
  # the options passed through. You may include any other keys accepted
50
50
  # by `Redis.new`
51
- def initialize(options = {})
52
- redis = options.delete(:redis)
53
- prefix = options.delete(:prefix)
54
- case redis
55
- when Redis
56
- @redis = redis
57
- else
58
- @redis = Redis.new(options)
59
- end
51
+ def initialize options = {}
52
+ redis = options.delete :redis
53
+ prefix = options.delete :prefix
54
+ @redis = case redis
55
+ when Redis
56
+ redis
57
+ else
58
+ Redis.new options
59
+ end
60
60
  @prefix = prefix || DEFAULT_KEY_PREFIX
61
61
  end
62
62
 
63
63
  # (see Google::Auth::Stores::TokenStore#load)
64
- def load(id)
65
- key = key_for(id)
66
- @redis.get(key)
64
+ def load id
65
+ key = key_for id
66
+ @redis.get key
67
67
  end
68
68
 
69
69
  # (see Google::Auth::Stores::TokenStore#store)
70
- def store(id, token)
71
- key = key_for(id)
72
- @redis.set(key, token)
70
+ def store id, token
71
+ key = key_for id
72
+ @redis.set key, token
73
73
  end
74
74
 
75
75
  # (see Google::Auth::Stores::TokenStore#delete)
76
- def delete(id)
77
- key = key_for(id)
78
- @redis.del(key)
76
+ def delete id
77
+ key = key_for id
78
+ @redis.del key
79
79
  end
80
80
 
81
81
  private
@@ -86,7 +86,7 @@ module Google
86
86
  # ID of the token
87
87
  # @return [String]
88
88
  # Redis key
89
- def key_for(id)
89
+ def key_for id
90
90
  @prefix + id
91
91
  end
92
92
  end
@@ -43,8 +43,8 @@ module Google
43
43
  # ID of token data to load.
44
44
  # @return [String]
45
45
  # The loaded token data.
46
- def load(_id)
47
- fail 'Not implemented'
46
+ def load _id
47
+ raise "Not implemented"
48
48
  end
49
49
 
50
50
  # Put the token data into storage for the given ID.
@@ -53,16 +53,16 @@ module Google
53
53
  # ID of token data to store.
54
54
  # @param [String] token
55
55
  # The token data to store.
56
- def store(_id, _token)
57
- fail 'Not implemented'
56
+ def store _id, _token
57
+ raise "Not implemented"
58
58
  end
59
59
 
60
60
  # Remove the token data from storage for the given ID.
61
61
  #
62
62
  # @param [String] id
63
63
  # ID of the token data to delete
64
- def delete(_id)
65
- fail 'Not implemented'
64
+ def delete _id
65
+ raise "Not implemented"
66
66
  end
67
67
  end
68
68
  end
@@ -27,10 +27,10 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- require 'uri'
31
- require 'multi_json'
32
- require 'googleauth/signet'
33
- require 'googleauth/user_refresh'
30
+ require "uri"
31
+ require "multi_json"
32
+ require "googleauth/signet"
33
+ require "googleauth/user_refresh"
34
34
 
35
35
  module Google
36
36
  module Auth
@@ -53,13 +53,13 @@ module Google
53
53
  # ...
54
54
  class UserAuthorizer
55
55
  MISMATCHED_CLIENT_ID_ERROR =
56
- 'Token client ID of %s does not match configured client id %s'
57
- NIL_CLIENT_ID_ERROR = 'Client id can not be nil.'
58
- NIL_SCOPE_ERROR = 'Scope can not be nil.'
59
- NIL_USER_ID_ERROR = 'User ID can not be nil.'
60
- NIL_TOKEN_STORE_ERROR = 'Can not call method if token store is nil'
56
+ "Token client ID of %s does not match configured client id %s".freeze
57
+ NIL_CLIENT_ID_ERROR = "Client id can not be nil.".freeze
58
+ NIL_SCOPE_ERROR = "Scope can not be nil.".freeze
59
+ NIL_USER_ID_ERROR = "User ID can not be nil.".freeze
60
+ NIL_TOKEN_STORE_ERROR = "Can not call method if token store is nil".freeze
61
61
  MISSING_ABSOLUTE_URL_ERROR =
62
- 'Absolute base url required for relative callback url "%s"'
62
+ 'Absolute base url required for relative callback url "%s"'.freeze
63
63
 
64
64
  # Initialize the authorizer
65
65
  #
@@ -72,14 +72,14 @@ module Google
72
72
  # @param [String] callback_uri
73
73
  # URL (either absolute or relative) of the auth callback.
74
74
  # Defaults to '/oauth2callback'
75
- def initialize(client_id, scope, token_store, callback_uri = nil)
76
- fail NIL_CLIENT_ID_ERROR if client_id.nil?
77
- fail NIL_SCOPE_ERROR if scope.nil?
75
+ def initialize client_id, scope, token_store, callback_uri = nil
76
+ raise NIL_CLIENT_ID_ERROR if client_id.nil?
77
+ raise NIL_SCOPE_ERROR if scope.nil?
78
78
 
79
79
  @client_id = client_id
80
80
  @scope = Array(scope)
81
81
  @token_store = token_store
82
- @callback_uri = callback_uri || '/oauth2callback'
82
+ @callback_uri = callback_uri || "/oauth2callback"
83
83
  end
84
84
 
85
85
  # Build the URL for requesting authorization.
@@ -97,19 +97,20 @@ module Google
97
97
  # nil.
98
98
  # @return [String]
99
99
  # Authorization url
100
- def get_authorization_url(options = {})
100
+ def get_authorization_url options = {}
101
101
  scope = options[:scope] || @scope
102
102
  credentials = UserRefreshCredentials.new(
103
- client_id: @client_id.id,
103
+ client_id: @client_id.id,
104
104
  client_secret: @client_id.secret,
105
- scope: scope)
106
- redirect_uri = redirect_uri_for(options[:base_url])
107
- url = credentials.authorization_uri(access_type: 'offline',
108
- redirect_uri: redirect_uri,
109
- approval_prompt: 'force',
110
- state: options[:state],
105
+ scope: scope
106
+ )
107
+ redirect_uri = redirect_uri_for options[:base_url]
108
+ url = credentials.authorization_uri(access_type: "offline",
109
+ redirect_uri: redirect_uri,
110
+ approval_prompt: "force",
111
+ state: options[:state],
111
112
  include_granted_scopes: true,
112
- login_hint: options[:login_hint])
113
+ login_hint: options[:login_hint])
113
114
  url.to_s
114
115
  end
115
116
 
@@ -122,31 +123,26 @@ module Google
122
123
  # the requested scopes
123
124
  # @return [Google::Auth::UserRefreshCredentials]
124
125
  # Stored credentials, nil if none present
125
- def get_credentials(user_id, scope = nil)
126
- fail NIL_USER_ID_ERROR if user_id.nil?
127
- fail NIL_TOKEN_STORE_ERROR if @token_store.nil?
128
-
129
- scope ||= @scope
130
- saved_token = @token_store.load(user_id)
126
+ def get_credentials user_id, scope = nil
127
+ saved_token = stored_token user_id
131
128
  return nil if saved_token.nil?
132
- data = MultiJson.load(saved_token)
129
+ data = MultiJson.load saved_token
133
130
 
134
- if data.fetch('client_id', @client_id.id) != @client_id.id
135
- fail sprintf(MISMATCHED_CLIENT_ID_ERROR,
136
- data['client_id'], @client_id.id)
131
+ if data.fetch("client_id", @client_id.id) != @client_id.id
132
+ raise format(MISMATCHED_CLIENT_ID_ERROR,
133
+ data["client_id"], @client_id.id)
137
134
  end
138
135
 
139
136
  credentials = UserRefreshCredentials.new(
140
- client_id: @client_id.id,
137
+ client_id: @client_id.id,
141
138
  client_secret: @client_id.secret,
142
- scope: data['scope'] || @scope,
143
- access_token: data['access_token'],
144
- refresh_token: data['refresh_token'],
145
- expires_at: data.fetch('expiration_time_millis', 0) / 1000)
146
- if credentials.includes_scope?(scope)
147
- monitor_credentials(user_id, credentials)
148
- return credentials
149
- end
139
+ scope: data["scope"] || @scope,
140
+ access_token: data["access_token"],
141
+ refresh_token: data["refresh_token"],
142
+ expires_at: data.fetch("expiration_time_millis", 0) / 1000
143
+ )
144
+ scope ||= @scope
145
+ return monitor_credentials user_id, credentials if credentials.includes_scope? scope
150
146
  nil
151
147
  end
152
148
 
@@ -165,19 +161,20 @@ module Google
165
161
  # callback uri is a relative.
166
162
  # @return [Google::Auth::UserRefreshCredentials]
167
163
  # Credentials if exchange is successful
168
- def get_credentials_from_code(options = {})
164
+ def get_credentials_from_code options = {}
169
165
  user_id = options[:user_id]
170
166
  code = options[:code]
171
167
  scope = options[:scope] || @scope
172
168
  base_url = options[:base_url]
173
169
  credentials = UserRefreshCredentials.new(
174
- client_id: @client_id.id,
170
+ client_id: @client_id.id,
175
171
  client_secret: @client_id.secret,
176
- redirect_uri: redirect_uri_for(base_url),
177
- scope: scope)
172
+ redirect_uri: redirect_uri_for(base_url),
173
+ scope: scope
174
+ )
178
175
  credentials.code = code
179
176
  credentials.fetch_access_token!({})
180
- monitor_credentials(user_id, credentials)
177
+ monitor_credentials user_id, credentials
181
178
  end
182
179
 
183
180
  # Exchanges an authorization code returned in the oauth callback.
@@ -197,10 +194,9 @@ module Google
197
194
  # callback uri is a relative.
198
195
  # @return [Google::Auth::UserRefreshCredentials]
199
196
  # Credentials if exchange is successful
200
- def get_and_store_credentials_from_code(options = {})
201
- credentials = get_credentials_from_code(options)
202
- monitor_credentials(options[:user_id], credentials)
203
- store_credentials(options[:user_id], credentials)
197
+ def get_and_store_credentials_from_code options = {}
198
+ credentials = get_credentials_from_code options
199
+ store_credentials options[:user_id], credentials
204
200
  end
205
201
 
206
202
  # Revokes a user's credentials. This both revokes the actual
@@ -208,11 +204,11 @@ module Google
208
204
  #
209
205
  # @param [String] user_id
210
206
  # Unique ID of the user for loading/storing credentials.
211
- def revoke_authorization(user_id)
212
- credentials = get_credentials(user_id)
207
+ def revoke_authorization user_id
208
+ credentials = get_credentials user_id
213
209
  if credentials
214
210
  begin
215
- @token_store.delete(user_id)
211
+ @token_store.delete user_id
216
212
  ensure
217
213
  credentials.revoke!
218
214
  end
@@ -228,19 +224,32 @@ module Google
228
224
  # Unique ID of the user for loading/storing credentials.
229
225
  # @param [Google::Auth::UserRefreshCredentials] credentials
230
226
  # Credentials to store.
231
- def store_credentials(user_id, credentials)
227
+ def store_credentials user_id, credentials
232
228
  json = MultiJson.dump(
233
- client_id: credentials.client_id,
234
- access_token: credentials.access_token,
235
- refresh_token: credentials.refresh_token,
236
- scope: credentials.scope,
237
- expiration_time_millis: (credentials.expires_at.to_i) * 1000)
238
- @token_store.store(user_id, json)
229
+ client_id: credentials.client_id,
230
+ access_token: credentials.access_token,
231
+ refresh_token: credentials.refresh_token,
232
+ scope: credentials.scope,
233
+ expiration_time_millis: credentials.expires_at.to_i * 1000
234
+ )
235
+ @token_store.store user_id, json
239
236
  credentials
240
237
  end
241
238
 
242
239
  private
243
240
 
241
+ # @private Fetch stored token with given user_id
242
+ #
243
+ # @param [String] user_id
244
+ # Unique ID of the user for loading/storing credentials.
245
+ # @return [String] The saved token from @token_store
246
+ def stored_token user_id
247
+ raise NIL_USER_ID_ERROR if user_id.nil?
248
+ raise NIL_TOKEN_STORE_ERROR if @token_store.nil?
249
+
250
+ @token_store.load user_id
251
+ end
252
+
244
253
  # Begin watching a credential for refreshes so the access token can be
245
254
  # saved.
246
255
  #
@@ -248,9 +257,9 @@ module Google
248
257
  # Unique ID of the user for loading/storing credentials.
249
258
  # @param [Google::Auth::UserRefreshCredentials] credentials
250
259
  # Credentials to store.
251
- def monitor_credentials(user_id, credentials)
260
+ def monitor_credentials user_id, credentials
252
261
  credentials.on_refresh do |cred|
253
- store_credentials(user_id, cred)
262
+ store_credentials user_id, cred
254
263
  end
255
264
  credentials
256
265
  end
@@ -261,13 +270,16 @@ module Google
261
270
  # Absolute URL to resolve the callback against if necessary.
262
271
  # @return [String]
263
272
  # Redirect URI
264
- def redirect_uri_for(base_url)
265
- return @callback_uri unless URI(@callback_uri).scheme.nil?
266
- fail sprintf(
267
- MISSING_ABSOLUTE_URL_ERROR,
268
- @callback_uri) if base_url.nil? || URI(base_url).scheme.nil?
273
+ def redirect_uri_for base_url
274
+ return @callback_uri if uri_is_postmessage?(@callback_uri) || !URI(@callback_uri).scheme.nil?
275
+ raise format(MISSING_ABSOLUTE_URL_ERROR, @callback_uri) if base_url.nil? || URI(base_url).scheme.nil?
269
276
  URI.join(base_url, @callback_uri).to_s
270
277
  end
278
+
279
+ # Check if URI is Google's postmessage flow (not a valid redirect_uri by spec, but allowed)
280
+ def uri_is_postmessage? uri
281
+ uri.to_s.casecmp("postmessage").zero?
282
+ end
271
283
  end
272
284
  end
273
285
  end
@@ -27,10 +27,10 @@
27
27
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
 
30
- require 'googleauth/signet'
31
- require 'googleauth/credentials_loader'
32
- require 'googleauth/scope_util'
33
- require 'multi_json'
30
+ require "googleauth/signet"
31
+ require "googleauth/credentials_loader"
32
+ require "googleauth/scope_util"
33
+ require "multi_json"
34
34
 
35
35
  module Google
36
36
  # Module Auth provides classes that provide Google-specific authorization
@@ -44,63 +44,72 @@ module Google
44
44
  # 'gcloud auth login' saves a file with these contents in well known
45
45
  # location
46
46
  #
47
- # cf [Application Default Credentials](http://goo.gl/mkAHpZ)
47
+ # cf [Application Default Credentials](https://cloud.google.com/docs/authentication/production)
48
48
  class UserRefreshCredentials < Signet::OAuth2::Client
49
- TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
50
- AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/auth'
51
- REVOKE_TOKEN_URI = 'https://accounts.google.com/o/oauth2/revoke'
49
+ TOKEN_CRED_URI = "https://oauth2.googleapis.com/token".freeze
50
+ AUTHORIZATION_URI = "https://accounts.google.com/o/oauth2/auth".freeze
51
+ REVOKE_TOKEN_URI = "https://oauth2.googleapis.com/revoke".freeze
52
52
  extend CredentialsLoader
53
+ attr_reader :project_id
53
54
 
54
55
  # Create a UserRefreshCredentials.
55
56
  #
56
57
  # @param json_key_io [IO] an IO from which the JSON key can be read
57
58
  # @param scope [string|array|nil] the scope(s) to access
58
- def self.make_creds(options = {})
59
- json_key_io, scope = options.values_at(:json_key_io, :scope)
60
- user_creds = read_json_key(json_key_io) if json_key_io
59
+ def self.make_creds options = {}
60
+ json_key_io, scope = options.values_at :json_key_io, :scope
61
+ user_creds = read_json_key json_key_io if json_key_io
61
62
  user_creds ||= {
62
- 'client_id' => ENV[CredentialsLoader::CLIENT_ID_VAR],
63
- 'client_secret' => ENV[CredentialsLoader::CLIENT_SECRET_VAR],
64
- 'refresh_token' => ENV[CredentialsLoader::REFRESH_TOKEN_VAR]
63
+ "client_id" => ENV[CredentialsLoader::CLIENT_ID_VAR],
64
+ "client_secret" => ENV[CredentialsLoader::CLIENT_SECRET_VAR],
65
+ "refresh_token" => ENV[CredentialsLoader::REFRESH_TOKEN_VAR],
66
+ "project_id" => ENV[CredentialsLoader::PROJECT_ID_VAR]
65
67
  }
66
68
 
67
69
  new(token_credential_uri: TOKEN_CRED_URI,
68
- client_id: user_creds['client_id'],
69
- client_secret: user_creds['client_secret'],
70
- refresh_token: user_creds['refresh_token'],
71
- scope: scope)
70
+ client_id: user_creds["client_id"],
71
+ client_secret: user_creds["client_secret"],
72
+ refresh_token: user_creds["refresh_token"],
73
+ project_id: user_creds["project_id"],
74
+ scope: scope)
75
+ .configure_connection(options)
72
76
  end
73
77
 
74
78
  # Reads the client_id, client_secret and refresh_token fields from the
75
79
  # JSON key.
76
- def self.read_json_key(json_key_io)
77
- json_key = MultiJson.load(json_key_io.read)
78
- wanted = %w(client_id client_secret refresh_token)
80
+ def self.read_json_key json_key_io
81
+ json_key = MultiJson.load json_key_io.read
82
+ wanted = ["client_id", "client_secret", "refresh_token"]
79
83
  wanted.each do |key|
80
- fail "the json is missing the #{key} field" unless json_key.key?(key)
84
+ raise "the json is missing the #{key} field" unless json_key.key? key
81
85
  end
82
86
  json_key
83
87
  end
84
88
 
85
- def initialize(options = {})
89
+ def initialize options = {}
86
90
  options ||= {}
87
91
  options[:token_credential_uri] ||= TOKEN_CRED_URI
88
92
  options[:authorization_uri] ||= AUTHORIZATION_URI
89
- super(options)
93
+ @project_id = options[:project_id]
94
+ @project_id ||= CredentialsLoader.load_gcloud_project_id
95
+ super options
90
96
  end
91
97
 
92
98
  # Revokes the credential
93
- def revoke!(options = {})
99
+ def revoke! options = {}
94
100
  c = options[:connection] || Faraday.default_connection
95
- resp = c.get(REVOKE_TOKEN_URI, token: refresh_token || access_token)
96
- case resp.status
97
- when 200
98
- self.access_token = nil
99
- self.refresh_token = nil
100
- self.expires_at = 0
101
- else
102
- fail(Signet::AuthorizationError,
103
- "Unexpected error code #{resp.status}")
101
+
102
+ retry_with_error do
103
+ resp = c.post(REVOKE_TOKEN_URI, token: refresh_token || access_token)
104
+ case resp.status
105
+ when 200
106
+ self.access_token = nil
107
+ self.refresh_token = nil
108
+ self.expires_at = 0
109
+ else
110
+ raise(Signet::AuthorizationError,
111
+ "Unexpected error code #{resp.status}")
112
+ end
104
113
  end
105
114
  end
106
115
 
@@ -110,7 +119,7 @@ module Google
110
119
  # Scope to verify
111
120
  # @return [Boolean]
112
121
  # True if scope is granted
113
- def includes_scope?(required_scope)
122
+ def includes_scope? required_scope
114
123
  missing_scope = Google::Auth::ScopeUtil.normalize(required_scope) -
115
124
  Google::Auth::ScopeUtil.normalize(scope)
116
125
  missing_scope.empty?