signet 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a90553898c900b623be7bcd66492052606823e88
4
- data.tar.gz: 79d812b9a1bf1c00a548b48a5434dd8a3f40cb39
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODJiNTkyYjQ1OGRkNDY2Y2RjNDZiY2U1YjJhNWI3MWFmNmU5OTNiNw==
5
+ data.tar.gz: !binary |-
6
+ MGUyODYzMjdmODI4Y2U4YjE5YTMyYzY2ZDU1ZWE3ZGFlYjZmNjRlMw==
5
7
  SHA512:
6
- metadata.gz: b41031268b8c1e10cea6cc132edcb85954c398927ecd7c364c401fab64930758c47a87d4ffb4b1c196f6c6e9dedd3a2cf893d939910440649f560c39555b0546
7
- data.tar.gz: be0549ccf4f39e5d7d0a67b209884c798bfcec5bda4618a27e6e96579cec21ff54d76f08c64cf606925cf9c04015c72c678f3066b3cfa75daf60648ae8bb6c29
8
+ metadata.gz: !binary |-
9
+ YTIyZGY5MDFjYmM4OWQwOWQzNTBjM2ZmNTNiNjg2ODBlYzAzMTdkOWQ4MWRh
10
+ OGQ4NTcxMjhkMGYxZmQyZGVhZTk5YzI3N2IyN2JmYjM0OTIyYTc2Yzc2ZTAw
11
+ MmRiZDRjZjM2NzFkMjdhYTEyNzQ5YTBlMjljZGU5NDA0YzRjZTc=
12
+ data.tar.gz: !binary |-
13
+ MWY0ZWJhNDg2MWQ1YjlkODQ5ZmQzMzBjNmRjZWVhYjA5N2JkZjU5YjRkMjU2
14
+ ZTBkNzNmZGQ5NDU4YjgyZjMxM2FiODdhZjM3YjE4OWZkYzBhZTk2ZGMxZWM5
15
+ YmE4YzU2YzI2M2E0NGIzZDI5ODMzYWJhMzM5MjkzMmQ5MjM5NTM=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 0.6.0
2
+
3
+ * Drop support for ruby versions < 1.9.3
4
+ * Update gem dependencies and lock down versions tighter
5
+ * Allow form encoded responses when exchanging OAuth 2 authorization codes
6
+ * Normalize options keys for indifferent access
7
+
1
8
  # 0.5.1
2
9
 
3
10
  * Allow Hash objects to be used to initialize authorization URI
data/Gemfile CHANGED
@@ -1,22 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'addressable', '>= 2.3.1'
4
- gem 'faraday', '>= 0.9.0.rc5'
5
- gem 'multi_json', '>= 1.0.0'
6
- gem 'jwt', '>= 0.1.5'
7
- gem 'extlib', '>= 0.9.15'
8
- gem 'jruby-openssl', :platforms => :jruby
9
-
10
- group :development do
11
- gem 'launchy', '>= 2.1.1'
12
- gem 'yard'
13
- gem 'kramdown'
14
- end
3
+ gemspec
15
4
 
16
-
17
- group :test, :development do
18
- gem 'json', '~> 1.7.7'
19
- gem 'rake', '>= 0.9.0'
20
- gem 'rspec', '>= 2.11.0'
21
- gem 'rcov', '>= 0.9.9', :platform => :mri_18
22
- end
5
+ gem 'jruby-openssl', :platforms => :jruby
@@ -153,26 +153,27 @@ module Signet
153
153
  # @see Signet::OAuth2::Client#initialize
154
154
  # @see Signet::OAuth2::Client#update_token!
155
155
  def update!(options={})
156
- # Normalize key to String to allow indifferent access.
157
- options = options.inject({}) { |accu, (k, v)| accu[k.to_s] = v; accu }
158
- self.authorization_uri = options["authorization_uri"] if options.has_key?("authorization_uri")
159
- self.token_credential_uri = options["token_credential_uri"] if options.has_key?("token_credential_uri")
160
- self.client_id = options["client_id"] if options.has_key?("client_id")
161
- self.client_secret = options["client_secret"] if options.has_key?("client_secret")
162
- self.scope = options["scope"] if options.has_key?("scope")
163
- self.state = options["state"] if options.has_key?("state")
164
- self.code = options["code"] if options.has_key?("code")
165
- self.redirect_uri = options["redirect_uri"] if options.has_key?("redirect_uri")
166
- self.username = options["username"] if options.has_key?("username")
167
- self.password = options["password"] if options.has_key?("password")
168
- self.issuer = options["issuer"] if options.has_key?("issuer")
169
- self.person = options["person"] if options.has_key?("person")
170
- self.sub = options["sub"] if options.has_key?("sub")
171
- self.expiry = options["expiry"] || 60
172
- self.audience = options["audience"] if options.has_key?("audience")
173
- self.signing_key = options["signing_key"] if options.has_key?("signing_key")
174
- self.extension_parameters = options["extension_parameters"] || {}
175
- self.additional_parameters = options["additional_parameters"] || {}
156
+ # Normalize all keys to symbols to allow indifferent access.
157
+ options = deep_hash_normalize(options)
158
+
159
+ self.authorization_uri = options[:authorization_uri] if options.has_key?(:authorization_uri)
160
+ self.token_credential_uri = options[:token_credential_uri] if options.has_key?(:token_credential_uri)
161
+ self.client_id = options[:client_id] if options.has_key?(:client_id)
162
+ self.client_secret = options[:client_secret] if options.has_key?(:client_secret)
163
+ self.scope = options[:scope] if options.has_key?(:scope)
164
+ self.state = options[:state] if options.has_key?(:state)
165
+ self.code = options[:code] if options.has_key?(:code)
166
+ self.redirect_uri = options[:redirect_uri] if options.has_key?(:redirect_uri)
167
+ self.username = options[:username] if options.has_key?(:username)
168
+ self.password = options[:password] if options.has_key?(:password)
169
+ self.issuer = options[:issuer] if options.has_key?(:issuer)
170
+ self.person = options[:person] if options.has_key?(:person)
171
+ self.sub = options[:sub] if options.has_key?(:sub)
172
+ self.expiry = options[:expiry] || 60
173
+ self.audience = options[:audience] if options.has_key?(:audience)
174
+ self.signing_key = options[:signing_key] if options.has_key?(:signing_key)
175
+ self.extension_parameters = options[:extension_parameters] || {}
176
+ self.additional_parameters = options[:additional_parameters] || {}
176
177
  self.update_token!(options)
177
178
  return self
178
179
  end
@@ -206,19 +207,20 @@ module Signet
206
207
  # @see Signet::OAuth2::Client#initialize
207
208
  # @see Signet::OAuth2::Client#update!
208
209
  def update_token!(options={})
209
- # Normalize key to String to allow indifferent access.
210
- options = options.inject({}) { |accu, (k, v)| accu[k.to_s] = v; accu }
210
+ # Normalize all keys to symbols to allow indifferent access internally
211
+ options = deep_hash_normalize(options)
211
212
 
212
- self.expires_in = options["expires_in"] if options.has_key?("expires_in")
213
- self.expires_at = options["expires_at"] if options.has_key?("expires_at")
213
+ self.expires_in = options[:expires] if options.has_key?(:expires)
214
+ self.expires_in = options[:expires_in] if options.has_key?(:expires_in)
215
+ self.expires_at = options[:expires_at] if options.has_key?(:expires_at)
214
216
 
215
217
  # By default, the token is issued at `Time.now` when `expires_in` is
216
218
  # set, but this can be used to supply a more precise time.
217
- self.issued_at = options["issued_at"] if options.has_key?("issued_at")
219
+ self.issued_at = options[:issued_at] if options.has_key?(:issued_at)
218
220
 
219
- self.access_token = options["access_token"] if options.has_key?("access_token")
220
- self.refresh_token = options["refresh_token"] if options.has_key?("refresh_token")
221
- self.id_token = options["id_token"] if options.has_key?("id_token")
221
+ self.access_token = options[:access_token] if options.has_key?(:access_token)
222
+ self.refresh_token = options[:refresh_token] if options.has_key?(:refresh_token)
223
+ self.id_token = options[:id_token] if options.has_key?(:id_token)
222
224
 
223
225
  return self
224
226
  end
@@ -230,6 +232,9 @@ module Signet
230
232
  #
231
233
  # @see Signet::OAuth2.generate_authorization_uri
232
234
  def authorization_uri(options={})
235
+ # Normalize external input
236
+ options = deep_hash_normalize(options)
237
+
233
238
  return nil if @authorization_uri == nil
234
239
  unless options[:response_type]
235
240
  options[:response_type] = :code
@@ -272,15 +277,7 @@ module Signet
272
277
  # @param [Addressable::URI, Hash, String, #to_str] new_authorization_uri
273
278
  # The authorization URI.
274
279
  def authorization_uri=(new_authorization_uri)
275
- if new_authorization_uri != nil
276
- new_authorization_uri = Addressable::URI.send(
277
- new_authorization_uri.kind_of?(Hash) ? :new : :parse,
278
- new_authorization_uri
279
- )
280
- @authorization_uri = new_authorization_uri
281
- else
282
- @authorization_uri = nil
283
- end
280
+ @authorization_uri = coerce_uri(new_authorization_uri)
284
281
  end
285
282
 
286
283
  ##
@@ -297,14 +294,16 @@ module Signet
297
294
  # @param [Addressable::URI, Hash, String, #to_str] new_token_credential_uri
298
295
  # The token credential URI.
299
296
  def token_credential_uri=(new_token_credential_uri)
300
- if new_token_credential_uri != nil
301
- new_token_credential_uri = Addressable::URI.send(
302
- new_token_credential_uri.kind_of?(Hash) ? :new : :parse,
303
- new_token_credential_uri
304
- )
305
- @token_credential_uri = new_token_credential_uri
306
- else
307
- @token_credential_uri = nil
297
+ @token_credential_uri = coerce_uri(new_token_credential_uri)
298
+ end
299
+
300
+ # Addressable expects URIs formatted as hashes to come in with symbols as keys.
301
+ # Returns nil implicitly for the nil case.
302
+ def coerce_uri(incoming_uri)
303
+ if incoming_uri.is_a? Hash
304
+ Addressable::URI.new(deep_hash_normalize(incoming_uri))
305
+ elsif incoming_uri
306
+ Addressable::URI.parse(incoming_uri)
308
307
  end
309
308
  end
310
309
 
@@ -692,14 +691,14 @@ module Signet
692
691
  #
693
692
  # @return [String] The decoded ID token.
694
693
  def decoded_id_token(public_key=nil)
695
- decoded = JWT.decode(self.id_token, public_key, !!public_key)
696
- if !decoded.has_key?('aud')
694
+ payload, header = JWT.decode(self.id_token, public_key, !!public_key)
695
+ if !payload.has_key?('aud')
697
696
  raise Signet::UnsafeOperationError, 'No ID token audience declared.'
698
- elsif decoded['aud'] != self.client_id
697
+ elsif payload['aud'] != self.client_id
699
698
  raise Signet::UnsafeOperationError,
700
699
  'ID token audience did not match Client ID.'
701
700
  end
702
- return decoded
701
+ return payload
703
702
  end
704
703
 
705
704
  ##
@@ -827,6 +826,8 @@ module Signet
827
826
  end
828
827
 
829
828
  def to_jwt(options={})
829
+ options = deep_hash_normalize(options)
830
+
830
831
  now = Time.new
831
832
  skew = options[:skew] || 60
832
833
  assertion = {
@@ -881,6 +882,8 @@ module Signet
881
882
  #
882
883
  # @return [Array] The request object.
883
884
  def generate_access_token_request(options={})
885
+ options = deep_hash_normalize(options)
886
+
884
887
  if self.token_credential_uri == nil
885
888
  raise ArgumentError, 'Missing token endpoint URI.'
886
889
  end
@@ -926,13 +929,16 @@ module Signet
926
929
  end
927
930
 
928
931
  def fetch_access_token(options={})
932
+ options = deep_hash_normalize(options)
933
+
929
934
  options[:connection] ||= Faraday.default_connection
930
935
  request = self.generate_access_token_request(options)
931
936
  request_env = request.to_env(options[:connection])
932
937
  request_env[:request] ||= request
933
938
  response = options[:connection].app.call(request_env)
934
939
  if response.status.to_i == 200
935
- return ::Signet::OAuth2.parse_json_credentials(response.body)
940
+ content_type = response.headers['content-type']
941
+ return ::Signet::OAuth2.parse_credentials(response.body, content_type)
936
942
  elsif [400, 401, 403].include?(response.status.to_i)
937
943
  message = 'Authorization failed.'
938
944
  if response.body.to_s.strip.length > 0
@@ -953,6 +959,8 @@ module Signet
953
959
  end
954
960
 
955
961
  def fetch_access_token!(options={})
962
+ options = deep_hash_normalize(options)
963
+
956
964
  token_hash = self.fetch_access_token(options)
957
965
  if token_hash
958
966
  # No-op for grant types other than `authorization_code`.
@@ -968,6 +976,8 @@ module Signet
968
976
  ##
969
977
  # Refresh the access token, if possible
970
978
  def refresh!(options={})
979
+ options = deep_hash_normalize(options)
980
+
971
981
  self.fetch_access_token!(options)
972
982
  end
973
983
 
@@ -993,6 +1003,8 @@ module Signet
993
1003
  #
994
1004
  # @return [Faraday::Request] The request object.
995
1005
  def generate_authenticated_request(options={})
1006
+ options = deep_hash_normalize(options)
1007
+
996
1008
  if self.access_token == nil
997
1009
  raise ArgumentError, 'Missing access token.'
998
1010
  end
@@ -1081,6 +1093,8 @@ module Signet
1081
1093
  #
1082
1094
  # @return [Array] The response object.
1083
1095
  def fetch_protected_resource(options={})
1096
+ options = deep_hash_normalize(options)
1097
+
1084
1098
  options[:connection] ||= Faraday.default_connection
1085
1099
  request = self.generate_authenticated_request(options)
1086
1100
  request_env = request.to_env(options[:connection])
@@ -1116,7 +1130,25 @@ module Signet
1116
1130
  def uri_is_oob?(uri)
1117
1131
  return uri.to_s == 'urn:ietf:wg:oauth:2.0:oob' || uri.to_s == 'oob'
1118
1132
  end
1133
+
1134
+ # Convert all keys in this hash (nested) to symbols for uniform retrieval
1135
+ def recursive_hash_normalize_keys(val)
1136
+ if val.is_a? Hash
1137
+ deep_hash_normalize(val)
1138
+ else
1139
+ val
1140
+ end
1141
+ end
1142
+
1143
+ def deep_hash_normalize(old_hash)
1144
+ old_hash.inject(formatted_hash={}) do |formatted_hash,(k,v)|
1119
1145
 
1146
+ formatted_hash[k.to_sym] = recursive_hash_normalize_keys(v)
1147
+ formatted_hash
1148
+ end
1149
+
1150
+ formatted_hash
1151
+ end
1120
1152
  end
1121
1153
  end
1122
1154
  end
@@ -74,11 +74,18 @@ module Signet #:nodoc:
74
74
  return Signet.parse_auth_param_list(challenge_string)
75
75
  end
76
76
 
77
- def self.parse_json_credentials(body)
77
+ def self.parse_credentials(body, content_type)
78
78
  if !body.kind_of?(String)
79
79
  raise TypeError, "Expected String, got #{body.class}."
80
80
  end
81
- return MultiJson.load(body)
81
+ case content_type
82
+ when /^application\/json.*/
83
+ return MultiJson.load(body)
84
+ when /^application\/x-www-form-urlencoded.*/
85
+ return Hash[Addressable::URI.form_unencode(body)]
86
+ else
87
+ raise ArgumentError, "Invalid content type '#{content_type}'"
88
+ end
82
89
  end
83
90
 
84
91
  ##
@@ -17,8 +17,8 @@ unless defined? Signet::VERSION
17
17
  module Signet
18
18
  module VERSION
19
19
  MAJOR = 0
20
- MINOR = 5
21
- TINY = 1
20
+ MINOR = 6
21
+ TINY = 0
22
22
 
23
23
  STRING = [MAJOR, MINOR, TINY].join('.')
24
24
  end
data/signet.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # stub: signet 0.5.1 ruby lib
3
+ require File.join(File.dirname(__FILE__), 'lib/signet', 'version')
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "signet"
7
+ s.version = Signet::VERSION::STRING
8
+
9
+ s.required_rubygems_version = ">= 1.3.5"
10
+ s.require_paths = ["lib"]
11
+ s.authors = ["Bob Aman", "Steven Bazyl"]
12
+ s.license = "Apache-2.0"
13
+ s.description = "Signet is an OAuth 1.0 / OAuth 2.0 implementation.\n"
14
+ s.email = "sbazyl@google.com"
15
+ s.extra_rdoc_files = ["README.md"]
16
+ s.files = %w(signet.gemspec Rakefile LICENSE CHANGELOG.md README.md Gemfile)
17
+ s.files += Dir.glob("lib/**/*.rb")
18
+ s.files += Dir.glob("spec/**/*.{rb,opts}")
19
+ s.files += Dir.glob("vendor/**/*.rb")
20
+ s.files += Dir.glob("tasks/**/*")
21
+ s.files += Dir.glob("website/**/*")
22
+ s.homepage = "https://github.com/google/signet/"
23
+ s.rdoc_options = ["--main", "README.md"]
24
+ s.summary = "Signet is an OAuth 1.0 / OAuth 2.0 implementation."
25
+
26
+ s.add_runtime_dependency 'addressable', '~> 2.3'
27
+ s.add_runtime_dependency 'faraday', '~> 0.9'
28
+ s.add_runtime_dependency 'multi_json', '~> 1.10'
29
+ s.add_runtime_dependency 'jwt', '~> 1.0'
30
+ s.add_runtime_dependency 'extlib', '~> 0.9'
31
+
32
+ s.add_development_dependency 'rake', '~> 10.0'
33
+ s.add_development_dependency 'yard', '~> 0.8'
34
+ s.add_development_dependency 'rspec', '~> 3.1'
35
+ s.add_development_dependency 'launchy', '~> 2.4'
36
+ s.add_development_dependency 'kramdown', '~> 1.5'
37
+ s.add_development_dependency 'simplecov', '~> 0.9'
38
+ end