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
@@ -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.5.1'
34
+ VERSION = "0.14.0".freeze
35
35
  end
36
36
  end
@@ -27,11 +27,11 @@
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 'multi_json'
31
- require 'googleauth/signet'
32
- require 'googleauth/user_authorizer'
33
- require 'googleauth/user_refresh'
34
- require 'securerandom'
30
+ require "multi_json"
31
+ require "googleauth/signet"
32
+ require "googleauth/user_authorizer"
33
+ require "googleauth/user_refresh"
34
+ require "securerandom"
35
35
 
36
36
  module Google
37
37
  module Auth
@@ -66,20 +66,21 @@ module Google
66
66
  # @see {Google::Auth::ControllerHelpers}
67
67
  # @note Requires sessions are enabled
68
68
  class WebUserAuthorizer < Google::Auth::UserAuthorizer
69
- STATE_PARAM = 'state'
70
- AUTH_CODE_KEY = 'code'
71
- ERROR_CODE_KEY = 'error'
72
- SESSION_ID_KEY = 'session_id'
73
- CALLBACK_STATE_KEY = 'g-auth-callback'
74
- CURRENT_URI_KEY = 'current_uri'
75
- XSRF_KEY = 'g-xsrf-token'
76
- SCOPE_KEY = 'scope'
69
+ STATE_PARAM = "state".freeze
70
+ AUTH_CODE_KEY = "code".freeze
71
+ ERROR_CODE_KEY = "error".freeze
72
+ SESSION_ID_KEY = "session_id".freeze
73
+ CALLBACK_STATE_KEY = "g-auth-callback".freeze
74
+ CURRENT_URI_KEY = "current_uri".freeze
75
+ XSRF_KEY = "g-xsrf-token".freeze
76
+ SCOPE_KEY = "scope".freeze
77
77
 
78
- NIL_REQUEST_ERROR = 'Request is required.'
79
- NIL_SESSION_ERROR = 'Sessions must be enabled'
80
- MISSING_AUTH_CODE_ERROR = 'Missing authorization code in request'
81
- AUTHORIZATION_ERROR = 'Authorization error: %s'
82
- INVALID_STATE_TOKEN_ERROR = 'State token does not match expected value'
78
+ NIL_REQUEST_ERROR = "Request is required.".freeze
79
+ NIL_SESSION_ERROR = "Sessions must be enabled".freeze
80
+ MISSING_AUTH_CODE_ERROR = "Missing authorization code in request".freeze
81
+ AUTHORIZATION_ERROR = "Authorization error: %s".freeze
82
+ INVALID_STATE_TOKEN_ERROR =
83
+ "State token does not match expected value".freeze
83
84
 
84
85
  class << self
85
86
  attr_accessor :default
@@ -96,9 +97,9 @@ module Google
96
97
  #
97
98
  # @param [Rack::Request] request
98
99
  # Current request
99
- def self.handle_auth_callback_deferred(request)
100
- callback_state, redirect_uri = extract_callback_state(request)
101
- request.session[CALLBACK_STATE_KEY] = MultiJson.dump(callback_state)
100
+ def self.handle_auth_callback_deferred request
101
+ callback_state, redirect_uri = extract_callback_state request
102
+ request.session[CALLBACK_STATE_KEY] = MultiJson.dump callback_state
102
103
  redirect_uri
103
104
  end
104
105
 
@@ -113,8 +114,8 @@ module Google
113
114
  # @param [String] callback_uri
114
115
  # URL (either absolute or relative) of the auth callback. Defaults
115
116
  # to '/oauth2callback'
116
- def initialize(client_id, scope, token_store, callback_uri = nil)
117
- super(client_id, scope, token_store, callback_uri)
117
+ def initialize client_id, scope, token_store, callback_uri = nil
118
+ super client_id, scope, token_store, callback_uri
118
119
  end
119
120
 
120
121
  # Handle the result of the oauth callback. Exchanges the authorization
@@ -126,15 +127,17 @@ module Google
126
127
  # Current request
127
128
  # @return (Google::Auth::UserRefreshCredentials, String)
128
129
  # credentials & next URL to redirect to
129
- def handle_auth_callback(user_id, request)
130
+ def handle_auth_callback user_id, request
130
131
  callback_state, redirect_uri = WebUserAuthorizer.extract_callback_state(
131
- request)
132
- WebUserAuthorizer.validate_callback_state(callback_state, request)
132
+ request
133
+ )
134
+ WebUserAuthorizer.validate_callback_state callback_state, request
133
135
  credentials = get_and_store_credentials_from_code(
134
- user_id: user_id,
135
- code: callback_state[AUTH_CODE_KEY],
136
- scope: callback_state[SCOPE_KEY],
137
- base_url: request.url)
136
+ user_id: user_id,
137
+ code: callback_state[AUTH_CODE_KEY],
138
+ scope: callback_state[SCOPE_KEY],
139
+ base_url: request.url
140
+ )
138
141
  [credentials, redirect_uri]
139
142
  end
140
143
 
@@ -151,29 +154,35 @@ module Google
151
154
  # @param [String, Array<String>] scope
152
155
  # Authorization scope to request. Overrides the instance scopes if
153
156
  # not nil.
157
+ # @param [Hash] state
158
+ # Optional key-values to be returned to the oauth callback.
154
159
  # @return [String]
155
160
  # Authorization url
156
- def get_authorization_url(options = {})
161
+ def get_authorization_url options = {}
157
162
  options = options.dup
158
163
  request = options[:request]
159
- fail NIL_REQUEST_ERROR if request.nil?
160
- fail NIL_SESSION_ERROR if request.session.nil?
164
+ raise NIL_REQUEST_ERROR if request.nil?
165
+ raise NIL_SESSION_ERROR if request.session.nil?
166
+
167
+ state = options[:state] || {}
161
168
 
162
169
  redirect_to = options[:redirect_to] || request.url
163
170
  request.session[XSRF_KEY] = SecureRandom.base64
164
- options[:state] = MultiJson.dump(
165
- SESSION_ID_KEY => request.session[XSRF_KEY],
166
- CURRENT_URI_KEY => redirect_to)
171
+ options[:state] = MultiJson.dump(state.merge(
172
+ SESSION_ID_KEY => request.session[XSRF_KEY],
173
+ CURRENT_URI_KEY => redirect_to
174
+ ))
167
175
  options[:base_url] = request.url
168
- super(options)
176
+ super options
169
177
  end
170
178
 
171
- # Fetch stored credentials for the user.
179
+ # Fetch stored credentials for the user from the given request session.
172
180
  #
173
181
  # @param [String] user_id
174
182
  # Unique ID of the user for loading/storing credentials.
175
183
  # @param [Rack::Request] request
176
- # Current request
184
+ # Current request. Optional. If omitted, this will attempt to fall back
185
+ # on the base class behavior of reading from the token store.
177
186
  # @param [Array<String>, String] scope
178
187
  # If specified, only returns credentials that have all the \
179
188
  # requested scopes
@@ -182,31 +191,32 @@ module Google
182
191
  # @raise [Signet::AuthorizationError]
183
192
  # May raise an error if an authorization code is present in the session
184
193
  # and exchange of the code fails
185
- def get_credentials(user_id, request, scope = nil)
186
- if request.session.key?(CALLBACK_STATE_KEY)
194
+ def get_credentials user_id, request = nil, scope = nil
195
+ if request && request.session.key?(CALLBACK_STATE_KEY)
187
196
  # Note - in theory, no need to check required scope as this is
188
197
  # expected to be called immediately after a return from authorization
189
- state_json = request.session.delete(CALLBACK_STATE_KEY)
190
- callback_state = MultiJson.load(state_json)
191
- WebUserAuthorizer.validate_callback_state(callback_state, request)
198
+ state_json = request.session.delete CALLBACK_STATE_KEY
199
+ callback_state = MultiJson.load state_json
200
+ WebUserAuthorizer.validate_callback_state callback_state, request
192
201
  get_and_store_credentials_from_code(
193
- user_id: user_id,
194
- code: callback_state[AUTH_CODE_KEY],
195
- scope: callback_state[SCOPE_KEY],
196
- base_url: request.url)
202
+ user_id: user_id,
203
+ code: callback_state[AUTH_CODE_KEY],
204
+ scope: callback_state[SCOPE_KEY],
205
+ base_url: request.url
206
+ )
197
207
  else
198
- super(user_id, scope)
208
+ super user_id, scope
199
209
  end
200
210
  end
201
211
 
202
- def self.extract_callback_state(request)
203
- state = MultiJson.load(request[STATE_PARAM] || '{}')
212
+ def self.extract_callback_state request
213
+ state = MultiJson.load(request[STATE_PARAM] || "{}")
204
214
  redirect_uri = state[CURRENT_URI_KEY]
205
215
  callback_state = {
206
- AUTH_CODE_KEY => request[AUTH_CODE_KEY],
207
- ERROR_CODE_KEY => request[ERROR_CODE_KEY],
216
+ AUTH_CODE_KEY => request[AUTH_CODE_KEY],
217
+ ERROR_CODE_KEY => request[ERROR_CODE_KEY],
208
218
  SESSION_ID_KEY => state[SESSION_ID_KEY],
209
- SCOPE_KEY => request[SCOPE_KEY]
219
+ SCOPE_KEY => request[SCOPE_KEY]
210
220
  }
211
221
  [callback_state, redirect_uri]
212
222
  end
@@ -221,14 +231,13 @@ module Google
221
231
  # Error message if failed
222
232
  # @param [Rack::Request] request
223
233
  # Current request
224
- def self.validate_callback_state(state, request)
225
- if state[AUTH_CODE_KEY].nil?
226
- fail Signet::AuthorizationError, MISSING_AUTH_CODE_ERROR
227
- elsif state[ERROR_CODE_KEY]
228
- fail Signet::AuthorizationError,
229
- sprintf(AUTHORIZATION_ERROR, state[ERROR_CODE_KEY])
234
+ def self.validate_callback_state state, request
235
+ raise Signet::AuthorizationError, MISSING_AUTH_CODE_ERROR if state[AUTH_CODE_KEY].nil?
236
+ if state[ERROR_CODE_KEY]
237
+ raise Signet::AuthorizationError,
238
+ format(AUTHORIZATION_ERROR, state[ERROR_CODE_KEY])
230
239
  elsif request.session[XSRF_KEY] != state[SESSION_ID_KEY]
231
- fail Signet::AuthorizationError, INVALID_STATE_TOKEN_ERROR
240
+ raise Signet::AuthorizationError, INVALID_STATE_TOKEN_ERROR
232
241
  end
233
242
  end
234
243
 
@@ -254,7 +263,7 @@ module Google
254
263
  #
255
264
  # @see {Google::Auth::WebUserAuthorizer}
256
265
  class CallbackApp
257
- LOCATION_HEADER = 'Location'
266
+ LOCATION_HEADER = "Location".freeze
258
267
  REDIR_STATUS = 302
259
268
  ERROR_STATUS = 500
260
269
 
@@ -270,18 +279,18 @@ module Google
270
279
  # Rack environment
271
280
  # @return [Array]
272
281
  # HTTP response
273
- def self.call(env)
274
- request = Rack::Request.new(env)
275
- return_url = WebUserAuthorizer.handle_auth_callback_deferred(request)
282
+ def self.call env
283
+ request = Rack::Request.new env
284
+ return_url = WebUserAuthorizer.handle_auth_callback_deferred request
276
285
  if return_url
277
286
  [REDIR_STATUS, { LOCATION_HEADER => return_url }, []]
278
287
  else
279
- [ERROR_STATUS, {}, ['No return URL is present in the request.']]
288
+ [ERROR_STATUS, {}, ["No return URL is present in the request."]]
280
289
  end
281
290
  end
282
291
 
283
- def call(env)
284
- self.class.call(env)
292
+ def call env
293
+ self.class.call env
285
294
  end
286
295
  end
287
296
  end
@@ -0,0 +1,45 @@
1
+ require "pathname"
2
+
3
+ require_relative "repo_metadata.rb"
4
+
5
+ class DevsiteBuilder
6
+ def initialize master_dir = "."
7
+ @master_dir = Pathname.new master_dir
8
+ @output_dir = "doc"
9
+ @metadata = RepoMetadata.from_source "#{master_dir}/.repo-metadata.json"
10
+ end
11
+
12
+ def build
13
+ FileUtils.remove_dir @output_dir if Dir.exist? @output_dir
14
+ markup = "--markup markdown"
15
+
16
+ Dir.chdir @master_dir do
17
+ cmds = ["-o #{@output_dir}", markup]
18
+ cmd "yard --verbose #{cmds.join ' '}"
19
+ end
20
+ @metadata.build @master_dir + @output_dir
21
+ end
22
+
23
+ def upload
24
+ Dir.chdir @output_dir do
25
+ opts = [
26
+ "--credentials=#{ENV['KOKORO_KEYSTORE_DIR']}/73713_docuploader_service_account",
27
+ "--staging-bucket=#{ENV.fetch 'STAGING_BUCKET', 'docs-staging'}",
28
+ "--metadata-file=./docs.metadata"
29
+ ]
30
+ cmd "python3 -m docuploader upload . #{opts.join ' '}"
31
+ end
32
+ end
33
+
34
+ def publish
35
+ build
36
+ upload
37
+ end
38
+
39
+ def cmd line
40
+ puts line
41
+ output = `#{line}`
42
+ puts output
43
+ output
44
+ end
45
+ end
@@ -0,0 +1,64 @@
1
+ require "open3"
2
+
3
+ class LinkChecker
4
+ def initialize
5
+ @failed = false
6
+ end
7
+
8
+ def run
9
+ job_info
10
+ git_commit = ENV.fetch "KOKORO_GITHUB_COMMIT", "master"
11
+
12
+ markdown_files = Dir.glob "**/*.md"
13
+ broken_markdown_links = check_links markdown_files,
14
+ "https://github.com/googleapis/google-auth-library-ruby/tree/#{git_commit}",
15
+ " --skip '^(?!(\\Wruby.*google|.*google.*\\Wruby|.*cloud\\.google\\.com))'"
16
+
17
+ broken_devsite_links = check_links ["googleauth"],
18
+ "https://googleapis.dev/ruby",
19
+ "/latest/ --recurse --skip https:.*github.*"
20
+
21
+ puts_broken_links broken_markdown_links
22
+ puts_broken_links broken_devsite_links
23
+ end
24
+
25
+ def check_links location_list, base, tail
26
+ broken_links = Hash.new { |h, k| h[k] = [] }
27
+ location_list.each do |location|
28
+ out, err, st = Open3.capture3 "npx linkinator #{base}/#{location}#{tail}"
29
+ puts out
30
+ unless st.to_i.zero?
31
+ @failed = true
32
+ puts err
33
+ end
34
+ checked_links = out.split "\n"
35
+ checked_links.select! { |link| link =~ /\[\d+\]/ && !link.include?("[200]") }
36
+ unless checked_links.empty?
37
+ @failed = true
38
+ broken_links[location] += checked_links
39
+ end
40
+ end
41
+ broken_links
42
+ end
43
+
44
+ def puts_broken_links link_hash
45
+ link_hash.each do |location, links|
46
+ puts "#{location} contains the following broken links:"
47
+ links.each { |link| puts " #{link}" }
48
+ puts ""
49
+ end
50
+ end
51
+
52
+ def job_info
53
+ line_length = "Using Ruby - #{RUBY_VERSION}".length + 8
54
+ puts ""
55
+ puts "#" * line_length
56
+ puts "### Using Ruby - #{RUBY_VERSION} ###"
57
+ puts "#" * line_length
58
+ puts ""
59
+ end
60
+
61
+ def exit_status
62
+ @failed ? 1 : 0
63
+ end
64
+ end
@@ -0,0 +1,59 @@
1
+ require "json"
2
+
3
+ class RepoMetadata
4
+ attr_reader :data
5
+
6
+ def initialize data
7
+ @data = data
8
+ normalize_data!
9
+ end
10
+
11
+ def allowed_fields
12
+ [
13
+ "name", "version", "language", "distribution-name",
14
+ "product-page", "github-repository", "issue-tracker"
15
+ ]
16
+ end
17
+
18
+ def build output_directory
19
+ fields = @data.to_a.map { |kv| "--#{kv[0]} #{kv[1]}" }
20
+ Dir.chdir output_directory do
21
+ cmd "python3 -m docuploader create-metadata #{fields.join ' '}"
22
+ end
23
+ end
24
+
25
+ def normalize_data!
26
+ require_relative "../lib/googleauth/version.rb"
27
+
28
+ @data.delete_if { |k, _| !allowed_fields.include?(k) }
29
+ @data["version"] = "v#{Google::Auth::VERSION}"
30
+ end
31
+
32
+ def [] key
33
+ data[key]
34
+ end
35
+
36
+ def []= key, value
37
+ @data[key] = value
38
+ end
39
+
40
+ def cmd line
41
+ puts line
42
+ output = `#{line}`
43
+ puts output
44
+ output
45
+ end
46
+
47
+ def self.from_source source
48
+ if source.is_a? RepoMetadata
49
+ data = source.data
50
+ elsif source.is_a? Hash
51
+ data = source
52
+ elsif File.file? source
53
+ data = JSON.parse File.read(source)
54
+ else
55
+ raise "Source must be a path, hash, or RepoMetadata instance"
56
+ end
57
+ RepoMetadata.new data
58
+ end
59
+ end
@@ -27,14 +27,14 @@
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
- spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
31
- $LOAD_PATH.unshift(spec_dir)
30
+ spec_dir = File.expand_path File.join(File.dirname(__FILE__))
31
+ $LOAD_PATH.unshift spec_dir
32
32
  $LOAD_PATH.uniq!
33
33
 
34
- require 'faraday'
35
- require 'spec_helper'
34
+ require "faraday"
35
+ require "spec_helper"
36
36
 
37
- shared_examples 'apply/apply! are OK' do
37
+ shared_examples "apply/apply! are OK" do
38
38
  let(:auth_key) { :authorization }
39
39
 
40
40
  # tests that use these examples need to define
@@ -43,102 +43,126 @@ shared_examples 'apply/apply! are OK' do
43
43
  #
44
44
  # @make_auth_stubs, which should stub out the expected http behaviour of the
45
45
  # auth client
46
- describe '#fetch_access_token' do
47
- let(:token) { '1/abcdef1234567890' }
48
- let(:stub) do
46
+ describe "#fetch_access_token" do
47
+ let(:token) { "1/abcdef1234567890" }
48
+ let :access_stub do
49
49
  make_auth_stubs access_token: token
50
50
  end
51
+ let :id_stub do
52
+ make_auth_stubs id_token: token
53
+ end
51
54
 
52
- it 'should set access_token to the fetched value' do
53
- stub
55
+ it "should set access_token to the fetched value" do
56
+ access_stub
54
57
  @client.fetch_access_token!
55
58
  expect(@client.access_token).to eq(token)
56
- expect(stub).to have_been_requested
59
+ expect(access_stub).to have_been_requested
57
60
  end
58
61
 
59
- it 'should notify refresh listeners after updating' do
60
- stub
62
+ it "should set id_token to the fetched value" do
63
+ skip unless @id_client
64
+ id_stub
65
+ @id_client.fetch_access_token!
66
+ expect(@id_client.id_token).to eq(token)
67
+ expect(id_stub).to have_been_requested
68
+ end
69
+
70
+ it "should notify refresh listeners after updating" do
71
+ access_stub
61
72
  expect do |b|
62
73
  @client.on_refresh(&b)
63
74
  @client.fetch_access_token!
64
75
  end.to yield_with_args(have_attributes(
65
- access_token: '1/abcdef1234567890'))
66
- expect(stub).to have_been_requested
76
+ access_token: "1/abcdef1234567890"
77
+ ))
78
+ expect(access_stub).to have_been_requested
67
79
  end
68
80
  end
69
81
 
70
- describe '#apply!' do
71
- it 'should update the target hash with fetched access token' do
72
- token = '1/abcdef1234567890'
82
+ describe "#apply!" do
83
+ it "should update the target hash with fetched access token" do
84
+ token = "1/abcdef1234567890"
73
85
  stub = make_auth_stubs access_token: token
74
86
 
75
- md = { foo: 'bar' }
76
- @client.apply!(md)
77
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
87
+ md = { foo: "bar" }
88
+ @client.apply! md
89
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
90
+ expect(md).to eq(want)
91
+ expect(stub).to have_been_requested
92
+ end
93
+
94
+ it "should update the target hash with fetched ID token" do
95
+ skip unless @id_client
96
+ token = "1/abcdef1234567890"
97
+ stub = make_auth_stubs id_token: token
98
+
99
+ md = { foo: "bar" }
100
+ @id_client.apply! md
101
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
78
102
  expect(md).to eq(want)
79
103
  expect(stub).to have_been_requested
80
104
  end
81
105
  end
82
106
 
83
- describe 'updater_proc' do
84
- it 'should provide a proc that updates a hash with the access token' do
85
- token = '1/abcdef1234567890'
107
+ describe "updater_proc" do
108
+ it "should provide a proc that updates a hash with the access token" do
109
+ token = "1/abcdef1234567890"
86
110
  stub = make_auth_stubs access_token: token
87
- md = { foo: 'bar' }
111
+ md = { foo: "bar" }
88
112
  the_proc = @client.updater_proc
89
- got = the_proc.call(md)
90
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
113
+ got = the_proc.call md
114
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
91
115
  expect(got).to eq(want)
92
116
  expect(stub).to have_been_requested
93
117
  end
94
118
  end
95
119
 
96
- describe '#apply' do
97
- it 'should not update the original hash with the access token' do
98
- token = '1/abcdef1234567890'
120
+ describe "#apply" do
121
+ it "should not update the original hash with the access token" do
122
+ token = "1/abcdef1234567890"
99
123
  stub = make_auth_stubs access_token: token
100
124
 
101
- md = { foo: 'bar' }
102
- @client.apply(md)
103
- want = { foo: 'bar' }
125
+ md = { foo: "bar" }
126
+ @client.apply md
127
+ want = { foo: "bar" }
104
128
  expect(md).to eq(want)
105
129
  expect(stub).to have_been_requested
106
130
  end
107
131
 
108
- it 'should add the token to the returned hash' do
109
- token = '1/abcdef1234567890'
132
+ it "should add the token to the returned hash" do
133
+ token = "1/abcdef1234567890"
110
134
  stub = make_auth_stubs access_token: token
111
135
 
112
- md = { foo: 'bar' }
113
- got = @client.apply(md)
114
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
136
+ md = { foo: "bar" }
137
+ got = @client.apply md
138
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
115
139
  expect(got).to eq(want)
116
140
  expect(stub).to have_been_requested
117
141
  end
118
142
 
119
- it 'should not fetch a new token if the current is not expired' do
120
- token = '1/abcdef1234567890'
143
+ it "should not fetch a new token if the current is not expired" do
144
+ token = "1/abcdef1234567890"
121
145
  stub = make_auth_stubs access_token: token
122
146
 
123
147
  n = 5 # arbitrary
124
148
  n.times do |_t|
125
- md = { foo: 'bar' }
126
- got = @client.apply(md)
127
- want = { :foo => 'bar', auth_key => "Bearer #{token}" }
149
+ md = { foo: "bar" }
150
+ got = @client.apply md
151
+ want = { :foo => "bar", auth_key => "Bearer #{token}" }
128
152
  expect(got).to eq(want)
129
153
  end
130
154
  expect(stub).to have_been_requested
131
155
  end
132
156
 
133
- it 'should fetch a new token if the current one is expired' do
134
- token_1 = '1/abcdef1234567890'
135
- token_2 = '2/abcdef1234567891'
157
+ it "should fetch a new token if the current one is expired" do
158
+ token1 = "1/abcdef1234567890"
159
+ token2 = "2/abcdef1234567891"
136
160
 
137
- [token_1, token_2].each do |t|
161
+ [token1, token2].each do |t|
138
162
  make_auth_stubs access_token: t
139
- md = { foo: 'bar' }
140
- got = @client.apply(md)
141
- want = { :foo => 'bar', auth_key => "Bearer #{t}" }
163
+ md = { foo: "bar" }
164
+ got = @client.apply md
165
+ want = { :foo => "bar", auth_key => "Bearer #{t}" }
142
166
  expect(got).to eq(want)
143
167
  @client.expires_at -= 3601 # default is to expire in 1hr
144
168
  end