signet 0.11.0 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -15
  3. data/Gemfile +5 -4
  4. data/README.md +4 -6
  5. data/Rakefile +107 -37
  6. data/lib/signet.rb +17 -14
  7. data/lib/signet/errors.rb +4 -4
  8. data/lib/signet/oauth_1.rb +129 -154
  9. data/lib/signet/oauth_1/client.rb +309 -343
  10. data/lib/signet/oauth_1/credential.rb +40 -37
  11. data/lib/signet/oauth_1/server.rb +197 -203
  12. data/lib/signet/oauth_1/signature_methods/hmac_sha1.rb +11 -10
  13. data/lib/signet/oauth_1/signature_methods/plaintext.rb +8 -7
  14. data/lib/signet/oauth_1/signature_methods/rsa_sha1.rb +11 -11
  15. data/lib/signet/oauth_2.rb +41 -43
  16. data/lib/signet/oauth_2/client.rb +328 -313
  17. data/lib/signet/version.rb +2 -73
  18. data/signet.gemspec +37 -39
  19. data/spec/signet/oauth_1/client_spec.rb +313 -315
  20. data/spec/signet/oauth_1/credential_spec.rb +64 -56
  21. data/spec/signet/oauth_1/server_spec.rb +362 -362
  22. data/spec/signet/oauth_1/signature_methods/hmac_sha1_spec.rb +26 -26
  23. data/spec/signet/oauth_1/signature_methods/plaintext_spec.rb +28 -28
  24. data/spec/signet/oauth_1/signature_methods/rsa_sha1_spec.rb +34 -35
  25. data/spec/signet/oauth_1_spec.rb +553 -524
  26. data/spec/signet/oauth_2/client_spec.rb +652 -576
  27. data/spec/signet/oauth_2_spec.rb +88 -89
  28. data/spec/signet_spec.rb +41 -41
  29. data/spec/spec_helper.rb +7 -7
  30. data/spec/spec_helper_spec.rb +8 -8
  31. metadata +64 -52
  32. data/tasks/clobber.rake +0 -2
  33. data/tasks/gem.rake +0 -34
  34. data/tasks/git.rake +0 -40
  35. data/tasks/metrics.rake +0 -41
  36. data/tasks/spec.rake +0 -34
  37. data/tasks/wiki.rake +0 -38
  38. data/tasks/yard.rake +0 -21
@@ -1,23 +1,24 @@
1
- require 'openssl'
2
- require 'signet'
1
+ require "openssl"
2
+ require "signet"
3
3
 
4
4
  module Signet #:nodoc:
5
5
  module OAuth1
6
6
  module HMACSHA1
7
- def self.generate_signature(
8
- base_string, client_credential_secret, token_credential_secret)
7
+ def self.generate_signature \
8
+ base_string, client_credential_secret, token_credential_secret
9
+
9
10
  # Both the client secret and token secret must be escaped
10
11
  client_credential_secret =
11
- Signet::OAuth1.encode(client_credential_secret)
12
+ Signet::OAuth1.encode client_credential_secret
12
13
  token_credential_secret =
13
- Signet::OAuth1.encode(token_credential_secret)
14
+ Signet::OAuth1.encode token_credential_secret
14
15
  # The key for the signature is just the client secret and token
15
16
  # secret joined by the '&' character. If the token secret is omitted,
16
17
  # the '&' must still be present.
17
- key = [client_credential_secret, token_credential_secret].join("&")
18
- return Base64.encode64(OpenSSL::HMAC.digest(
19
- OpenSSL::Digest.new('sha1'), key, base_string
20
- )).strip
18
+ key = [client_credential_secret, token_credential_secret].join "&"
19
+ Base64.encode64(OpenSSL::HMAC.digest(
20
+ OpenSSL::Digest.new("sha1"), key, base_string
21
+ )).strip
21
22
  end
22
23
  end
23
24
  end
@@ -1,20 +1,21 @@
1
- require 'signet'
1
+ require "signet"
2
2
 
3
3
  module Signet #:nodoc:
4
4
  module OAuth1
5
5
  module PLAINTEXT
6
- def self.generate_signature(
7
- base_string, client_credential_secret, token_credential_secret)
6
+ def self.generate_signature \
7
+ _base_string, client_credential_secret, token_credential_secret
8
+
8
9
  # Both the client secret and token secret must be escaped
9
10
  client_credential_secret =
10
- Signet::OAuth1.encode(client_credential_secret)
11
+ Signet::OAuth1.encode client_credential_secret
11
12
  token_credential_secret =
12
- Signet::OAuth1.encode(token_credential_secret)
13
+ Signet::OAuth1.encode token_credential_secret
13
14
  # The key for the signature is just the client secret and token
14
15
  # secret joined by the '&' character. If the token secret is omitted,
15
16
  # the '&' must still be present.
16
- key = [client_credential_secret, token_credential_secret].join("&")
17
- return Signet::OAuth1.encode(key).strip
17
+ key = [client_credential_secret, token_credential_secret].join "&"
18
+ Signet::OAuth1.encode(key).strip
18
19
  end
19
20
  end
20
21
  end
@@ -1,20 +1,20 @@
1
- require 'digest/sha1'
2
- require 'base64'
3
- require 'openssl'
4
- require 'signet'
1
+ require "digest/sha1"
2
+ require "base64"
3
+ require "openssl"
4
+ require "signet"
5
5
 
6
6
  module Signet #:nodoc:
7
7
  module OAuth1
8
8
  module RSASHA1
9
- def self.generate_signature(
10
- base_string, client_credential_secret, token_credential_secret)
9
+ def self.generate_signature \
10
+ base_string, client_credential_secret, _token_credential_secret
11
11
 
12
- private_key = OpenSSL::PKey::RSA.new(client_credential_secret)
13
- signature = private_key.sign(OpenSSL::Digest::SHA1.new, base_string)
14
- #using strict_encode64 because the encode64 method adds newline characters after ever 60 chars
15
- return Base64.strict_encode64(signature).strip
16
- end
17
12
 
13
+ private_key = OpenSSL::PKey::RSA.new client_credential_secret
14
+ signature = private_key.sign OpenSSL::Digest::SHA1.new, base_string
15
+ # using strict_encode64 because the encode64 method adds newline characters after ever 60 chars
16
+ Base64.strict_encode64(signature).strip
17
+ end
18
18
  end
19
19
  end
20
20
  end
@@ -12,9 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'base64'
16
- require 'signet'
17
- require 'multi_json'
15
+ require "base64"
16
+ require "signet"
17
+ require "multi_json"
18
18
 
19
19
  module Signet #:nodoc:
20
20
  ##
@@ -23,63 +23,61 @@ module Signet #:nodoc:
23
23
  # This module will be updated periodically to support newer drafts of the
24
24
  # specification, as they become widely deployed.
25
25
  module OAuth2
26
- def self.parse_authorization_header(field_value)
26
+ def self.parse_authorization_header field_value
27
27
  auth_scheme = field_value[/^([-._0-9a-zA-Z]+)/, 1]
28
28
  case auth_scheme
29
29
  when /^Basic$/i
30
30
  # HTTP Basic is allowed in OAuth 2
31
- return self.parse_basic_credentials(field_value[/^Basic\s+(.*)$/i, 1])
31
+ return parse_basic_credentials(field_value[/^Basic\s+(.*)$/i, 1])
32
32
  when /^OAuth$/i
33
33
  # Other token types may be supported eventually
34
- return self.parse_bearer_credentials(field_value[/^OAuth\s+(.*)$/i, 1])
34
+ return parse_bearer_credentials(field_value[/^OAuth\s+(.*)$/i, 1])
35
35
  else
36
36
  raise ParseError,
37
- 'Parsing non-OAuth Authorization headers is out of scope.'
37
+ "Parsing non-OAuth Authorization headers is out of scope."
38
38
  end
39
39
  end
40
40
 
41
- def self.parse_www_authenticate_header(field_value)
41
+ def self.parse_www_authenticate_header field_value
42
42
  auth_scheme = field_value[/^([-._0-9a-zA-Z]+)/, 1]
43
43
  case auth_scheme
44
44
  when /^OAuth$/i
45
45
  # Other token types may be supported eventually
46
- return self.parse_oauth_challenge(field_value[/^OAuth\s+(.*)$/i, 1])
46
+ return parse_oauth_challenge(field_value[/^OAuth\s+(.*)$/i, 1])
47
47
  else
48
48
  raise ParseError,
49
- 'Parsing non-OAuth WWW-Authenticate headers is out of scope.'
49
+ "Parsing non-OAuth WWW-Authenticate headers is out of scope."
50
50
  end
51
51
  end
52
52
 
53
- def self.parse_basic_credentials(credential_string)
54
- decoded = Base64.decode64(credential_string)
55
- client_id, client_secret = decoded.split(':', 2)
56
- return [['client_id', client_id], ['client_secret', client_secret]]
53
+ def self.parse_basic_credentials credential_string
54
+ decoded = Base64.decode64 credential_string
55
+ client_id, client_secret = decoded.split ":", 2
56
+ [["client_id", client_id], ["client_secret", client_secret]]
57
57
  end
58
58
 
59
- def self.parse_bearer_credentials(credential_string)
59
+ def self.parse_bearer_credentials credential_string
60
60
  access_token = credential_string[/^([^,\s]+)(?:\s|,|$)/i, 1]
61
61
  parameters = []
62
- parameters << ['access_token', access_token]
62
+ parameters << ["access_token", access_token]
63
63
  auth_param_string = credential_string[/^(?:[^,\s]+)\s*,\s*(.*)$/i, 1]
64
64
  if auth_param_string
65
65
  # This code will rarely get called, but is included for completeness
66
- parameters.concat(Signet.parse_auth_param_list(auth_param_string))
66
+ parameters.concat Signet.parse_auth_param_list(auth_param_string)
67
67
  end
68
- return parameters
68
+ parameters
69
69
  end
70
70
 
71
- def self.parse_oauth_challenge(challenge_string)
72
- return Signet.parse_auth_param_list(challenge_string)
71
+ def self.parse_oauth_challenge challenge_string
72
+ Signet.parse_auth_param_list challenge_string
73
73
  end
74
74
 
75
- def self.parse_credentials(body, content_type)
76
- if !body.kind_of?(String)
77
- raise TypeError, "Expected String, got #{body.class}."
78
- end
75
+ def self.parse_credentials body, content_type
76
+ raise TypeError, "Expected String, got #{body.class}." unless body.is_a? String
79
77
  case content_type
80
- when /^application\/json.*/
81
- return MultiJson.load(body)
82
- when /^application\/x-www-form-urlencoded.*/
78
+ when %r{^application/json.*}
79
+ return MultiJson.load body
80
+ when %r{^application/x-www-form-urlencoded.*}
83
81
  return Hash[Addressable::URI.form_unencode(body)]
84
82
  else
85
83
  raise ArgumentError, "Invalid content type '#{content_type}'"
@@ -97,14 +95,14 @@ module Signet #:nodoc:
97
95
  #
98
96
  # @return [String]
99
97
  # The value for the HTTP Basic Authorization header.
100
- def self.generate_basic_authorization_header(client_id, client_password)
98
+ def self.generate_basic_authorization_header client_id, client_password
101
99
  if client_id =~ /:/
102
100
  raise ArgumentError,
103
- "A client identifier may not contain a ':' character."
101
+ "A client identifier may not contain a ':' character."
104
102
  end
105
- return 'Basic ' + Base64.encode64(
106
- client_id + ':' + client_password
107
- ).gsub(/\n/, '')
103
+ "Basic " + Base64.encode64(
104
+ client_id + ":" + client_password
105
+ ).delete("\n")
108
106
  end
109
107
 
110
108
  ##
@@ -117,19 +115,19 @@ module Signet #:nodoc:
117
115
  #
118
116
  # @return [String]
119
117
  # The value for the HTTP Basic Authorization header.
120
- def self.generate_bearer_authorization_header(
121
- access_token, auth_params=nil)
118
+ def self.generate_bearer_authorization_header \
119
+ access_token, auth_params = nil
120
+
122
121
  # TODO: escaping?
123
122
  header = "Bearer #{access_token}"
124
123
  if auth_params && !auth_params.empty?
125
124
  header += (", " +
126
- (auth_params.inject([]) do |accu, (key, value)|
125
+ (auth_params.each_with_object [] do |(key, value), accu|
127
126
  accu << "#{key}=\"#{value}\""
128
- accu
129
127
  end).join(", ")
130
- )
128
+ )
131
129
  end
132
- return header
130
+ header
133
131
  end
134
132
 
135
133
  ##
@@ -140,15 +138,15 @@ module Signet #:nodoc:
140
138
  # The base authorization endpoint URI.
141
139
  #
142
140
  # @return [String] The authorization URI to redirect the user to.
143
- def self.generate_authorization_uri(authorization_uri, parameters={})
144
- for key, value in parameters
145
- parameters.delete(key) if value.nil?
141
+ def self.generate_authorization_uri authorization_uri, parameters = {}
142
+ parameters.each do |key, value|
143
+ parameters.delete key if value.nil?
146
144
  end
147
145
  parsed_uri = Addressable::URI.parse(authorization_uri).dup
148
146
  query_values = parsed_uri.query_values || {}
149
- query_values = query_values.merge(parameters)
147
+ query_values = query_values.merge parameters
150
148
  parsed_uri.query_values = query_values
151
- return parsed_uri.normalize.to_s
149
+ parsed_uri.normalize.to_s
152
150
  end
153
151
  end
154
152
  end
@@ -12,20 +12,19 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- require 'faraday'
16
- require 'stringio'
17
- require 'addressable/uri'
18
- require 'signet'
19
- require 'signet/errors'
20
- require 'signet/oauth_2'
21
- require 'jwt'
22
- require 'date'
15
+ require "faraday"
16
+ require "stringio"
17
+ require "addressable/uri"
18
+ require "signet"
19
+ require "signet/errors"
20
+ require "signet/oauth_2"
21
+ require "jwt"
22
+ require "date"
23
23
 
24
24
  module Signet
25
25
  module OAuth2
26
26
  class Client
27
-
28
- OOB_MODES = %w(urn:ietf:wg:oauth:2.0:oob:auto urn:ietf:wg:oauth:2.0:oob oob)
27
+ OOB_MODES = ["urn:ietf:wg:oauth:2.0:oob:auto", "urn:ietf:wg:oauth:2.0:oob", "oob"].freeze
29
28
 
30
29
  ##
31
30
  # Creates an OAuth 2.0 client.
@@ -47,6 +46,9 @@ module Signet
47
46
  # - <code>:scope</code> -
48
47
  # The scope of the access request, expressed either as an Array
49
48
  # or as a space-delimited String.
49
+ # - <code>:target_audience</code> -
50
+ # The final target audience for ID tokens fetched by this client,
51
+ # as a String.
50
52
  # - <code>:state</code> -
51
53
  # An arbitrary string designed to allow the client to maintain state.
52
54
  # - <code>:code</code> -
@@ -89,7 +91,7 @@ module Signet
89
91
  # )
90
92
  #
91
93
  # @see Signet::OAuth2::Client#update!
92
- def initialize options={}
94
+ def initialize options = {}
93
95
  @authorization_uri = nil
94
96
  @token_credential_uri = nil
95
97
  @client_id = nil
@@ -102,11 +104,15 @@ module Signet
102
104
  @principal = nil
103
105
  @redirect_uri = nil
104
106
  @scope = nil
107
+ @target_audience = nil
105
108
  @state = nil
106
109
  @username = nil
107
110
  @access_type = nil
108
- self.update!(options)
111
+ update! options
109
112
  end
113
+ # rubocop:disable Metrics/AbcSize
114
+ # rubocop:disable Metrics/CyclomaticComplexity
115
+ # rubocop:disable Metrics/PerceivedComplexity
110
116
 
111
117
  ##
112
118
  # Updates an OAuth 2.0 client.
@@ -128,6 +134,9 @@ module Signet
128
134
  # - <code>:scope</code> -
129
135
  # The scope of the access request, expressed either as an Array
130
136
  # or as a space-delimited String.
137
+ # - <code>:target_audience</code> -
138
+ # The final target audience for ID tokens fetched by this client,
139
+ # as a String.
131
140
  # - <code>:state</code> -
132
141
  # An arbitrary string designed to allow the client to maintain state.
133
142
  # - <code>:code</code> -
@@ -170,32 +179,36 @@ module Signet
170
179
  #
171
180
  # @see Signet::OAuth2::Client#initialize
172
181
  # @see Signet::OAuth2::Client#update_token!
173
- def update!(options={})
182
+ def update! options = {}
174
183
  # Normalize all keys to symbols to allow indifferent access.
175
- options = deep_hash_normalize(options)
176
-
177
- self.authorization_uri = options[:authorization_uri] if options.has_key?(:authorization_uri)
178
- self.token_credential_uri = options[:token_credential_uri] if options.has_key?(:token_credential_uri)
179
- self.client_id = options[:client_id] if options.has_key?(:client_id)
180
- self.client_secret = options[:client_secret] if options.has_key?(:client_secret)
181
- self.scope = options[:scope] if options.has_key?(:scope)
182
- self.state = options[:state] if options.has_key?(:state)
183
- self.code = options[:code] if options.has_key?(:code)
184
- self.redirect_uri = options[:redirect_uri] if options.has_key?(:redirect_uri)
185
- self.username = options[:username] if options.has_key?(:username)
186
- self.password = options[:password] if options.has_key?(:password)
187
- self.issuer = options[:issuer] if options.has_key?(:issuer)
188
- self.person = options[:person] if options.has_key?(:person)
189
- self.sub = options[:sub] if options.has_key?(:sub)
184
+ options = deep_hash_normalize options
185
+
186
+ self.authorization_uri = options[:authorization_uri] if options.key? :authorization_uri
187
+ self.token_credential_uri = options[:token_credential_uri] if options.key? :token_credential_uri
188
+ self.client_id = options[:client_id] if options.key? :client_id
189
+ self.client_secret = options[:client_secret] if options.key? :client_secret
190
+ self.scope = options[:scope] if options.key? :scope
191
+ self.target_audience = options[:target_audience] if options.key? :target_audience
192
+ self.state = options[:state] if options.key? :state
193
+ self.code = options[:code] if options.key? :code
194
+ self.redirect_uri = options[:redirect_uri] if options.key? :redirect_uri
195
+ self.username = options[:username] if options.key? :username
196
+ self.password = options[:password] if options.key? :password
197
+ self.issuer = options[:issuer] if options.key? :issuer
198
+ self.person = options[:person] if options.key? :person
199
+ self.sub = options[:sub] if options.key? :sub
190
200
  self.expiry = options[:expiry] || 60
191
- self.audience = options[:audience] if options.has_key?(:audience)
192
- self.signing_key = options[:signing_key] if options.has_key?(:signing_key)
201
+ self.audience = options[:audience] if options.key? :audience
202
+ self.signing_key = options[:signing_key] if options.key? :signing_key
193
203
  self.extension_parameters = options[:extension_parameters] || {}
194
204
  self.additional_parameters = options[:additional_parameters] || {}
195
205
  self.access_type = options.fetch(:access_type) { :offline }
196
- self.update_token!(options)
197
- return self
206
+ update_token! options
207
+ self
198
208
  end
209
+ # rubocop:enable Metrics/AbcSize
210
+ # rubocop:enable Metrics/CyclomaticComplexity
211
+ # rubocop:enable Metrics/PerceivedComplexity
199
212
 
200
213
  ##
201
214
  # Updates an OAuth 2.0 client.
@@ -225,29 +238,33 @@ module Signet
225
238
  #
226
239
  # @see Signet::OAuth2::Client#initialize
227
240
  # @see Signet::OAuth2::Client#update!
228
- def update_token!(options={})
241
+ def update_token! options = {}
229
242
  # Normalize all keys to symbols to allow indifferent access internally
230
- options = deep_hash_normalize(options)
243
+ options = deep_hash_normalize options
231
244
 
232
- self.expires_in = options[:expires] if options.has_key?(:expires)
233
- self.expires_in = options[:expires_in] if options.has_key?(:expires_in)
234
- self.expires_at = options[:expires_at] if options.has_key?(:expires_at)
245
+ self.expires_in = options[:expires] if options.key? :expires
246
+ self.expires_in = options[:expires_in] if options.key? :expires_in
247
+ self.expires_at = options[:expires_at] if options.key? :expires_at
235
248
 
236
249
  # By default, the token is issued at `Time.now` when `expires_in` is
237
250
  # set, but this can be used to supply a more precise time.
238
- self.issued_at = options[:issued_at] if options.has_key?(:issued_at)
251
+ self.issued_at = options[:issued_at] if options.key? :issued_at
239
252
 
240
253
  # Special case where we want expires_at to be relative to issued_at
241
- if options.has_key?(:issued_at) && options.has_key?(:expires_in)
254
+ if options.key?(:issued_at) && options.key?(:expires_in)
242
255
  set_relative_expires_at options[:issued_at], options[:expires_in]
243
256
  end
244
257
 
245
- self.access_token = options[:access_token] if options.has_key?(:access_token)
246
- self.refresh_token = options[:refresh_token] if options.has_key?(:refresh_token)
247
- self.id_token = options[:id_token] if options.has_key?(:id_token)
258
+ self.access_token = options[:access_token] if options.key? :access_token
259
+ self.refresh_token = options[:refresh_token] if options.key? :refresh_token
260
+ self.id_token = options[:id_token] if options.key? :id_token
248
261
 
249
- return self
262
+ self
250
263
  end
264
+ # rubocop:disable Metrics/AbcSize
265
+ # rubocop:disable Metrics/CyclomaticComplexity
266
+ # rubocop:disable Metrics/MethodLength
267
+ # rubocop:disable Metrics/PerceivedComplexity
251
268
 
252
269
  ##
253
270
  # Returns the authorization URI that the user should be redirected to.
@@ -255,34 +272,24 @@ module Signet
255
272
  # @return [Addressable::URI] The authorization URI.
256
273
  #
257
274
  # @see Signet::OAuth2.generate_authorization_uri
258
- def authorization_uri(options={})
275
+ def authorization_uri options = {}
259
276
  # Normalize external input
260
- options = deep_hash_normalize(options)
277
+ options = deep_hash_normalize options
261
278
 
262
- return nil if @authorization_uri == nil
263
- unless options[:response_type]
264
- options[:response_type] = :code
265
- end
266
- if !options[:access_type] && access_type
267
- options[:access_type] = access_type
268
- end
269
- options[:client_id] ||= self.client_id
270
- options[:redirect_uri] ||= self.redirect_uri
279
+ return nil if @authorization_uri.nil?
280
+ options[:response_type] = :code unless options[:response_type]
281
+ options[:access_type] = access_type if !options[:access_type] && access_type
282
+ options[:client_id] ||= client_id
283
+ options[:redirect_uri] ||= redirect_uri
271
284
  if options[:prompt] && options[:approval_prompt]
272
285
  raise ArgumentError, "prompt and approval_prompt are mutually exclusive parameters"
273
286
  end
274
- if !options[:client_id]
275
- raise ArgumentError, "Missing required client identifier."
276
- end
277
- unless options[:redirect_uri]
278
- raise ArgumentError, "Missing required redirect URI."
279
- end
280
- if !options[:scope] && self.scope
281
- options[:scope] = self.scope.join(' ')
282
- end
283
- options[:state] = self.state unless options[:state]
284
- options.merge!(self.additional_parameters.merge(options[:additional_parameters] || {}))
285
- options.delete(:additional_parameters)
287
+ raise ArgumentError, "Missing required client identifier." unless options[:client_id]
288
+ raise ArgumentError, "Missing required redirect URI." unless options[:redirect_uri]
289
+ options[:scope] = scope.join " " if !options[:scope] && scope
290
+ options[:state] = state unless options[:state]
291
+ options.merge!(additional_parameters.merge(options[:additional_parameters] || {}))
292
+ options.delete :additional_parameters
286
293
  options = Hash[options.map do |key, option|
287
294
  [key.to_s, option]
288
295
  end]
@@ -291,20 +298,24 @@ module Signet
291
298
  @authorization_uri, options
292
299
  )
293
300
  )
294
- if uri.normalized_scheme != 'https'
301
+ if uri.normalized_scheme != "https"
295
302
  raise Signet::UnsafeOperationError,
296
- 'Authorization endpoint must be protected by TLS.'
303
+ "Authorization endpoint must be protected by TLS."
297
304
  end
298
- return uri
305
+ uri
299
306
  end
307
+ # rubocop:enable Metrics/AbcSize
308
+ # rubocop:enable Metrics/CyclomaticComplexity
309
+ # rubocop:enable Metrics/MethodLength
310
+ # rubocop:enable Metrics/PerceivedComplexity
300
311
 
301
312
  ##
302
313
  # Sets the authorization URI for this client.
303
314
  #
304
315
  # @param [Addressable::URI, Hash, String, #to_str] new_authorization_uri
305
316
  # The authorization URI.
306
- def authorization_uri=(new_authorization_uri)
307
- @authorization_uri = coerce_uri(new_authorization_uri)
317
+ def authorization_uri= new_authorization_uri
318
+ @authorization_uri = coerce_uri new_authorization_uri
308
319
  end
309
320
 
310
321
  ##
@@ -312,7 +323,7 @@ module Signet
312
323
  #
313
324
  # @return [Addressable::URI] The token credential URI.
314
325
  def token_credential_uri
315
- return @token_credential_uri
326
+ @token_credential_uri
316
327
  end
317
328
 
318
329
  ##
@@ -320,17 +331,17 @@ module Signet
320
331
  #
321
332
  # @param [Addressable::URI, Hash, String, #to_str] new_token_credential_uri
322
333
  # The token credential URI.
323
- def token_credential_uri=(new_token_credential_uri)
324
- @token_credential_uri = coerce_uri(new_token_credential_uri)
334
+ def token_credential_uri= new_token_credential_uri
335
+ @token_credential_uri = coerce_uri new_token_credential_uri
325
336
  end
326
337
 
327
338
  # Addressable expects URIs formatted as hashes to come in with symbols as keys.
328
339
  # Returns nil implicitly for the nil case.
329
- def coerce_uri(incoming_uri)
340
+ def coerce_uri incoming_uri
330
341
  if incoming_uri.is_a? Hash
331
- Addressable::URI.new(deep_hash_normalize(incoming_uri))
342
+ Addressable::URI.new deep_hash_normalize(incoming_uri)
332
343
  elsif incoming_uri
333
- Addressable::URI.parse(incoming_uri)
344
+ Addressable::URI.parse incoming_uri
334
345
  end
335
346
  end
336
347
 
@@ -339,7 +350,7 @@ module Signet
339
350
  #
340
351
  # @return [String, Symbol] The current access type.
341
352
  def access_type
342
- return @access_type
353
+ @access_type
343
354
  end
344
355
 
345
356
  ##
@@ -347,7 +358,7 @@ module Signet
347
358
  #
348
359
  # @param [String, Symbol] new_access_type
349
360
  # The current access type.
350
- def access_type=(new_access_type)
361
+ def access_type= new_access_type
351
362
  @access_type = new_access_type
352
363
  end
353
364
 
@@ -356,7 +367,7 @@ module Signet
356
367
  #
357
368
  # @return [String] The client identifier.
358
369
  def client_id
359
- return @client_id
370
+ @client_id
360
371
  end
361
372
 
362
373
  ##
@@ -364,7 +375,7 @@ module Signet
364
375
  #
365
376
  # @param [String] new_client_id
366
377
  # The client identifier.
367
- def client_id=(new_client_id)
378
+ def client_id= new_client_id
368
379
  @client_id = new_client_id
369
380
  end
370
381
 
@@ -373,7 +384,7 @@ module Signet
373
384
  #
374
385
  # @return [String] The client secret.
375
386
  def client_secret
376
- return @client_secret
387
+ @client_secret
377
388
  end
378
389
 
379
390
  ##
@@ -381,7 +392,7 @@ module Signet
381
392
  #
382
393
  # @param [String] new_client_secret
383
394
  # The client secret.
384
- def client_secret=(new_client_secret)
395
+ def client_secret= new_client_secret
385
396
  @client_secret = new_client_secret
386
397
  end
387
398
 
@@ -391,7 +402,7 @@ module Signet
391
402
  #
392
403
  # @return [Array] The scope of access the client is requesting.
393
404
  def scope
394
- return @scope
405
+ @scope
395
406
  end
396
407
 
397
408
  ##
@@ -401,18 +412,18 @@ module Signet
401
412
  # The scope of access the client is requesting. This may be
402
413
  # expressed as either an Array of String objects or as a
403
414
  # space-delimited String.
404
- def scope=(new_scope)
415
+ def scope= new_scope
405
416
  case new_scope
406
417
  when Array
407
418
  new_scope.each do |scope|
408
- if scope.include?(' ')
419
+ if scope.include? " "
409
420
  raise ArgumentError,
410
- "Individual scopes cannot contain the space character."
421
+ "Individual scopes cannot contain the space character."
411
422
  end
412
423
  end
413
424
  @scope = new_scope
414
425
  when String
415
- @scope = new_scope.split(' ')
426
+ @scope = new_scope.split " "
416
427
  when nil
417
428
  @scope = nil
418
429
  else
@@ -420,12 +431,28 @@ module Signet
420
431
  end
421
432
  end
422
433
 
434
+ ##
435
+ # Returns the final target audience for ID tokens fetched by this client.
436
+ #
437
+ # @return [String] The target audience.
438
+ def target_audience
439
+ @target_audience
440
+ end
441
+
442
+ ##
443
+ # Sets the final target audience for ID tokens fetched by this client.
444
+ #
445
+ # @param [String] new_target_audience The new target audience.
446
+ def target_audience= new_target_audience
447
+ @target_audience = new_target_audience
448
+ end
449
+
423
450
  ##
424
451
  # Returns the client's current state value.
425
452
  #
426
453
  # @return [String] The state value.
427
454
  def state
428
- return @state
455
+ @state
429
456
  end
430
457
 
431
458
  ##
@@ -433,7 +460,7 @@ module Signet
433
460
  #
434
461
  # @param [String] new_state
435
462
  # The state value.
436
- def state=(new_state)
463
+ def state= new_state
437
464
  @state = new_state
438
465
  end
439
466
 
@@ -443,7 +470,7 @@ module Signet
443
470
  #
444
471
  # @return [String] The authorization code.
445
472
  def code
446
- return @code
473
+ @code
447
474
  end
448
475
 
449
476
  ##
@@ -452,7 +479,7 @@ module Signet
452
479
  #
453
480
  # @param [String] new_code
454
481
  # The authorization code.
455
- def code=(new_code)
482
+ def code= new_code
456
483
  @code = new_code
457
484
  end
458
485
 
@@ -461,7 +488,7 @@ module Signet
461
488
  #
462
489
  # @return [String] The redirect URI.
463
490
  def redirect_uri
464
- return @redirect_uri
491
+ @redirect_uri
465
492
  end
466
493
 
467
494
  ##
@@ -469,14 +496,14 @@ module Signet
469
496
  #
470
497
  # @param [String] new_redirect_uri
471
498
  # The redirect URI.
472
- def redirect_uri=(new_redirect_uri)
473
- new_redirect_uri = Addressable::URI.parse(new_redirect_uri)
474
- #TODO - Better solution to allow google postmessage flow. For now, make an exception to the spec.
475
- if new_redirect_uri == nil|| new_redirect_uri.absolute? || uri_is_postmessage?(new_redirect_uri) || uri_is_oob?(new_redirect_uri)
476
- @redirect_uri = new_redirect_uri
477
- else
499
+ def redirect_uri= new_redirect_uri
500
+ new_redirect_uri = Addressable::URI.parse new_redirect_uri
501
+ # TODO: - Better solution to allow google postmessage flow. For now, make an exception to the spec.
502
+ unless new_redirect_uri.nil? || new_redirect_uri.absolute? || uri_is_postmessage?(new_redirect_uri) ||
503
+ uri_is_oob?(new_redirect_uri)
478
504
  raise ArgumentError, "Redirect URI must be an absolute URI."
479
505
  end
506
+ @redirect_uri = new_redirect_uri
480
507
  end
481
508
 
482
509
  ##
@@ -485,7 +512,7 @@ module Signet
485
512
  #
486
513
  # @return [String] The username.
487
514
  def username
488
- return @username
515
+ @username
489
516
  end
490
517
 
491
518
  ##
@@ -494,7 +521,7 @@ module Signet
494
521
  #
495
522
  # @param [String] new_username
496
523
  # The username.
497
- def username=(new_username)
524
+ def username= new_username
498
525
  @username = new_username
499
526
  end
500
527
 
@@ -504,7 +531,7 @@ module Signet
504
531
  #
505
532
  # @return [String] The password.
506
533
  def password
507
- return @password
534
+ @password
508
535
  end
509
536
 
510
537
  ##
@@ -513,7 +540,7 @@ module Signet
513
540
  #
514
541
  # @param [String] new_password
515
542
  # The password.
516
- def password=(new_password)
543
+ def password= new_password
517
544
  @password = new_password
518
545
  end
519
546
 
@@ -523,7 +550,7 @@ module Signet
523
550
  #
524
551
  # @return [String] Issuer id.
525
552
  def issuer
526
- return @issuer
553
+ @issuer
527
554
  end
528
555
 
529
556
  ##
@@ -532,17 +559,17 @@ module Signet
532
559
  #
533
560
  # @param [String] new_issuer
534
561
  # Issuer ID (typical in email adddress form).
535
- def issuer=(new_issuer)
562
+ def issuer= new_issuer
536
563
  @issuer = new_issuer
537
564
  end
538
565
 
539
566
  ##
540
- # Returns the issuer ID associated with this client.
567
+ # Returns the target audience ID when issuing assertions.
541
568
  # Used only by the assertion grant type.
542
569
  #
543
570
  # @return [String] Target audience ID.
544
571
  def audience
545
- return @audience
572
+ @audience
546
573
  end
547
574
 
548
575
  ##
@@ -551,7 +578,7 @@ module Signet
551
578
  #
552
579
  # @param [String] new_audience
553
580
  # Target audience ID
554
- def audience=(new_audience)
581
+ def audience= new_audience
555
582
  @audience = new_audience
556
583
  end
557
584
 
@@ -561,7 +588,7 @@ module Signet
561
588
  #
562
589
  # @return [String] Target user for impersonation.
563
590
  def principal
564
- return @principal
591
+ @principal
565
592
  end
566
593
 
567
594
  ##
@@ -570,12 +597,12 @@ module Signet
570
597
  #
571
598
  # @param [String] new_person
572
599
  # Target user for impersonation
573
- def principal=(new_person)
600
+ def principal= new_person
574
601
  @principal = new_person
575
602
  end
576
603
 
577
- alias_method :person, :principal
578
- alias_method :person=, :principal=
604
+ alias person principal
605
+ alias person= principal=
579
606
 
580
607
  ##
581
608
  # The target "sub" when issuing assertions.
@@ -589,7 +616,7 @@ module Signet
589
616
  #
590
617
  # @return [Integer] Assertion expiry, in seconds
591
618
  def expiry
592
- return @expiry
619
+ @expiry
593
620
  end
594
621
 
595
622
  ##
@@ -598,18 +625,17 @@ module Signet
598
625
  #
599
626
  # @param [Integer, String] new_expiry
600
627
  # Assertion expiry, in seconds
601
- def expiry=(new_expiry)
628
+ def expiry= new_expiry
602
629
  @expiry = new_expiry ? new_expiry.to_i : nil
603
630
  end
604
631
 
605
-
606
632
  ##
607
633
  # Returns the signing key associated with this client.
608
634
  # Used only by the assertion grant type.
609
635
  #
610
636
  # @return [String,OpenSSL::PKey] Signing key
611
637
  def signing_key
612
- return @signing_key
638
+ @signing_key
613
639
  end
614
640
 
615
641
  ##
@@ -618,7 +644,7 @@ module Signet
618
644
  #
619
645
  # @param [String, OpenSSL::Pkey] new_key
620
646
  # Signing key. Either private key for RSA or string for HMAC algorithm
621
- def signing_key=(new_key)
647
+ def signing_key= new_key
622
648
  @signing_key = new_key
623
649
  end
624
650
 
@@ -626,7 +652,7 @@ module Signet
626
652
  # Algorithm used for signing JWTs
627
653
  # @return [String] Signing algorithm
628
654
  def signing_algorithm
629
- self.signing_key.is_a?(String) ? "HS256" : "RS256"
655
+ signing_key.is_a?(String) ? "HS256" : "RS256"
630
656
  end
631
657
 
632
658
  ##
@@ -635,7 +661,7 @@ module Signet
635
661
  #
636
662
  # @return [Hash] The extension parameters.
637
663
  def extension_parameters
638
- return @extension_parameters ||= {}
664
+ @extension_parameters ||= {}
639
665
  end
640
666
 
641
667
  ##
@@ -644,12 +670,12 @@ module Signet
644
670
  #
645
671
  # @param [Hash] new_extension_parameters
646
672
  # The parameters.
647
- def extension_parameters=(new_extension_parameters)
648
- if new_extension_parameters.respond_to?(:to_hash)
673
+ def extension_parameters= new_extension_parameters
674
+ if new_extension_parameters.respond_to? :to_hash
649
675
  @extension_parameters = new_extension_parameters.to_hash
650
676
  else
651
677
  raise TypeError,
652
- "Expected Hash, got #{new_extension_parameters.class}."
678
+ "Expected Hash, got #{new_extension_parameters.class}."
653
679
  end
654
680
  end
655
681
 
@@ -658,7 +684,7 @@ module Signet
658
684
  #
659
685
  # @return [Hash] The pass through parameters.
660
686
  def additional_parameters
661
- return @additional_parameters ||= {}
687
+ @additional_parameters ||= {}
662
688
  end
663
689
 
664
690
  ##
@@ -666,8 +692,8 @@ module Signet
666
692
  #
667
693
  # @param [Hash] new_additional_parameters
668
694
  # The parameters.
669
- def additional_parameters=(new_additional_parameters)
670
- if new_additional_parameters.respond_to?(:to_hash)
695
+ def additional_parameters= new_additional_parameters
696
+ if new_additional_parameters.respond_to? :to_hash
671
697
  @additional_parameters = new_additional_parameters.to_hash
672
698
  else
673
699
  raise TypeError,
@@ -680,7 +706,7 @@ module Signet
680
706
  #
681
707
  # @return [String] The refresh token.
682
708
  def refresh_token
683
- return @refresh_token ||= nil
709
+ @refresh_token ||= nil
684
710
  end
685
711
 
686
712
  ##
@@ -688,7 +714,7 @@ module Signet
688
714
  #
689
715
  # @param [String] new_refresh_token
690
716
  # The refresh token.
691
- def refresh_token=(new_refresh_token)
717
+ def refresh_token= new_refresh_token
692
718
  @refresh_token = new_refresh_token
693
719
  end
694
720
 
@@ -697,7 +723,7 @@ module Signet
697
723
  #
698
724
  # @return [String] The access token.
699
725
  def access_token
700
- return @access_token ||= nil
726
+ @access_token ||= nil
701
727
  end
702
728
 
703
729
  ##
@@ -705,7 +731,7 @@ module Signet
705
731
  #
706
732
  # @param [String] new_access_token
707
733
  # The access token.
708
- def access_token=(new_access_token)
734
+ def access_token= new_access_token
709
735
  @access_token = new_access_token
710
736
  end
711
737
 
@@ -714,7 +740,7 @@ module Signet
714
740
  #
715
741
  # @return [String] The ID token.
716
742
  def id_token
717
- return @id_token ||= nil
743
+ @id_token ||= nil
718
744
  end
719
745
 
720
746
  ##
@@ -722,7 +748,7 @@ module Signet
722
748
  #
723
749
  # @param [String] new_id_token
724
750
  # The ID token.
725
- def id_token=(new_id_token)
751
+ def id_token= new_id_token
726
752
  @id_token = new_id_token
727
753
  end
728
754
 
@@ -734,17 +760,16 @@ module Signet
734
760
  # omitted.
735
761
  #
736
762
  # @return [String] The decoded ID token.
737
- def decoded_id_token public_key=nil, options = {}, &keyfinder
763
+ def decoded_id_token public_key = nil, options = {}, &keyfinder
738
764
  options[:algorithm] ||= signing_algorithm
739
- verify = !!(public_key || keyfinder)
740
- payload, _header = JWT.decode(self.id_token, public_key, verify, options, &keyfinder)
741
- if !payload.has_key?('aud')
742
- raise Signet::UnsafeOperationError, 'No ID token audience declared.'
743
- elsif payload['aud'] != self.client_id
765
+ verify = !public_key.nil? || block_given?
766
+ payload, _header = JWT.decode(id_token, public_key, verify, options, &keyfinder)
767
+ raise Signet::UnsafeOperationError, "No ID token audience declared." unless payload.key? "aud"
768
+ unless Array(payload["aud"]).include?(client_id)
744
769
  raise Signet::UnsafeOperationError,
745
- 'ID token audience did not match Client ID.'
770
+ "ID token audience did not match Client ID."
746
771
  end
747
- return payload
772
+ payload
748
773
  end
749
774
 
750
775
  ##
@@ -790,8 +815,8 @@ module Signet
790
815
  #
791
816
  # @param [String,Integer,Time] new_issued_at
792
817
  # The access token issuance time.
793
- def issued_at=(new_issued_at)
794
- @issued_at = normalize_timestamp(new_issued_at)
818
+ def issued_at= new_issued_at
819
+ @issued_at = normalize_timestamp new_issued_at
795
820
  end
796
821
 
797
822
  ##
@@ -809,7 +834,7 @@ module Signet
809
834
  # not expire.
810
835
  # @param [String,Integer,Time, nil] new_expires_at
811
836
  # The access token expiration time.
812
- def expires_at=(new_expires_at)
837
+ def expires_at= new_expires_at
813
838
  @expires_at = normalize_timestamp new_expires_at
814
839
  end
815
840
 
@@ -820,7 +845,7 @@ module Signet
820
845
  # @return [TrueClass, FalseClass]
821
846
  # The expiration state of the access token.
822
847
  def expired?
823
- return self.expires_at != nil && Time.now >= self.expires_at
848
+ !expires_at.nil? && Time.now >= expires_at
824
849
  end
825
850
 
826
851
  ##
@@ -832,8 +857,8 @@ module Signet
832
857
  # expired.
833
858
  # @return [TrueClass, FalseClass]
834
859
  # The expiration state of the access token.
835
- def expires_within?(sec)
836
- return self.expires_at != nil && Time.now >= (self.expires_at - sec)
860
+ def expires_within? sec
861
+ !expires_at.nil? && Time.now >= (expires_at - sec)
837
862
  end
838
863
 
839
864
  ##
@@ -849,7 +874,6 @@ module Signet
849
874
  @expires_at = nil
850
875
  end
851
876
 
852
-
853
877
  ##
854
878
  # Returns the inferred grant type, based on the current state of the
855
879
  # client object. Returns `"none"` if the client has insufficient
@@ -859,52 +883,47 @@ module Signet
859
883
  # The inferred grant type.
860
884
  def grant_type
861
885
  @grant_type ||= nil
862
- if @grant_type
863
- return @grant_type
864
- else
865
- if self.code && self.redirect_uri
866
- 'authorization_code'
867
- elsif self.refresh_token
868
- 'refresh_token'
869
- elsif self.username && self.password
870
- 'password'
871
- elsif self.issuer && self.signing_key
872
- 'urn:ietf:params:oauth:grant-type:jwt-bearer'
873
- else
874
- # We don't have sufficient auth information, assume an out-of-band
875
- # authorization arrangement between the client and server, or an
876
- # extension grant type.
877
- nil
878
- end
886
+ return @grant_type if @grant_type
887
+ if code && redirect_uri
888
+ "authorization_code"
889
+ elsif refresh_token
890
+ "refresh_token"
891
+ elsif username && password
892
+ "password"
893
+ elsif issuer && signing_key
894
+ "urn:ietf:params:oauth:grant-type:jwt-bearer"
879
895
  end
880
896
  end
881
897
 
882
- def grant_type=(new_grant_type)
898
+ def grant_type= new_grant_type
883
899
  case new_grant_type
884
- when 'authorization_code', 'refresh_token',
885
- 'password', 'client_credentials'
900
+ when "authorization_code", "refresh_token",
901
+ "password", "client_credentials"
886
902
  @grant_type = new_grant_type
887
903
  else
888
- @grant_type = Addressable::URI.parse(new_grant_type)
904
+ @grant_type = Addressable::URI.parse new_grant_type
889
905
  end
890
906
  end
891
907
 
892
- def to_jwt(options={})
893
- options = deep_hash_normalize(options)
908
+ def to_jwt options = {}
909
+ options = deep_hash_normalize options
894
910
 
895
911
  now = Time.new
896
912
  skew = options[:skew] || 60
897
913
  assertion = {
898
- "iss" => self.issuer,
899
- "aud" => self.audience,
900
- "exp" => (now + self.expiry).to_i,
914
+ "iss" => issuer,
915
+ "aud" => audience,
916
+ "exp" => (now + expiry).to_i,
901
917
  "iat" => (now - skew).to_i
902
918
  }
903
- assertion['scope'] = self.scope.join(' ') unless self.scope.nil?
904
- assertion['prn'] = self.person unless self.person.nil?
905
- assertion['sub'] = self.sub unless self.sub.nil?
906
- JWT.encode(assertion, self.signing_key, self.signing_algorithm)
919
+ assertion["scope"] = scope.join " " unless scope.nil?
920
+ assertion["target_audience"] = target_audience unless target_audience.nil?
921
+ assertion["prn"] = person unless person.nil?
922
+ assertion["sub"] = sub unless sub.nil?
923
+ JWT.encode assertion, signing_key, signing_algorithm
907
924
  end
925
+ # rubocop:disable Style/MethodDefParentheses
926
+ # rubocop:disable Metrics/AbcSize
908
927
 
909
928
  ##
910
929
  # Serialize the client object to JSON.
@@ -913,29 +932,34 @@ module Signet
913
932
  #
914
933
  # @return [String] A serialized JSON representation of the client.
915
934
  def to_json(*)
916
- return MultiJson.dump({
917
- 'authorization_uri' => self.authorization_uri ? self.authorization_uri.to_s : nil,
918
- 'token_credential_uri' => self.token_credential_uri ? self.token_credential_uri.to_s : nil,
919
- 'client_id' => self.client_id,
920
- 'client_secret' => self.client_secret,
921
- 'scope' => self.scope,
922
- 'state' => self.state,
923
- 'code' => self.code,
924
- 'redirect_uri' => self.redirect_uri ? self.redirect_uri.to_s : nil,
925
- 'username' => self.username,
926
- 'password' => self.password,
927
- 'issuer' => self.issuer,
928
- 'audience' => self.audience,
929
- 'person' => self.person,
930
- 'expiry' => self.expiry,
931
- 'expires_at' => self.expires_at ? self.expires_at.to_i : nil,
932
- 'signing_key' => self.signing_key,
933
- 'refresh_token' => self.refresh_token,
934
- 'access_token' => self.access_token,
935
- 'id_token' => self.id_token,
936
- 'extension_parameters' => self.extension_parameters
937
- })
935
+ MultiJson.dump(
936
+ "authorization_uri" => authorization_uri ? authorization_uri.to_s : nil,
937
+ "token_credential_uri" => token_credential_uri ? token_credential_uri.to_s : nil,
938
+ "client_id" => client_id,
939
+ "client_secret" => client_secret,
940
+ "scope" => scope,
941
+ "target_audience" => target_audience,
942
+ "state" => state,
943
+ "code" => code,
944
+ "redirect_uri" => redirect_uri ? redirect_uri.to_s : nil,
945
+ "username" => username,
946
+ "password" => password,
947
+ "issuer" => issuer,
948
+ "audience" => audience,
949
+ "person" => person,
950
+ "expiry" => expiry,
951
+ "expires_at" => expires_at ? expires_at.to_i : nil,
952
+ "signing_key" => signing_key,
953
+ "refresh_token" => refresh_token,
954
+ "access_token" => access_token,
955
+ "id_token" => id_token,
956
+ "extension_parameters" => extension_parameters
957
+ )
938
958
  end
959
+ # rubocop:enable Style/MethodDefParentheses
960
+ # rubocop:disable Metrics/CyclomaticComplexity
961
+ # rubocop:disable Metrics/MethodLength
962
+ # rubocop:disable Metrics/PerceivedComplexity
939
963
 
940
964
  ##
941
965
  # Generates a request for token credentials.
@@ -947,58 +971,58 @@ module Signet
947
971
  #
948
972
  # @private
949
973
  # @return [Array] The request object.
950
- def generate_access_token_request(options={})
951
- options = deep_hash_normalize(options)
952
-
953
- parameters = {"grant_type" => self.grant_type}
954
- case self.grant_type
955
- when 'authorization_code'
956
- parameters['code'] = self.code
957
- parameters['redirect_uri'] = self.redirect_uri
958
- when 'password'
959
- parameters['username'] = self.username
960
- parameters['password'] = self.password
961
- when 'refresh_token'
962
- parameters['refresh_token'] = self.refresh_token
963
- when 'urn:ietf:params:oauth:grant-type:jwt-bearer'
964
- parameters['assertion'] = self.to_jwt(options)
974
+ def generate_access_token_request options = {}
975
+ options = deep_hash_normalize options
976
+
977
+ parameters = { "grant_type" => grant_type }
978
+ case grant_type
979
+ when "authorization_code"
980
+ parameters["code"] = code
981
+ parameters["redirect_uri"] = redirect_uri
982
+ when "password"
983
+ parameters["username"] = username
984
+ parameters["password"] = password
985
+ when "refresh_token"
986
+ parameters["refresh_token"] = refresh_token
987
+ when "urn:ietf:params:oauth:grant-type:jwt-bearer"
988
+ parameters["assertion"] = to_jwt options
965
989
  else
966
- if self.redirect_uri
990
+ if redirect_uri
967
991
  # Grant type was intended to be `authorization_code` because of
968
992
  # the presence of the redirect URI.
969
- raise ArgumentError, 'Missing authorization code.'
993
+ raise ArgumentError, "Missing authorization code."
970
994
  end
971
- parameters.merge!(self.extension_parameters)
995
+ parameters.merge! extension_parameters
972
996
  end
973
- parameters['client_id'] = self.client_id unless self.client_id.nil?
974
- parameters['client_secret'] = self.client_secret unless self.client_secret.nil?
997
+ parameters["client_id"] = client_id unless client_id.nil?
998
+ parameters["client_secret"] = client_secret unless client_secret.nil?
975
999
  if options[:scope]
976
- parameters['scope'] = options[:scope]
977
- elsif options[:use_configured_scope] && !self.scope.nil?
978
- parameters['scope'] = self.scope
1000
+ parameters["scope"] = options[:scope]
1001
+ elsif options[:use_configured_scope] && !scope.nil?
1002
+ parameters["scope"] = scope
979
1003
  end
980
- additional = self.additional_parameters.merge(options[:additional_parameters] || {})
1004
+ additional = additional_parameters.merge(options[:additional_parameters] || {})
981
1005
  additional.each { |k, v| parameters[k.to_s] = v }
982
1006
  parameters
983
1007
  end
1008
+ # rubocop:enable Metrics/CyclomaticComplexity
1009
+ # rubocop:enable Metrics/PerceivedComplexity
984
1010
 
985
- def fetch_access_token(options={})
986
- if self.token_credential_uri.nil?
987
- raise ArgumentError, 'Missing token endpoint URI.'
988
- end
1011
+ def fetch_access_token options = {}
1012
+ raise ArgumentError, "Missing token endpoint URI." if token_credential_uri.nil?
989
1013
 
990
- options = deep_hash_normalize(options)
1014
+ options = deep_hash_normalize options
991
1015
 
992
1016
  client = options[:connection] ||= Faraday.default_connection
993
- url = Addressable::URI.parse(self.token_credential_uri).normalize.to_s
994
- parameters = self.generate_access_token_request(options)
995
- if client.is_a?(Faraday::Connection)
1017
+ url = Addressable::URI.parse(token_credential_uri).normalize.to_s
1018
+ parameters = generate_access_token_request options
1019
+ if client.is_a? Faraday::Connection
996
1020
  response = client.post url,
997
- Addressable::URI.form_encode(parameters),
998
- { 'Content-Type' => 'application/x-www-form-urlencoded' }
1021
+ Addressable::URI.form_encode(parameters),
1022
+ "Content-Type" => "application/x-www-form-urlencoded"
999
1023
  status = response.status.to_i
1000
1024
  body = response.body
1001
- content_type = response.headers['Content-type']
1025
+ content_type = response.headers["Content-type"]
1002
1026
  else
1003
1027
  # Hurley
1004
1028
  response = client.post url, parameters
@@ -1007,49 +1031,46 @@ module Signet
1007
1031
  content_type = response.header[:content_type]
1008
1032
  end
1009
1033
 
1010
- if status == 200
1011
- return ::Signet::OAuth2.parse_credentials(body, content_type)
1012
- elsif [400, 401, 403].include?(status)
1013
- message = 'Authorization failed.'
1014
- if body.to_s.strip.length > 0
1015
- message += " Server message:\n#{response.body.to_s.strip}"
1016
- end
1034
+ return ::Signet::OAuth2.parse_credentials body, content_type if status == 200
1035
+
1036
+ message = " Server message:\n#{response.body.to_s.strip}" unless body.to_s.strip.empty?
1037
+ if [400, 401, 403].include? status
1038
+ message = "Authorization failed." + message
1017
1039
  raise ::Signet::AuthorizationError.new(
1018
- message, :response => response
1040
+ message, response: response
1019
1041
  )
1020
1042
  elsif status.to_s[0] == "5"
1021
- message = 'Remote server error.'
1022
- if body.to_s.strip.length > 0
1023
- message += " Server message:\n#{response.body.to_s.strip}"
1024
- end
1025
- raise ::Signet::RemoteServerError.new(message)
1043
+ message = "Remote server error." + message
1044
+ raise ::Signet::RemoteServerError, message
1026
1045
  else
1027
- message = "Unexpected status code: #{response.status}."
1028
- if body.to_s.strip.length > 0
1029
- message += " Server message:\n#{response.body.to_s.strip}"
1030
- end
1031
- raise ::Signet::UnexpectedStatusError.new(message)
1046
+ message = "Unexpected status code: #{response.status}." + message
1047
+ raise ::Signet::UnexpectedStatusError, message
1032
1048
  end
1033
1049
  end
1050
+ # rubocop:enable Metrics/AbcSize
1051
+ # rubocop:enable Metrics/MethodLength
1034
1052
 
1035
- def fetch_access_token!(options={})
1036
- token_hash = self.fetch_access_token(options)
1053
+ def fetch_access_token! options = {}
1054
+ token_hash = fetch_access_token options
1037
1055
  if token_hash
1038
1056
  # No-op for grant types other than `authorization_code`.
1039
1057
  # An authorization code is a one-time use token and is immediately
1040
1058
  # revoked after usage.
1041
1059
  self.code = nil
1042
1060
  self.issued_at = Time.now
1043
- self.update_token!(token_hash)
1061
+ update_token! token_hash
1044
1062
  end
1045
- return token_hash
1063
+ token_hash
1046
1064
  end
1047
1065
 
1048
1066
  ##
1049
1067
  # Refresh the access token, if possible
1050
- def refresh!(options={})
1051
- self.fetch_access_token!(options)
1068
+ def refresh! options = {}
1069
+ fetch_access_token! options
1052
1070
  end
1071
+ # rubocop:disable Metrics/AbcSize
1072
+ # rubocop:disable Metrics/MethodLength
1073
+ # rubocop:disable Metrics/PerceivedComplexity
1053
1074
 
1054
1075
  ##
1055
1076
  # Generates an authenticated request for protected resources.
@@ -1071,55 +1092,54 @@ module Signet
1071
1092
  # - <code>:realm</code> -
1072
1093
  # The Authorization realm. See RFC 2617.
1073
1094
  # @return [Faraday::Request] The request object.
1074
- def generate_authenticated_request(options={})
1075
- options = deep_hash_normalize(options)
1095
+ def generate_authenticated_request options = {}
1096
+ options = deep_hash_normalize options
1076
1097
 
1077
- if self.access_token == nil
1078
- raise ArgumentError, 'Missing access token.'
1079
- end
1098
+ raise ArgumentError, "Missing access token." if access_token.nil?
1080
1099
  options = {
1081
- :realm => nil
1100
+ realm: nil
1082
1101
  }.merge(options)
1083
1102
 
1084
- if options[:request].kind_of?(Faraday::Request)
1103
+ if options[:request].is_a? Faraday::Request
1085
1104
  request = options[:request]
1086
1105
  else
1087
- if options[:request].kind_of?(Array)
1106
+ if options[:request].is_a? Array
1088
1107
  method, uri, headers, body = options[:request]
1089
1108
  else
1090
1109
  method = options[:method] || :get
1091
1110
  uri = options[:uri]
1092
1111
  headers = options[:headers] || []
1093
- body = options[:body] || ''
1112
+ body = options[:body] || ""
1094
1113
  end
1095
- headers = headers.to_a if headers.kind_of?(Hash)
1114
+ headers = headers.to_a if headers.is_a? Hash
1096
1115
  request_components = {
1097
- :method => method,
1098
- :uri => uri,
1099
- :headers => headers,
1100
- :body => body
1116
+ method: method,
1117
+ uri: uri,
1118
+ headers: headers,
1119
+ body: body
1101
1120
  }
1102
1121
  # Verify that we have all pieces required to return an HTTP request
1103
1122
  request_components.each do |(key, value)|
1104
- unless value
1105
- raise ArgumentError, "Missing :#{key} parameter."
1106
- end
1123
+ raise ArgumentError, "Missing :#{key} parameter." unless value
1107
1124
  end
1108
1125
  method = method.to_s.downcase.to_sym
1109
- request = options[:connection].build_request(method.to_s.downcase.to_sym) do |req|
1110
- req.url(Addressable::URI.parse(uri).normalize.to_s)
1111
- req.headers = Faraday::Utils::Headers.new(headers)
1126
+ request = options[:connection].build_request method.to_s.downcase.to_sym do |req|
1127
+ req.url Addressable::URI.parse(uri).normalize.to_s
1128
+ req.headers = Faraday::Utils::Headers.new headers
1112
1129
  req.body = body
1113
1130
  end
1114
1131
  end
1115
1132
 
1116
- request['Authorization'] = ::Signet::OAuth2.generate_bearer_authorization_header(
1117
- self.access_token,
1118
- options[:realm] ? [['realm', options[:realm]]] : nil
1133
+ request["Authorization"] = ::Signet::OAuth2.generate_bearer_authorization_header(
1134
+ access_token,
1135
+ options[:realm] ? [["realm", options[:realm]]] : nil
1119
1136
  )
1120
- request['Cache-Control'] = 'no-store'
1121
- return request
1137
+ request["Cache-Control"] = "no-store"
1138
+ request
1122
1139
  end
1140
+ # rubocop:enable Metrics/AbcSize
1141
+ # rubocop:enable Metrics/MethodLength
1142
+ # rubocop:enable Metrics/PerceivedComplexity
1123
1143
 
1124
1144
  ##
1125
1145
  # Transmits a request for a protected resource.
@@ -1151,27 +1171,22 @@ module Signet
1151
1171
  # )
1152
1172
  #
1153
1173
  # @return [Array] The response object.
1154
- def fetch_protected_resource(options={})
1155
- options = deep_hash_normalize(options)
1174
+ def fetch_protected_resource options = {}
1175
+ options = deep_hash_normalize options
1156
1176
 
1157
1177
  options[:connection] ||= Faraday.default_connection
1158
- request = self.generate_authenticated_request(options)
1159
- request_env = request.to_env(options[:connection])
1178
+ request = generate_authenticated_request options
1179
+ request_env = request.to_env options[:connection]
1160
1180
  request_env[:request] ||= request
1161
- response = options[:connection].app.call(request_env)
1162
- if response.status.to_i == 401
1163
- # When accessing a protected resource, we only want to raise an
1164
- # error for 401 responses.
1165
- message = 'Authorization failed.'
1166
- if response.body.to_s.strip.length > 0
1167
- message += " Server message:\n#{response.body.to_s.strip}"
1168
- end
1169
- raise ::Signet::AuthorizationError.new(
1170
- message, :request => request, :response => response
1171
- )
1172
- else
1173
- return response
1174
- end
1181
+ response = options[:connection].app.call request_env
1182
+ return response unless response.status.to_i == 401
1183
+ # When accessing a protected resource, we only want to raise an
1184
+ # error for 401 responses.
1185
+ message = "Authorization failed."
1186
+ message += " Server message:\n#{response.body.to_s.strip}" unless response.body.to_s.strip.empty?
1187
+ raise ::Signet::AuthorizationError.new(
1188
+ message, request: request, response: response
1189
+ )
1175
1190
  end
1176
1191
 
1177
1192
  private
@@ -1179,33 +1194,33 @@ module Signet
1179
1194
  ##
1180
1195
  # Check if URI is Google's postmessage flow (not a valid redirect_uri by spec, but allowed)
1181
1196
  # @private
1182
- def uri_is_postmessage?(uri)
1183
- return uri.to_s.casecmp('postmessage') == 0
1197
+ def uri_is_postmessage? uri
1198
+ uri.to_s.casecmp("postmessage").zero?
1184
1199
  end
1185
1200
 
1186
1201
  ##
1187
1202
  # Check if the URI is a out-of-band
1188
1203
  # @private
1189
- def uri_is_oob?(uri)
1190
- return OOB_MODES.include?(uri.to_s)
1204
+ def uri_is_oob? uri
1205
+ OOB_MODES.include? uri.to_s
1191
1206
  end
1192
1207
 
1193
1208
  # Convert all keys in this hash (nested) to symbols for uniform retrieval
1194
- def recursive_hash_normalize_keys(val)
1209
+ def recursive_hash_normalize_keys val
1195
1210
  if val.is_a? Hash
1196
- deep_hash_normalize(val)
1211
+ deep_hash_normalize val
1197
1212
  else
1198
1213
  val
1199
1214
  end
1200
1215
  end
1201
1216
 
1202
- def deep_hash_normalize(old_hash)
1217
+ def deep_hash_normalize old_hash
1203
1218
  sym_hash = {}
1204
- old_hash and old_hash.each {|k,v| sym_hash[k.to_sym] = recursive_hash_normalize_keys(v)}
1219
+ old_hash&.each { |k, v| sym_hash[k.to_sym] = recursive_hash_normalize_keys v }
1205
1220
  sym_hash
1206
1221
  end
1207
1222
 
1208
- def normalize_timestamp(time)
1223
+ def normalize_timestamp time
1209
1224
  case time
1210
1225
  when NilClass
1211
1226
  nil
@@ -1214,15 +1229,15 @@ module Signet
1214
1229
  when DateTime
1215
1230
  time.to_time
1216
1231
  when String
1217
- Time.parse(time)
1232
+ Time.parse time
1218
1233
  when Integer
1219
- Time.at(time)
1234
+ Time.at time
1220
1235
  else
1221
- fail "Invalid time value #{time}"
1236
+ raise "Invalid time value #{time}"
1222
1237
  end
1223
1238
  end
1224
1239
 
1225
- def set_relative_expires_at(issued_at, expires_in)
1240
+ def set_relative_expires_at issued_at, expires_in
1226
1241
  self.issued_at = issued_at
1227
1242
  # Using local expires_in because if self.expires_in is used, it returns
1228
1243
  # the time left before the token expires