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 +13 -5
- data/CHANGELOG.md +7 -0
- data/Gemfile +2 -19
- data/lib/signet/oauth_2/client.rb +82 -50
- data/lib/signet/oauth_2.rb +9 -2
- data/lib/signet/version.rb +2 -2
- data/signet.gemspec +38 -0
- data/spec/signet/oauth_1/client_spec.rb +231 -243
- data/spec/signet/oauth_1/credential_spec.rb +30 -30
- data/spec/signet/oauth_1/server_spec.rb +128 -129
- data/spec/signet/oauth_1/services/google_spec.rb +24 -25
- data/spec/signet/oauth_1/signature_methods/hmac_sha1_spec.rb +4 -4
- data/spec/signet/oauth_1/signature_methods/plaintext_spec.rb +4 -4
- data/spec/signet/oauth_1/signature_methods/rsa_sha1_spec.rb +6 -6
- data/spec/signet/oauth_1_spec.rb +190 -192
- data/spec/signet/oauth_2/client_spec.rb +296 -181
- data/spec/signet/oauth_2_spec.rb +58 -48
- data/spec/signet_spec.rb +23 -23
- data/spec/spec_helper.rb +3 -1
- data/tasks/gem.rake +3 -55
- data/tasks/spec.rake +0 -25
- metadata +99 -38
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ODJiNTkyYjQ1OGRkNDY2Y2RjNDZiY2U1YjJhNWI3MWFmNmU5OTNiNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MGUyODYzMjdmODI4Y2U4YjE5YTMyYzY2ZDU1ZWE3ZGFlYjZmNjRlMw==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
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
|
-
|
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
|
157
|
-
options = options
|
158
|
-
|
159
|
-
self.
|
160
|
-
self.
|
161
|
-
self.
|
162
|
-
self.
|
163
|
-
self.
|
164
|
-
self.
|
165
|
-
self.
|
166
|
-
self.
|
167
|
-
self.
|
168
|
-
self.
|
169
|
-
self.
|
170
|
-
self.
|
171
|
-
self.
|
172
|
-
self.
|
173
|
-
self.
|
174
|
-
self.
|
175
|
-
self.
|
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
|
210
|
-
options = options
|
210
|
+
# Normalize all keys to symbols to allow indifferent access internally
|
211
|
+
options = deep_hash_normalize(options)
|
211
212
|
|
212
|
-
self.expires_in = options[
|
213
|
-
self.
|
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[
|
219
|
+
self.issued_at = options[:issued_at] if options.has_key?(:issued_at)
|
218
220
|
|
219
|
-
self.access_token = options[
|
220
|
-
self.refresh_token = options[
|
221
|
-
self.id_token = options[
|
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
|
-
|
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
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
-
|
696
|
-
if !
|
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
|
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
|
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
|
-
|
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
|
data/lib/signet/oauth_2.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
##
|
data/lib/signet/version.rb
CHANGED
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
|