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 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. (Seth)
7
- * Added help to the 'oauth' CLI. (Seth)
8
- * Fixed a problem when attempting to normalize MockRequest URIs. (Seth)
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
@@ -2,4 +2,4 @@
2
2
 
3
3
  require "oauth/cli"
4
4
 
5
- OAuth::CLI.execute(STDOUT, ARGV)
5
+ OAuth::CLI.execute(STDOUT, STDIN, STDERR, ARGV)
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
- "debug" => "Verbosely generate an OAuth signature",
8
- "sign" => "Generate an OAuth signature"
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
- options[:oauth_consumer_key] && options[:oauth_consumer_secret] && options[:method] && options[:uri]
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 !uri.query || uri.query == ''
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(@oauth_helper.signature)}"
76
+ @path << "&oauth_signature=#{escape(oauth_helper.signature)}"
79
77
  end
80
78
  end
@@ -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
- _http = http
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
- _http.request(create_signed_request(http_method, path, token, request_options, *arguments))
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
- if response.code == "200"
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[:request_token_url]!=nil
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[:authorize_url]!=nil
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[:access_token_url]!=nil
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
- http_object.use_ssl = true if our_uri.scheme == "https"
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
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'active_support'
3
2
  require 'action_controller/request'
4
3
  require 'oauth/request_proxy/base'
@@ -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
@@ -1,5 +1,4 @@
1
1
  require 'oauth/signature/hmac/base'
2
- require 'rubygems'
3
2
  require 'hmac-sha1'
4
3
 
5
4
  module OAuth::Signature::HMAC
data/lib/oauth/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module OAuth #:nodoc:
2
- VERSION = '0.3.1.6'
2
+ VERSION = '0.3.1.7'
3
3
  end
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.6"
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-11}
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}
@@ -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=iMZaUTbQof%2fHMFyIde%2bOIkhW5is%3d&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1199645624&oauth_token=token_411a7f&oauth_version=1.0", request.body.split("&").sort.join("&")
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.6
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-11 00:00:00 -08:00
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: