signet 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|