googleauth 0.17.0 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.md +6 -0
  4. data/lib/googleauth/version.rb +1 -1
  5. metadata +14 -88
  6. data/.github/CODEOWNERS +0 -7
  7. data/.github/CONTRIBUTING.md +0 -74
  8. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -36
  9. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -21
  10. data/.github/ISSUE_TEMPLATE/support_request.md +0 -7
  11. data/.github/renovate.json +0 -6
  12. data/.github/sync-repo-settings.yaml +0 -18
  13. data/.github/workflows/ci.yml +0 -55
  14. data/.github/workflows/release-please.yml +0 -39
  15. data/.gitignore +0 -39
  16. data/.kokoro/populate-secrets.sh +0 -76
  17. data/.kokoro/release.cfg +0 -52
  18. data/.kokoro/release.sh +0 -18
  19. data/.kokoro/trampoline_v2.sh +0 -489
  20. data/.repo-metadata.json +0 -5
  21. data/.rspec +0 -2
  22. data/.rubocop.yml +0 -17
  23. data/.toys/.toys.rb +0 -45
  24. data/.toys/ci.rb +0 -43
  25. data/.toys/kokoro/.toys.rb +0 -66
  26. data/.toys/kokoro/publish-docs.rb +0 -67
  27. data/.toys/kokoro/publish-gem.rb +0 -53
  28. data/.toys/linkinator.rb +0 -43
  29. data/.trampolinerc +0 -48
  30. data/Gemfile +0 -25
  31. data/googleauth.gemspec +0 -39
  32. data/integration/helper.rb +0 -31
  33. data/integration/id_tokens/key_source_test.rb +0 -74
  34. data/spec/googleauth/apply_auth_examples.rb +0 -171
  35. data/spec/googleauth/client_id_spec.rb +0 -160
  36. data/spec/googleauth/compute_engine_spec.rb +0 -178
  37. data/spec/googleauth/credentials_spec.rb +0 -600
  38. data/spec/googleauth/get_application_default_spec.rb +0 -286
  39. data/spec/googleauth/iam_spec.rb +0 -80
  40. data/spec/googleauth/scope_util_spec.rb +0 -77
  41. data/spec/googleauth/service_account_spec.rb +0 -511
  42. data/spec/googleauth/signet_spec.rb +0 -142
  43. data/spec/googleauth/stores/file_token_store_spec.rb +0 -57
  44. data/spec/googleauth/stores/redis_token_store_spec.rb +0 -50
  45. data/spec/googleauth/stores/store_examples.rb +0 -58
  46. data/spec/googleauth/user_authorizer_spec.rb +0 -343
  47. data/spec/googleauth/user_refresh_spec.rb +0 -359
  48. data/spec/googleauth/web_user_authorizer_spec.rb +0 -172
  49. data/spec/spec_helper.rb +0 -92
  50. data/test/helper.rb +0 -33
  51. data/test/id_tokens/key_sources_test.rb +0 -240
  52. data/test/id_tokens/verifier_test.rb +0 -269
@@ -1,359 +0,0 @@
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 "apply_auth_examples"
35
- require "fakefs/safe"
36
- require "fileutils"
37
- require "googleauth/user_refresh"
38
- require "jwt"
39
- require "multi_json"
40
- require "openssl"
41
- require "spec_helper"
42
- require "tmpdir"
43
- require "os"
44
-
45
- include Google::Auth::CredentialsLoader
46
-
47
- describe Google::Auth::UserRefreshCredentials do
48
- UserRefreshCredentials = Google::Auth::UserRefreshCredentials
49
-
50
- let :cred_json do
51
- {
52
- client_secret: "privatekey",
53
- client_id: "client123",
54
- refresh_token: "refreshtoken",
55
- type: "authorized_user"
56
- }
57
- end
58
-
59
- before :example do
60
- @key = OpenSSL::PKey::RSA.new 2048
61
- @client = UserRefreshCredentials.make_creds(
62
- json_key_io: StringIO.new(cred_json_text),
63
- scope: "https://www.googleapis.com/auth/userinfo.profile"
64
- )
65
- end
66
-
67
- def make_auth_stubs opts
68
- access_token = opts[:access_token] || ""
69
- body = MultiJson.dump("access_token" => access_token,
70
- "token_type" => "Bearer",
71
- "expires_in" => 3600)
72
- stub_request(:post, "https://oauth2.googleapis.com/token")
73
- .with(body: hash_including("grant_type" => "refresh_token"))
74
- .to_return(body: body,
75
- status: 200,
76
- headers: { "Content-Type" => "application/json" })
77
- end
78
-
79
- def cred_json_text missing = nil
80
- cred_json.delete missing.to_sym unless missing.nil?
81
- MultiJson.dump cred_json
82
- end
83
-
84
- it_behaves_like "apply/apply! are OK"
85
-
86
- describe "#from_env" do
87
- before :example do
88
- @var_name = ENV_VAR
89
- @credential_vars = [
90
- ENV_VAR, CLIENT_ID_VAR, CLIENT_SECRET_VAR, REFRESH_TOKEN_VAR,
91
- ACCOUNT_TYPE_VAR
92
- ]
93
- @original_env_vals = {}
94
- @credential_vars.each { |var| @original_env_vals[var] = ENV[var] }
95
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
96
- @clz = UserRefreshCredentials
97
- @project_id = "a_project_id"
98
- end
99
-
100
- after :example do
101
- @credential_vars.each { |var| ENV[var] = @original_env_vals[var] }
102
- end
103
-
104
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is unset" do
105
- ENV.delete @var_name unless ENV[@var_name].nil?
106
- expect(UserRefreshCredentials.from_env(@scope)).to be_nil
107
- end
108
-
109
- it "returns nil if the GOOGLE_APPLICATION_CREDENTIALS is empty" do
110
- ENV[@var_name] = ""
111
- expect(UserRefreshCredentials.from_env(@scope)).to be_nil
112
- end
113
-
114
- it "fails if the GOOGLE_APPLICATION_CREDENTIALS path does not exist" do
115
- ENV.delete @var_name unless ENV[@var_name].nil?
116
- expect(UserRefreshCredentials.from_env(@scope)).to be_nil
117
- Dir.mktmpdir do |dir|
118
- key_path = File.join dir, "does-not-exist"
119
- ENV[@var_name] = key_path
120
- expect { @clz.from_env @scope }.to raise_error RuntimeError
121
- end
122
- end
123
-
124
- it "fails if the GOOGLE_APPLICATION_CREDENTIALS path file is invalid" do
125
- needed = %w[client_id client_secret refresh_token]
126
- needed.each do |missing|
127
- Dir.mktmpdir do |dir|
128
- key_path = File.join dir, "my_cert_file"
129
- FileUtils.mkdir_p File.dirname(key_path)
130
- File.write key_path, cred_json_text(missing)
131
- ENV[@var_name] = key_path
132
- expect { @clz.from_env @scope }.to raise_error RuntimeError
133
- end
134
- end
135
- end
136
-
137
- it "succeeds when the GOOGLE_APPLICATION_CREDENTIALS file is valid" do
138
- Dir.mktmpdir do |dir|
139
- key_path = File.join dir, "my_cert_file"
140
- FileUtils.mkdir_p File.dirname(key_path)
141
- File.write key_path, cred_json_text
142
- ENV[@var_name] = key_path
143
- expect(@clz.from_env(@scope)).to_not be_nil
144
- end
145
- end
146
-
147
- it "succeeds when GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and "\
148
- "GOOGLE_REFRESH_TOKEN env vars are valid" do
149
- ENV[ENV_VAR] = nil
150
- ENV[CLIENT_ID_VAR] = cred_json[:client_id]
151
- ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
152
- ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
153
- ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
154
- creds = @clz.from_env @scope
155
- expect(creds).to_not be_nil
156
- expect(creds.client_id).to eq(cred_json[:client_id])
157
- expect(creds.client_secret).to eq(cred_json[:client_secret])
158
- expect(creds.refresh_token).to eq(cred_json[:refresh_token])
159
- end
160
-
161
- it "sets project_id when the PROJECT_ID_VAR env var is set" do
162
- ENV[ENV_VAR] = nil
163
- ENV[CLIENT_ID_VAR] = cred_json[:client_id]
164
- ENV[CLIENT_SECRET_VAR] = cred_json[:client_secret]
165
- ENV[REFRESH_TOKEN_VAR] = cred_json[:refresh_token]
166
- ENV[ACCOUNT_TYPE_VAR] = cred_json[:type]
167
- ENV[PROJECT_ID_VAR] = @project_id
168
- creds = @clz.from_env @scope
169
- expect(creds.project_id).to eq(@project_id)
170
- end
171
- end
172
-
173
- describe "#from_well_known_path" do
174
- before :example do
175
- @home = ENV["HOME"]
176
- @app_data = ENV["APPDATA"]
177
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
178
- @known_path = WELL_KNOWN_PATH
179
- @clz = UserRefreshCredentials
180
- end
181
-
182
- after :example do
183
- ENV["HOME"] = @home unless @home == ENV["HOME"]
184
- ENV["APPDATA"] = @app_data unless @app_data == ENV["APPDATA"]
185
- end
186
-
187
- it "is nil if no file exists" do
188
- ENV["HOME"] = File.dirname __FILE__
189
- expect(UserRefreshCredentials.from_well_known_path(@scope)).to be_nil
190
- end
191
-
192
- it "fails if the file is invalid" do
193
- needed = %w[client_id client_secret refresh_token]
194
- needed.each do |missing|
195
- Dir.mktmpdir do |dir|
196
- key_path = File.join dir, ".config", @known_path
197
- key_path = File.join dir, @known_path if OS.windows?
198
- FileUtils.mkdir_p File.dirname(key_path)
199
- File.write key_path, cred_json_text(missing)
200
- ENV["HOME"] = dir
201
- ENV["APPDATA"] = dir
202
- expect { @clz.from_well_known_path @scope }
203
- .to raise_error RuntimeError
204
- end
205
- end
206
- end
207
-
208
- it "successfully loads the file when it is present" do
209
- Dir.mktmpdir do |dir|
210
- key_path = File.join dir, ".config", @known_path
211
- key_path = File.join dir, @known_path if OS.windows?
212
- FileUtils.mkdir_p File.dirname(key_path)
213
- File.write key_path, cred_json_text
214
- ENV["HOME"] = dir
215
- ENV["APPDATA"] = dir
216
- expect(@clz.from_well_known_path(@scope)).to_not be_nil
217
- end
218
- end
219
-
220
- it "checks gcloud config for project_id if none was provided" do
221
- Dir.mktmpdir do |dir|
222
- key_path = File.join dir, ".config", @known_path
223
- key_path = File.join dir, @known_path if OS.windows?
224
- FileUtils.mkdir_p File.dirname(key_path)
225
- File.write key_path, cred_json_text
226
- ENV["HOME"] = dir
227
- ENV["APPDATA"] = dir
228
- ENV[PROJECT_ID_VAR] = nil
229
- expect(Google::Auth::CredentialsLoader).to receive(:load_gcloud_project_id).with(no_args)
230
- @clz.from_well_known_path @scope
231
- end
232
- end
233
- end
234
-
235
- describe "#from_system_default_path" do
236
- before :example do
237
- @scope = "https://www.googleapis.com/auth/userinfo.profile"
238
- @prefix = OS.windows? ? "/etc/Google/Auth/" : "/etc/google/auth/"
239
- @path = File.join @prefix, CREDENTIALS_FILE_NAME
240
- @program_data = ENV["ProgramData"]
241
- @clz = UserRefreshCredentials
242
- end
243
-
244
- after :example do
245
- ENV["ProgramData"] = @program_data
246
- end
247
-
248
- it "is nil if no file exists" do
249
- FakeFS do
250
- expect(UserRefreshCredentials.from_system_default_path(@scope))
251
- .to be_nil
252
- end
253
- end
254
-
255
- it "fails if the file is invalid" do
256
- needed = %w[client_id client_secret refresh_token]
257
- needed.each do |missing|
258
- FakeFS do
259
- ENV["ProgramData"] = "/etc"
260
- FileUtils.mkdir_p File.dirname(@path)
261
- File.write @path, cred_json_text(missing)
262
- expect { @clz.from_system_default_path @scope }
263
- .to raise_error RuntimeError
264
- File.delete @path
265
- end
266
- end
267
- end
268
-
269
- it "successfully loads the file when it is present" do
270
- FakeFS do
271
- ENV["ProgramData"] = "/etc"
272
- FileUtils.mkdir_p File.dirname(@path)
273
- File.write @path, cred_json_text
274
- expect(@clz.from_system_default_path(@scope)).to_not be_nil
275
- File.delete @path
276
- end
277
- end
278
- end
279
-
280
- shared_examples "revoked token" do
281
- it "should nil the refresh token" do
282
- expect(@client.refresh_token).to be_nil
283
- end
284
-
285
- it "should nil the access token" do
286
- expect(@client.access_token).to be_nil
287
- end
288
-
289
- it "should mark the token as expired" do
290
- expect(@client.expired?).to be_truthy
291
- end
292
- end
293
-
294
- describe "when revoking a refresh token" do
295
- let :stub do
296
- stub_request(:post, "https://oauth2.googleapis.com/revoke")
297
- .with(body: hash_including("token" => "refreshtoken"))
298
- .to_return(status: 200,
299
- headers: { "Content-Type" => "application/json" })
300
- end
301
-
302
- before :example do
303
- stub
304
- @client.revoke!
305
- end
306
-
307
- it_behaves_like "revoked token"
308
- end
309
-
310
- describe "when revoking an access token" do
311
- let :stub do
312
- stub_request(:post, "https://oauth2.googleapis.com/revoke")
313
- .with(body: hash_including("token" => "accesstoken"))
314
- .to_return(status: 200,
315
- headers: { "Content-Type" => "application/json" })
316
- end
317
-
318
- before :example do
319
- stub
320
- @client.refresh_token = nil
321
- @client.access_token = "accesstoken"
322
- @client.revoke!
323
- end
324
-
325
- it_behaves_like "revoked token"
326
- end
327
-
328
- describe "when revoking an invalid token" do
329
- let :stub do
330
- stub_request(:post, "https://oauth2.googleapis.com/revoke")
331
- .with(body: hash_including("token" => "refreshtoken"))
332
- .to_return(status: 400,
333
- headers: { "Content-Type" => "application/json" })
334
- end
335
-
336
- it "raises an authorization error" do
337
- stub
338
- expect { @client.revoke! }.to raise_error(
339
- Signet::AuthorizationError
340
- )
341
- end
342
- end
343
-
344
- describe "when errors occurred with request" do
345
- it "should fail with Signet::AuthorizationError if request times out" do
346
- allow_any_instance_of(Faraday::Connection).to receive(:post)
347
- .and_raise(Faraday::TimeoutError)
348
- expect { @client.revoke! }
349
- .to raise_error Signet::AuthorizationError
350
- end
351
-
352
- it "should fail with Signet::AuthorizationError if request fails" do
353
- allow_any_instance_of(Faraday::Connection).to receive(:post)
354
- .and_raise(Faraday::ConnectionFailed, nil)
355
- expect { @client.revoke! }
356
- .to raise_error Signet::AuthorizationError
357
- end
358
- end
359
- end
@@ -1,172 +0,0 @@
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"
35
- require "googleauth/web_user_authorizer"
36
- require "uri"
37
- require "multi_json"
38
- require "spec_helper"
39
- require "rack"
40
-
41
- describe Google::Auth::WebUserAuthorizer do
42
- include TestHelpers
43
-
44
- let(:client_id) { Google::Auth::ClientId.new "testclient", "notasecret" }
45
- let(:scope) { %w[email profile] }
46
- let(:token_store) { DummyTokenStore.new }
47
- let :authorizer do
48
- Google::Auth::WebUserAuthorizer.new client_id, scope, token_store
49
- end
50
-
51
- describe "#get_authorization_url" do
52
- let :env do
53
- Rack::MockRequest.env_for(
54
- "http://example.com:8080/test",
55
- "REMOTE_ADDR" => "10.10.10.10"
56
- )
57
- end
58
- let(:request) { Rack::Request.new env }
59
- it "should include current url in state" do
60
- url = authorizer.get_authorization_url request: request
61
- expect(url).to match(
62
- %r{%22current_uri%22:%22http://example.com:8080/test%22}
63
- )
64
- end
65
-
66
- it "should allow adding custom state key-value pairs" do
67
- url = authorizer.get_authorization_url request: request, state: { james: "bond", kind: 1 }
68
- expect(url).to match(%r{%22james%22:%22bond%22})
69
- expect(url).to match(%r{%22kind%22:1})
70
- end
71
-
72
- it "should include request forgery token in state" do
73
- expect(SecureRandom).to receive(:base64).and_return("aGVsbG8=")
74
- url = authorizer.get_authorization_url request: request
75
- expect(url).to match(/%22session_id%22:%22aGVsbG8=%22/)
76
- end
77
-
78
- it "should include request forgery token in session" do
79
- expect(SecureRandom).to receive(:base64).and_return("aGVsbG8=")
80
- authorizer.get_authorization_url request: request
81
- expect(request.session["g-xsrf-token"]).to eq "aGVsbG8="
82
- end
83
-
84
- it "should resolve callback against base URL" do
85
- url = authorizer.get_authorization_url request: request
86
- expect(url).to match(
87
- %r{redirect_uri=http://example.com:8080/oauth2callback}
88
- )
89
- end
90
-
91
- it "should allow overriding the current URL" do
92
- url = authorizer.get_authorization_url(
93
- request: request,
94
- redirect_to: "/foo"
95
- )
96
- expect(url).to match %r{%22current_uri%22:%22/foo%22}
97
- end
98
-
99
- it "should pass through login hint" do
100
- url = authorizer.get_authorization_url(
101
- request: request,
102
- login_hint: "user@example.com"
103
- )
104
- expect(url).to match(/login_hint=user@example.com/)
105
- end
106
- end
107
-
108
- shared_examples "handles callback" do
109
- let :token_json do
110
- MultiJson.dump("access_token" => "1/abc123",
111
- "token_type" => "Bearer",
112
- "expires_in" => 3600)
113
- end
114
-
115
- before :example do
116
- stub_request(:post, "https://oauth2.googleapis.com/token")
117
- .to_return(body: token_json,
118
- status: 200,
119
- headers: { "Content-Type" => "application/json" })
120
- end
121
-
122
- let :env do
123
- Rack::MockRequest.env_for(
124
- "http://example.com:8080/oauth2callback?code=authcode&"\
125
- "state=%7B%22current_uri%22%3A%22%2Ffoo%22%2C%22"\
126
- "session_id%22%3A%22abc%22%7D",
127
- "REMOTE_ADDR" => "10.10.10.10"
128
- )
129
- end
130
- let(:request) { Rack::Request.new env }
131
-
132
- before :example do
133
- request.session["g-xsrf-token"] = "abc"
134
- end
135
-
136
- it "should return credentials when valid code present" do
137
- expect(credentials).to be_instance_of(
138
- Google::Auth::UserRefreshCredentials
139
- )
140
- end
141
-
142
- it "should return next URL to redirect to" do
143
- expect(next_url).to eq "/foo"
144
- end
145
-
146
- it "should fail if xrsf token in session and does not match request" do
147
- request.session["g-xsrf-token"] = "123"
148
- expect { credentials }.to raise_error(Signet::AuthorizationError)
149
- end
150
- end
151
-
152
- describe "#handle_auth_callback" do
153
- let(:result) { authorizer.handle_auth_callback "user1", request }
154
- let(:credentials) { result[0] }
155
- let(:next_url) { result[1] }
156
-
157
- it_behaves_like "handles callback"
158
- end
159
-
160
- describe "#handle_auth_callback_deferred and #get_credentials" do
161
- let :next_url do
162
- Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred request
163
- end
164
-
165
- let :credentials do
166
- next_url
167
- authorizer.get_credentials "user1", request
168
- end
169
-
170
- it_behaves_like "handles callback"
171
- end
172
- end