mojodna-oauth 0.3.1.6 → 0.3.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -3
- data/Manifest.txt +4 -0
- data/bin/oauth +1 -1
- data/lib/oauth/cli.rb +76 -7
- data/lib/oauth/client/net_http.rb +4 -6
- data/lib/oauth/consumer.rb +60 -13
- data/lib/oauth/request_proxy/action_controller_request.rb +0 -1
- data/lib/oauth/request_proxy/rack_request.rb +2 -2
- data/lib/oauth/signature/hmac/sha1.rb +0 -1
- data/lib/oauth/version.rb +1 -1
- data/oauth.gemspec +2 -2
- data/test/test_consumer.rb +1 -1
- metadata +7 -2
data/History.txt
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
== 0.3.2
|
2
2
|
|
3
|
+
* 2xx statuses should be treated as success (Anders Conbere)
|
4
|
+
* Support applications using the MethodOverride Rack middleware (László Bácsi)
|
5
|
+
* `authorize` command for `oauth` CLI (Seth)
|
6
|
+
* Initial support for Problem Reporting extension (Seth)
|
7
|
+
* Verify SSL certificates if CA certificates are available (Seth)
|
3
8
|
* Fixed ActionController parameter escaping behavior (Thiago Arrais, László
|
4
9
|
Bácsi, Brett Gibson, et al)
|
5
10
|
* Fixed signature calculation when both options and a block were provided to
|
6
|
-
OAuth::Signature::Base#initialize
|
7
|
-
* Added help to the 'oauth' CLI
|
8
|
-
* Fixed a problem when attempting to normalize MockRequest URIs
|
11
|
+
OAuth::Signature::Base#initialize (Seth)
|
12
|
+
* Added help to the 'oauth' CLI (Seth)
|
13
|
+
* Fixed a problem when attempting to normalize MockRequest URIs (Seth)
|
9
14
|
|
10
15
|
== 0.3.1 2009-1-26
|
11
16
|
|
data/Manifest.txt
CHANGED
@@ -14,6 +14,10 @@ lib/oauth/client/action_controller_request.rb
|
|
14
14
|
lib/oauth/client/helper.rb
|
15
15
|
lib/oauth/client/net_http.rb
|
16
16
|
lib/oauth/consumer.rb
|
17
|
+
lib/oauth/errors.rb
|
18
|
+
lib/oauth/errors/error.rb
|
19
|
+
lib/oauth/errors/problem.rb
|
20
|
+
lib/oauth/errors/unauthorized.rb
|
17
21
|
lib/oauth/helper.rb
|
18
22
|
lib/oauth/oauth_test_helper.rb
|
19
23
|
lib/oauth/request_proxy.rb
|
data/bin/oauth
CHANGED
data/lib/oauth/cli.rb
CHANGED
@@ -4,24 +4,32 @@ require 'oauth'
|
|
4
4
|
module OAuth
|
5
5
|
class CLI
|
6
6
|
SUPPORTED_COMMANDS = {
|
7
|
-
"
|
8
|
-
"
|
7
|
+
"authorize" => "Obtain an access token and secret for a user",
|
8
|
+
"debug" => "Verbosely generate an OAuth signature",
|
9
|
+
"sign" => "Generate an OAuth signature"
|
9
10
|
}
|
10
11
|
|
11
12
|
attr_reader :command
|
12
13
|
attr_reader :options
|
13
|
-
attr_reader :stdout
|
14
|
+
attr_reader :stdout, :stdin
|
14
15
|
|
15
|
-
def self.execute(stdout, arguments = [])
|
16
|
-
self.new.execute(stdout, arguments)
|
16
|
+
def self.execute(stdout, stdin, stderr, arguments = [])
|
17
|
+
self.new.execute(stdout, stdin, stderr, arguments)
|
17
18
|
end
|
18
19
|
|
19
20
|
def initialize
|
20
21
|
@options = {}
|
22
|
+
|
23
|
+
# don't dump a backtrace on a ^C
|
24
|
+
trap(:INT) {
|
25
|
+
exit
|
26
|
+
}
|
21
27
|
end
|
22
28
|
|
23
|
-
def execute(stdout, arguments = [])
|
29
|
+
def execute(stdout, stdin, stderr, arguments = [])
|
24
30
|
@stdout = stdout
|
31
|
+
@stdin = stdin
|
32
|
+
@stderr = stderr
|
25
33
|
extract_command_and_parse_options(arguments)
|
26
34
|
|
27
35
|
if sufficient_options? && valid_command?
|
@@ -31,6 +39,40 @@ module OAuth
|
|
31
39
|
end
|
32
40
|
|
33
41
|
case command
|
42
|
+
# TODO move command logic elsewhere
|
43
|
+
when "authorize"
|
44
|
+
# Y! token authority requires realm=yahoo.com when headers are in use
|
45
|
+
# TODO remove :scheme when that's been fixed
|
46
|
+
# TODO determine endpoints w/ X-RDS-Simple
|
47
|
+
consumer = OAuth::Consumer.new \
|
48
|
+
options[:oauth_consumer_key],
|
49
|
+
options[:oauth_consumer_secret],
|
50
|
+
:access_token_url => options[:access_token_url],
|
51
|
+
:authorize_url => options[:authorize_url],
|
52
|
+
:request_token_url => options[:request_token_url],
|
53
|
+
:scheme => :query_string
|
54
|
+
|
55
|
+
# get a request token
|
56
|
+
request_token = consumer.get_request_token
|
57
|
+
|
58
|
+
stdout.puts "Please visit this url to authorize:"
|
59
|
+
stdout.puts request_token.authorize_url
|
60
|
+
|
61
|
+
stdout.puts "Press return to continue..."
|
62
|
+
stdin.gets
|
63
|
+
|
64
|
+
begin
|
65
|
+
# get an access token
|
66
|
+
access_token = request_token.get_access_token
|
67
|
+
|
68
|
+
stdout.puts "Response:"
|
69
|
+
access_token.params.each do |k,v|
|
70
|
+
stdout.puts " #{k}: #{v}"
|
71
|
+
end
|
72
|
+
rescue OAuth::Unauthorized => e
|
73
|
+
stderr.puts "A problem occurred while attempting to obtain an access token:"
|
74
|
+
stderr.puts e
|
75
|
+
end
|
34
76
|
when "sign"
|
35
77
|
parameters = prepare_parameters
|
36
78
|
|
@@ -116,6 +158,8 @@ module OAuth
|
|
116
158
|
options[:oauth_version] = "1.0"
|
117
159
|
options[:params] = []
|
118
160
|
|
161
|
+
## Common Options
|
162
|
+
|
119
163
|
opts.on("--consumer-key KEY", "Specifies the consumer key to use.") do |v|
|
120
164
|
options[:oauth_consumer_key] = v
|
121
165
|
end
|
@@ -124,6 +168,8 @@ module OAuth
|
|
124
168
|
options[:oauth_consumer_secret] = v
|
125
169
|
end
|
126
170
|
|
171
|
+
## Options for signing
|
172
|
+
|
127
173
|
opts.on("--method METHOD", "Specifies the method (e.g. GET) to use when signing.") do |v|
|
128
174
|
options[:method] = v
|
129
175
|
end
|
@@ -176,6 +222,20 @@ module OAuth
|
|
176
222
|
opts.on("-v", "--verbose", "Be verbose.") do
|
177
223
|
options[:verbose] = true
|
178
224
|
end
|
225
|
+
|
226
|
+
## Options for authorization
|
227
|
+
|
228
|
+
opts.on("--access-token-url URL", "Specifies the access token URL.") do |v|
|
229
|
+
options[:access_token_url] = v
|
230
|
+
end
|
231
|
+
|
232
|
+
opts.on("--authorize-url URL", "Specifies the authorization URL.") do |v|
|
233
|
+
options[:authorize_url] = v
|
234
|
+
end
|
235
|
+
|
236
|
+
opts.on("--request-token-url URL", "Specifies the request token URL.") do |v|
|
237
|
+
options[:request_token_url] = v
|
238
|
+
end
|
179
239
|
end
|
180
240
|
end
|
181
241
|
|
@@ -208,7 +268,16 @@ module OAuth
|
|
208
268
|
end
|
209
269
|
|
210
270
|
def sufficient_options?
|
211
|
-
|
271
|
+
case command
|
272
|
+
# TODO move command logic elsewhere
|
273
|
+
when "authorize"
|
274
|
+
options[:oauth_consumer_key] && options[:oauth_consumer_secret] &&
|
275
|
+
options[:access_token_url] && options[:authorize_url] &&
|
276
|
+
options[:request_token_url]
|
277
|
+
else
|
278
|
+
options[:oauth_consumer_key] && options[:oauth_consumer_secret] &&
|
279
|
+
options[:method] && options[:uri]
|
280
|
+
end
|
212
281
|
end
|
213
282
|
|
214
283
|
def usage
|
@@ -5,6 +5,8 @@ require 'oauth/request_proxy/net_http'
|
|
5
5
|
class Net::HTTPRequest
|
6
6
|
include OAuth::Helper
|
7
7
|
|
8
|
+
attr_reader :oauth_helper
|
9
|
+
|
8
10
|
def oauth!(http, consumer = nil, token = nil, options = {})
|
9
11
|
options = { :request_uri => oauth_full_request_uri(http),
|
10
12
|
:consumer => consumer,
|
@@ -30,10 +32,6 @@ class Net::HTTPRequest
|
|
30
32
|
OAuth::Client::Helper.new(self, options).signature_base_string
|
31
33
|
end
|
32
34
|
|
33
|
-
def oauth_helper
|
34
|
-
@oauth_helper
|
35
|
-
end
|
36
|
-
|
37
35
|
private
|
38
36
|
|
39
37
|
def oauth_full_request_uri(http)
|
@@ -67,7 +65,7 @@ private
|
|
67
65
|
oauth_params_str = @oauth_helper.oauth_parameters.map { |k,v| [escape(k), escape(v)] * "=" }.join("&")
|
68
66
|
|
69
67
|
uri = URI.parse(path)
|
70
|
-
if
|
68
|
+
if uri.query.to_s == ""
|
71
69
|
uri.query = oauth_params_str
|
72
70
|
else
|
73
71
|
uri.query = uri.query + "&" + oauth_params_str
|
@@ -75,6 +73,6 @@ private
|
|
75
73
|
|
76
74
|
@path = uri.to_s
|
77
75
|
|
78
|
-
@path << "&oauth_signature=#{escape(
|
76
|
+
@path << "&oauth_signature=#{escape(oauth_helper.signature)}"
|
79
77
|
end
|
80
78
|
end
|
data/lib/oauth/consumer.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'net/https'
|
3
3
|
require 'oauth/client/net_http'
|
4
|
+
require 'oauth/errors'
|
5
|
+
|
4
6
|
module OAuth
|
5
7
|
class Consumer
|
8
|
+
# determine the certificate authority path to verify SSL certs
|
9
|
+
CA_FILES = %w(/etc/ssl/certs/ca-certificates.crt /usr/share/curl/curl-ca-bundle.crt)
|
10
|
+
CA_FILES.each do |ca_file|
|
11
|
+
if File.exists?(ca_file)
|
12
|
+
CA_FILE = ca_file
|
13
|
+
break
|
14
|
+
end
|
15
|
+
end
|
16
|
+
CA_FILE = nil unless defined?(CA_FILE)
|
6
17
|
|
7
18
|
@@default_options = {
|
8
19
|
# Signature method used by server. Defaults to HMAC-SHA1
|
@@ -102,20 +113,39 @@ module OAuth
|
|
102
113
|
# @consumer.request(:post, '/people', @token, {}, @person.to_xml, { 'Content-Type' => 'application/xml' })
|
103
114
|
#
|
104
115
|
def request(http_method, path, token = nil, request_options = {}, *arguments)
|
105
|
-
if path
|
106
|
-
|
107
|
-
else
|
108
|
-
_http = create_http(path)
|
116
|
+
if path !~ /^\//
|
117
|
+
@http = create_http(path)
|
109
118
|
_uri = URI.parse(path)
|
110
119
|
path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
|
111
120
|
end
|
112
121
|
|
113
|
-
|
122
|
+
rsp = http.request(create_signed_request(http_method, path, token, request_options, *arguments))
|
123
|
+
|
124
|
+
# check for an error reported by the Problem Reporting extension
|
125
|
+
# (http://wiki.oauth.net/ProblemReporting)
|
126
|
+
# note: a 200 may actually be an error; check for an oauth_problem key to be sure
|
127
|
+
if !(headers = rsp.to_hash["www-authenticate"]).nil? &&
|
128
|
+
(h = headers.select { |h| h =~ /^OAuth / }).any? &&
|
129
|
+
h.first =~ /oauth_problem/
|
130
|
+
|
131
|
+
# puts "Header: #{h.first}"
|
132
|
+
|
133
|
+
# TODO doesn't handle broken responses from api.login.yahoo.com
|
134
|
+
# remove debug code when done
|
135
|
+
params = OAuth::Helper.parse_header(h.first)
|
136
|
+
|
137
|
+
# puts "Params: #{params.inspect}"
|
138
|
+
# puts "Body: #{rsp.body}"
|
139
|
+
|
140
|
+
raise OAuth::Problem.new(params.delete("oauth_problem"), rsp, params)
|
141
|
+
end
|
142
|
+
|
143
|
+
rsp
|
114
144
|
end
|
115
145
|
|
116
146
|
# Creates and signs an http request.
|
117
147
|
# It's recommended to use the Token classes to set this up correctly
|
118
|
-
def create_signed_request(http_method, path, token = nil,request_options = {}, *arguments)
|
148
|
+
def create_signed_request(http_method, path, token = nil, request_options = {}, *arguments)
|
119
149
|
request = create_http_request(http_method, path, *arguments)
|
120
150
|
sign!(request, token, request_options)
|
121
151
|
request
|
@@ -124,20 +154,28 @@ module OAuth
|
|
124
154
|
# Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.
|
125
155
|
def token_request(http_method, path, token = nil, request_options = {}, *arguments)
|
126
156
|
response = request(http_method, path, token, request_options, *arguments)
|
127
|
-
|
157
|
+
|
158
|
+
case response.code.to_i
|
159
|
+
|
160
|
+
when (200..299)
|
128
161
|
CGI.parse(response.body).inject({}) { |h,(k,v)| h[k.to_sym] = v.first; h }
|
162
|
+
when (300..399)
|
163
|
+
# this is a redirect
|
164
|
+
response.error!
|
165
|
+
when (400..499)
|
166
|
+
raise OAuth::Unauthorized, response
|
129
167
|
else
|
130
168
|
response.error!
|
131
169
|
end
|
132
170
|
end
|
133
171
|
|
134
172
|
# Sign the Request object. Use this if you have an externally generated http request object you want to sign.
|
135
|
-
def sign!(request, token=nil, request_options = {})
|
173
|
+
def sign!(request, token = nil, request_options = {})
|
136
174
|
request.oauth!(http, self, token, options.merge(request_options))
|
137
175
|
end
|
138
176
|
|
139
177
|
# Return the signature_base_string
|
140
|
-
def signature_base_string(request, token=nil, request_options = {})
|
178
|
+
def signature_base_string(request, token = nil, request_options = {})
|
141
179
|
request.signature_base_string(http, self, token, options.merge(request_options))
|
142
180
|
end
|
143
181
|
|
@@ -167,7 +205,7 @@ module OAuth
|
|
167
205
|
end
|
168
206
|
|
169
207
|
def request_token_url?
|
170
|
-
@options
|
208
|
+
@options.has_key?(:request_token_url)
|
171
209
|
end
|
172
210
|
|
173
211
|
def authorize_url
|
@@ -175,7 +213,7 @@ module OAuth
|
|
175
213
|
end
|
176
214
|
|
177
215
|
def authorize_url?
|
178
|
-
@options
|
216
|
+
@options.has_key?(:authorize_url)
|
179
217
|
end
|
180
218
|
|
181
219
|
def access_token_url
|
@@ -183,7 +221,7 @@ module OAuth
|
|
183
221
|
end
|
184
222
|
|
185
223
|
def access_token_url?
|
186
|
-
@options
|
224
|
+
@options.has_key?(:access_token_url)
|
187
225
|
end
|
188
226
|
|
189
227
|
protected
|
@@ -197,7 +235,16 @@ module OAuth
|
|
197
235
|
end
|
198
236
|
|
199
237
|
http_object = Net::HTTP.new(our_uri.host, our_uri.port)
|
200
|
-
|
238
|
+
|
239
|
+
http_object.use_ssl = (our_uri.scheme == 'https')
|
240
|
+
|
241
|
+
if CA_FILE
|
242
|
+
http_object.ca_file = CA_FILE
|
243
|
+
http_object.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
244
|
+
http_object.verify_depth = 5
|
245
|
+
else
|
246
|
+
http_object.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
247
|
+
end
|
201
248
|
|
202
249
|
http_object
|
203
250
|
end
|
@@ -7,7 +7,7 @@ module OAuth::RequestProxy
|
|
7
7
|
proxies Rack::Request
|
8
8
|
|
9
9
|
def method
|
10
|
-
request.request_method
|
10
|
+
request.env["rack.methodoverride.original_method"] || request.request_method
|
11
11
|
end
|
12
12
|
|
13
13
|
def uri
|
@@ -37,4 +37,4 @@ module OAuth::RequestProxy
|
|
37
37
|
request.params
|
38
38
|
end
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
data/lib/oauth/version.rb
CHANGED
data/oauth.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{oauth}
|
5
|
-
s.version = "0.3.1.
|
5
|
+
s.version = "0.3.1.7"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Pelle Braendgaard", "Blaine Cook", "Larry Halff", "Jesse Clark", "Jon Crosby", "Seth Fitzsimmons"]
|
9
|
-
s.date = %q{2009-02
|
9
|
+
s.date = %q{2009-03-02}
|
10
10
|
s.default_executable = %q{oauth}
|
11
11
|
s.description = %q{OAuth Core Ruby implementation}
|
12
12
|
s.email = %q{pelleb@gmail.com}
|
data/test/test_consumer.rb
CHANGED
@@ -143,7 +143,7 @@ class ConsumerTest < Test::Unit::TestCase
|
|
143
143
|
|
144
144
|
assert_equal 'POST', request.method
|
145
145
|
assert_equal '/test', request.path
|
146
|
-
assert_equal "key=value&oauth_consumer_key=consumer_key_86cad9&oauth_nonce=225579211881198842005988698334675835446&oauth_signature=
|
146
|
+
assert_equal "key=value&oauth_consumer_key=consumer_key_86cad9&oauth_nonce=225579211881198842005988698334675835446&oauth_signature=26g7wHTtNO6ZWJaLltcueppHYiI%3d&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1199645624&oauth_token=token_411a7f&oauth_version=1.0", request.body.split("&").sort.join("&")
|
147
147
|
assert_equal nil, request['authorization']
|
148
148
|
end
|
149
149
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mojodna-oauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.1.
|
4
|
+
version: 0.3.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pelle Braendgaard
|
@@ -14,11 +14,12 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2009-02
|
17
|
+
date: 2009-03-02 00:00:00 -08:00
|
18
18
|
default_executable: oauth
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: ruby-hmac
|
22
|
+
type: :runtime
|
22
23
|
version_requirement:
|
23
24
|
version_requirements: !ruby/object:Gem::Requirement
|
24
25
|
requirements:
|
@@ -28,6 +29,7 @@ dependencies:
|
|
28
29
|
version:
|
29
30
|
- !ruby/object:Gem::Dependency
|
30
31
|
name: newgem
|
32
|
+
type: :development
|
31
33
|
version_requirement:
|
32
34
|
version_requirements: !ruby/object:Gem::Requirement
|
33
35
|
requirements:
|
@@ -37,6 +39,7 @@ dependencies:
|
|
37
39
|
version:
|
38
40
|
- !ruby/object:Gem::Dependency
|
39
41
|
name: actionpack
|
42
|
+
type: :development
|
40
43
|
version_requirement:
|
41
44
|
version_requirements: !ruby/object:Gem::Requirement
|
42
45
|
requirements:
|
@@ -46,6 +49,7 @@ dependencies:
|
|
46
49
|
version:
|
47
50
|
- !ruby/object:Gem::Dependency
|
48
51
|
name: rack
|
52
|
+
type: :development
|
49
53
|
version_requirement:
|
50
54
|
version_requirements: !ruby/object:Gem::Requirement
|
51
55
|
requirements:
|
@@ -55,6 +59,7 @@ dependencies:
|
|
55
59
|
version:
|
56
60
|
- !ruby/object:Gem::Dependency
|
57
61
|
name: hoe
|
62
|
+
type: :development
|
58
63
|
version_requirement:
|
59
64
|
version_requirements: !ruby/object:Gem::Requirement
|
60
65
|
requirements:
|