oauth 0.3.6 → 0.3.7.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oauth might be problematic. Click here for more details.
- data/.gitignore +1 -0
- data/History.txt +16 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +13 -0
- data/Rakefile +27 -27
- data/TODO +1 -0
- data/lib/digest/hmac.rb +104 -0
- data/lib/oauth.rb +5 -1
- data/lib/oauth/client/action_controller_request.rb +1 -1
- data/lib/oauth/client/em_http.rb +94 -0
- data/lib/oauth/client/helper.rb +7 -4
- data/lib/oauth/client/net_http.rb +9 -6
- data/lib/oauth/consumer.rb +45 -25
- data/lib/oauth/core_ext.rb +31 -0
- data/lib/oauth/helper.rb +11 -1
- data/lib/oauth/request_proxy/base.rb +4 -3
- data/lib/oauth/request_proxy/curb_request.rb +55 -0
- data/lib/oauth/request_proxy/em_http_request.rb +67 -0
- data/lib/oauth/request_proxy/net_http.rb +9 -6
- data/lib/oauth/request_proxy/typhoeus_request.rb +53 -0
- data/lib/oauth/signature.rb +4 -1
- data/lib/oauth/signature/base.rb +9 -3
- data/lib/oauth/signature/hmac/base.rb +5 -2
- data/lib/oauth/signature/hmac/md5.rb +1 -2
- data/lib/oauth/signature/hmac/rmd160.rb +1 -2
- data/lib/oauth/signature/hmac/sha1.rb +2 -3
- data/lib/oauth/signature/hmac/sha2.rb +1 -2
- data/lib/oauth/signature/plaintext.rb +2 -2
- data/lib/oauth/version.rb +1 -1
- data/oauth.gemspec +157 -27
- data/test/integration/consumer_test.rb +304 -0
- data/test/test_action_controller_request_proxy.rb +4 -1
- data/test/test_consumer.rb +51 -254
- data/test/test_curb_request_proxy.rb +69 -0
- data/test/test_em_http_client.rb +74 -0
- data/test/test_em_http_request_proxy.rb +107 -0
- data/test/test_helper.rb +15 -9
- data/test/test_net_http_client.rb +59 -5
- data/test/test_net_http_request_proxy.rb +1 -1
- data/test/test_signature.rb +6 -3
- data/test/test_typhoeus_request_proxy.rb +73 -0
- data/website/index.html +2 -2
- metadata +43 -25
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/*
|
data/History.txt
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 0.3.7
|
2
|
+
* Better marshalling implementation (Yoan Blanc)
|
3
|
+
* Added optional block to OAuth::Consumer.get_*_token (Neill Pearman)
|
4
|
+
* Exclude `oauth_callback` with :exclude_callback (Neill Pearman)
|
5
|
+
* Strip extraneous spaces and line breaks from access_token responses
|
6
|
+
(observed in the wild with Yahoo!'s OAuth+OpenID hybrid) (Eric Hartmann)
|
7
|
+
* Stop double-escaping PLAINTEXT signatures (Jimmy Zimmerman)
|
8
|
+
* OAuth::Client::Helper won't override the specified `oauth_version`
|
9
|
+
(Philip Kromer)
|
10
|
+
* Support for Ruby 1.9 (Aaron Quint, Corey Donahoe, et al)
|
11
|
+
* Fixed an encoding / multibyte issue (成田 一生)
|
12
|
+
* Replaced hoe with Jeweler (Aaron Quint)
|
13
|
+
* Support for Typhoeus (Bill Kocik)
|
14
|
+
* Support for em-http (EventMachine) (Darcy Laycock)
|
15
|
+
* Support for curb (André Luis Leal Cardoso Junior)
|
16
|
+
|
1
17
|
== 0.3.6 2009-09-14
|
2
18
|
|
3
19
|
* Added -B CLI option to use the :body authentication scheme (Seth)
|
data/Manifest.txt
CHANGED
@@ -13,6 +13,7 @@ lib/oauth/client.rb
|
|
13
13
|
lib/oauth/client/action_controller_request.rb
|
14
14
|
lib/oauth/client/helper.rb
|
15
15
|
lib/oauth/client/net_http.rb
|
16
|
+
lib/oauth/client/em_http.rb
|
16
17
|
lib/oauth/consumer.rb
|
17
18
|
lib/oauth/errors.rb
|
18
19
|
lib/oauth/errors/error.rb
|
@@ -27,6 +28,7 @@ lib/oauth/request_proxy/jabber_request.rb
|
|
27
28
|
lib/oauth/request_proxy/mock_request.rb
|
28
29
|
lib/oauth/request_proxy/net_http.rb
|
29
30
|
lib/oauth/request_proxy/rack_request.rb
|
31
|
+
lib/oauth/request_proxy/em_http_request.rb
|
30
32
|
lib/oauth/server.rb
|
31
33
|
lib/oauth/signature.rb
|
32
34
|
lib/oauth/signature/base.rb
|
data/README.rdoc
CHANGED
@@ -37,8 +37,21 @@ When user returns create an access_token
|
|
37
37
|
@access_token = @request_token.get_access_token
|
38
38
|
@photos = @access_token.get('/photos.xml')
|
39
39
|
|
40
|
+
Now that you have an access token, you can use Typhoeus to interact with the OAuth provider if you choose.
|
41
|
+
|
42
|
+
oauth_params = {:consumer => oauth_consumer, :token => access_token}
|
43
|
+
hydra = Typhoeus::Hydra.new
|
44
|
+
req = Typhoeus::Request.new(uri, options)
|
45
|
+
oauth_helper = OAuth::Client::Helper.new(req, oauth_params.merge(:request_uri => uri))
|
46
|
+
req.headers.merge!({"Authorization" => oauth_helper.header}) # Signs the request
|
47
|
+
hydra.queue(req)
|
48
|
+
hydra.run
|
49
|
+
@response = req.response
|
50
|
+
|
40
51
|
For more detailed instructions I have written this OAuth Client Tutorial http://stakeventures.com/articles/2008/02/23/developing-oauth-clients-in-ruby and "How to turn your rails site into an OAuth Provider ":http://stakeventures.com/articles/2007/11/26/how-to-turn-your-rails-site-into-an-oauth-provider .
|
41
52
|
|
53
|
+
If you wish to use em-http-request, you can find an example "in the official em-http-request repository":http://github.com/igrigorik/em-http-request/blob/master/examples/oauth-tweet.rb
|
54
|
+
|
42
55
|
Finally be sure to check out the OAuth RDoc Manual http://oauth.rubyforge.org/rdoc/ .
|
43
56
|
|
44
57
|
== Documentation Wiki
|
data/Rakefile
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
%w[rubygems rake rake/clean fileutils
|
1
|
+
%w[rubygems rake rake/clean rake/testtask fileutils].each { |f| require f }
|
2
2
|
$LOAD_PATH << File.dirname(__FILE__) + '/lib'
|
3
3
|
require 'oauth'
|
4
4
|
require 'oauth/version'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
[
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |s|
|
9
|
+
s.name = %q{oauth}
|
10
|
+
s.version = OAuth::VERSION
|
11
|
+
s.date = %q{2009-08-10}
|
12
|
+
s.authors = ["Pelle Braendgaard", "Blaine Cook", "Larry Halff", "Jesse Clark", "Jon Crosby", "Seth Fitzsimmons", "Matt Sanford", "Aaron Quint"]
|
13
|
+
s.email = "oauth-ruby@googlegroups.com"
|
14
|
+
s.description = "OAuth Core Ruby implementation"
|
15
|
+
s.summary = s.description
|
16
|
+
s.rubyforge_project = %q{oauth}
|
17
|
+
s.add_development_dependency(%q<actionpack>, [">= 2.2.0"])
|
18
|
+
s.add_development_dependency(%q<rack>, [">= 1.0.0"])
|
19
|
+
s.add_development_dependency(%q<mocha>, [">= 0.9.8"])
|
20
|
+
s.add_development_dependency(%q<typhoeus>, [">= 0.1.13"])
|
21
|
+
s.add_development_dependency(%q<em-http-request>)
|
22
|
+
end
|
23
|
+
Jeweler::GemcutterTasks.new
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
Rake::TestTask.new do |t|
|
29
|
+
t.libs << "test"
|
30
|
+
t.test_files = FileList['test/*test*.rb']
|
31
|
+
t.verbose = true
|
30
32
|
end
|
31
33
|
|
32
|
-
require 'newgem/tasks' # load /tasks/*.rake
|
33
34
|
Dir['tasks/**/*.rake'].each { |t| load t }
|
34
35
|
|
35
|
-
|
36
|
-
# task :default => [:spec, :features]
|
36
|
+
task :default => :test
|
data/TODO
CHANGED
data/lib/digest/hmac.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# = digest/hmac.rb
|
2
|
+
#
|
3
|
+
# An implementation of HMAC keyed-hashing algorithm
|
4
|
+
#
|
5
|
+
# == Overview
|
6
|
+
#
|
7
|
+
# This library adds a method named hmac() to Digest classes, which
|
8
|
+
# creates a Digest class for calculating HMAC digests.
|
9
|
+
#
|
10
|
+
# == Examples
|
11
|
+
#
|
12
|
+
# require 'digest/hmac'
|
13
|
+
#
|
14
|
+
# # one-liner example
|
15
|
+
# puts Digest::HMAC.hexdigest("data", "hash key", Digest::SHA1)
|
16
|
+
#
|
17
|
+
# # rather longer one
|
18
|
+
# hmac = Digest::HMAC.new("foo", Digest::RMD160)
|
19
|
+
#
|
20
|
+
# buf = ""
|
21
|
+
# while stream.read(16384, buf)
|
22
|
+
# hmac.update(buf)
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# puts hmac.bubblebabble
|
26
|
+
#
|
27
|
+
# == License
|
28
|
+
#
|
29
|
+
# Copyright (c) 2006 Akinori MUSHA <knu@iDaemons.org>
|
30
|
+
#
|
31
|
+
# Documentation by Akinori MUSHA
|
32
|
+
#
|
33
|
+
# All rights reserved. You can redistribute and/or modify it under
|
34
|
+
# the same terms as Ruby.
|
35
|
+
#
|
36
|
+
# $Id: hmac.rb 14881 2008-01-04 07:26:14Z akr $
|
37
|
+
#
|
38
|
+
|
39
|
+
require 'digest'
|
40
|
+
|
41
|
+
unless defined?(Digest::HMAC)
|
42
|
+
module Digest
|
43
|
+
class HMAC < Digest::Class
|
44
|
+
def initialize(key, digester)
|
45
|
+
@md = digester.new
|
46
|
+
|
47
|
+
block_len = @md.block_length
|
48
|
+
|
49
|
+
if key.bytesize > block_len
|
50
|
+
key = @md.digest(key)
|
51
|
+
end
|
52
|
+
|
53
|
+
ipad = Array.new(block_len).fill(0x36)
|
54
|
+
opad = Array.new(block_len).fill(0x5c)
|
55
|
+
|
56
|
+
key.bytes.each_with_index { |c, i|
|
57
|
+
ipad[i] ^= c
|
58
|
+
opad[i] ^= c
|
59
|
+
}
|
60
|
+
|
61
|
+
@key = key.freeze
|
62
|
+
@ipad = ipad.inject('') { |s, c| s << c.chr }.freeze
|
63
|
+
@opad = opad.inject('') { |s, c| s << c.chr }.freeze
|
64
|
+
@md.update(@ipad)
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize_copy(other)
|
68
|
+
@md = other.instance_eval { @md.clone }
|
69
|
+
end
|
70
|
+
|
71
|
+
def update(text)
|
72
|
+
@md.update(text)
|
73
|
+
self
|
74
|
+
end
|
75
|
+
alias << update
|
76
|
+
|
77
|
+
def reset
|
78
|
+
@md.reset
|
79
|
+
@md.update(@ipad)
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
def finish
|
84
|
+
d = @md.digest!
|
85
|
+
@md.update(@opad)
|
86
|
+
@md.update(d)
|
87
|
+
@md.digest!
|
88
|
+
end
|
89
|
+
private :finish
|
90
|
+
|
91
|
+
def digest_length
|
92
|
+
@md.digest_length
|
93
|
+
end
|
94
|
+
|
95
|
+
def block_length
|
96
|
+
@md.block_length
|
97
|
+
end
|
98
|
+
|
99
|
+
def inspect
|
100
|
+
sprintf('#<%s: key=%s, digest=%s>', self.class.name, @key.inspect, @md.inspect.sub(/^\#<(.*)>$/) { $1 });
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/oauth.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
2
|
+
|
1
3
|
require 'oauth/oauth'
|
4
|
+
require 'oauth/core_ext'
|
5
|
+
|
2
6
|
require 'oauth/client/helper'
|
3
7
|
require 'oauth/signature/hmac/sha1'
|
4
|
-
require 'oauth/request_proxy/mock_request'
|
8
|
+
require 'oauth/request_proxy/mock_request'
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'em-http'
|
2
|
+
require 'oauth/helper'
|
3
|
+
require 'oauth/client/helper'
|
4
|
+
require 'oauth/request_proxy/em_http_request'
|
5
|
+
|
6
|
+
# Extensions for em-http so that we can use consumer.sign! with an EventMachine::HttpClient
|
7
|
+
# instance. This is purely syntactic sugar.
|
8
|
+
class EventMachine::HttpClient
|
9
|
+
|
10
|
+
attr_reader :oauth_helper
|
11
|
+
|
12
|
+
# Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
|
13
|
+
# this may add a header, additional query string parameters, or additional POST body parameters.
|
14
|
+
# The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
|
15
|
+
# header.
|
16
|
+
#
|
17
|
+
# * http - Configured Net::HTTP instance, ignored in this scenario except for getting host.
|
18
|
+
# * consumer - OAuth::Consumer instance
|
19
|
+
# * token - OAuth::Token instance
|
20
|
+
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
|
21
|
+
# +signature_method+, +nonce+, +timestamp+)
|
22
|
+
#
|
23
|
+
# This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
|
24
|
+
#
|
25
|
+
# See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1]
|
26
|
+
def oauth!(http, consumer = nil, token = nil, options = {})
|
27
|
+
options = { :request_uri => normalized_oauth_uri(http),
|
28
|
+
:consumer => consumer,
|
29
|
+
:token => token,
|
30
|
+
:scheme => 'header',
|
31
|
+
:signature_method => nil,
|
32
|
+
:nonce => nil,
|
33
|
+
:timestamp => nil }.merge(options)
|
34
|
+
|
35
|
+
@oauth_helper = OAuth::Client::Helper.new(self, options)
|
36
|
+
self.__send__(:"set_oauth_#{options[:scheme]}")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Create a string suitable for signing for an HTTP request. This process involves parameter
|
40
|
+
# normalization as specified in the OAuth specification. The exact normalization also depends
|
41
|
+
# on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
|
42
|
+
# itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
|
43
|
+
# header.
|
44
|
+
#
|
45
|
+
# * http - Configured Net::HTTP instance
|
46
|
+
# * consumer - OAuth::Consumer instance
|
47
|
+
# * token - OAuth::Token instance
|
48
|
+
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
|
49
|
+
# +signature_method+, +nonce+, +timestamp+)
|
50
|
+
#
|
51
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
52
|
+
def signature_base_string(http, consumer = nil, token = nil, options = {})
|
53
|
+
options = { :request_uri => normalized_oauth_uri(http),
|
54
|
+
:consumer => consumer,
|
55
|
+
:token => token,
|
56
|
+
:scheme => 'header',
|
57
|
+
:signature_method => nil,
|
58
|
+
:nonce => nil,
|
59
|
+
:timestamp => nil }.merge(options)
|
60
|
+
|
61
|
+
OAuth::Client::Helper.new(self, options).signature_base_string
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# Since we expect to get the host etc details from the http instance (...),
|
67
|
+
# we create a fake url here. Surely this is a horrible, horrible idea?
|
68
|
+
def normalized_oauth_uri(http)
|
69
|
+
uri = URI.parse(normalize_uri.path)
|
70
|
+
uri.host = http.address
|
71
|
+
uri.port = http.port
|
72
|
+
|
73
|
+
if http.respond_to?(:use_ssl?) && http.use_ssl?
|
74
|
+
uri.scheme = "https"
|
75
|
+
else
|
76
|
+
uri.scheme = "http"
|
77
|
+
end
|
78
|
+
uri.to_s
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_oauth_header
|
82
|
+
headers = (self.options[:head] ||= {})
|
83
|
+
headers['Authorization'] = @oauth_helper.header
|
84
|
+
end
|
85
|
+
|
86
|
+
def set_oauth_body
|
87
|
+
raise NotImplementedError, 'please use the set_oauth_header method instead'
|
88
|
+
end
|
89
|
+
|
90
|
+
def set_oauth_query_string
|
91
|
+
raise NotImplementedError, 'please use the set_oauth_header method instead'
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/lib/oauth/client/helper.rb
CHANGED
@@ -36,14 +36,16 @@ module OAuth::Client
|
|
36
36
|
'oauth_timestamp' => timestamp,
|
37
37
|
'oauth_nonce' => nonce,
|
38
38
|
'oauth_verifier' => options[:oauth_verifier],
|
39
|
-
'oauth_version' => '1.0'
|
39
|
+
'oauth_version' => (options[:oauth_version] || '1.0')
|
40
40
|
}.reject { |k,v| v.to_s == "" }
|
41
41
|
end
|
42
42
|
|
43
43
|
def signature(extra_options = {})
|
44
44
|
OAuth::Signature.sign(@request, { :uri => options[:request_uri],
|
45
45
|
:consumer => options[:consumer],
|
46
|
-
:token => options[:token]
|
46
|
+
:token => options[:token],
|
47
|
+
:unsigned_parameters => options[:unsigned_parameters]
|
48
|
+
}.merge(extra_options) )
|
47
49
|
end
|
48
50
|
|
49
51
|
def signature_base_string(extra_options = {})
|
@@ -55,7 +57,8 @@ module OAuth::Client
|
|
55
57
|
|
56
58
|
def amend_user_agent_header(headers)
|
57
59
|
@oauth_ua_string ||= "OAuth gem v#{OAuth::VERSION}"
|
58
|
-
|
60
|
+
# Net::HTTP in 1.9 appends Ruby
|
61
|
+
if headers['User-Agent'] && headers['User-Agent'] != 'Ruby'
|
59
62
|
headers['User-Agent'] += " (#{@oauth_ua_string})"
|
60
63
|
else
|
61
64
|
headers['User-Agent'] = @oauth_ua_string
|
@@ -66,7 +69,7 @@ module OAuth::Client
|
|
66
69
|
parameters = oauth_parameters
|
67
70
|
parameters.merge!('oauth_signature' => signature(options.merge(:parameters => parameters)))
|
68
71
|
|
69
|
-
header_params_str = parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
|
72
|
+
header_params_str = parameters.sort.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
|
70
73
|
|
71
74
|
realm = "realm=\"#{options[:realm]}\", " if options[:realm]
|
72
75
|
"OAuth #{realm}#{header_params_str}"
|
@@ -80,18 +80,21 @@ private
|
|
80
80
|
self['Authorization'] = @oauth_helper.header
|
81
81
|
end
|
82
82
|
|
83
|
-
# FIXME: if you're using a POST body and query string parameters,
|
84
|
-
#
|
85
|
-
#
|
83
|
+
# FIXME: if you're using a POST body and query string parameters, this method
|
84
|
+
# will move query string parameters into the body unexpectedly. This may
|
85
|
+
# cause problems with non-x-www-form-urlencoded bodies submitted to URLs
|
86
|
+
# containing query string params. If duplicate parameters are present in both
|
87
|
+
# places, all instances should be included when calculating the signature
|
88
|
+
# base string.
|
89
|
+
|
86
90
|
def set_oauth_body
|
87
|
-
self.set_form_data(@oauth_helper.parameters_with_oauth)
|
91
|
+
self.set_form_data(@oauth_helper.stringify_keys(@oauth_helper.parameters_with_oauth))
|
88
92
|
params_with_sig = @oauth_helper.parameters.merge(:oauth_signature => @oauth_helper.signature)
|
89
|
-
self.set_form_data(params_with_sig)
|
93
|
+
self.set_form_data(@oauth_helper.stringify_keys(params_with_sig))
|
90
94
|
end
|
91
95
|
|
92
96
|
def set_oauth_query_string
|
93
97
|
oauth_params_str = @oauth_helper.oauth_parameters.map { |k,v| [escape(k), escape(v)] * "=" }.join("&")
|
94
|
-
|
95
98
|
uri = URI.parse(path)
|
96
99
|
if uri.query.to_s == ""
|
97
100
|
uri.query = oauth_params_str
|
data/lib/oauth/consumer.rb
CHANGED
@@ -3,6 +3,7 @@ require 'net/https'
|
|
3
3
|
require 'oauth/oauth'
|
4
4
|
require 'oauth/client/net_http'
|
5
5
|
require 'oauth/errors'
|
6
|
+
require 'cgi'
|
6
7
|
|
7
8
|
module OAuth
|
8
9
|
class Consumer
|
@@ -75,9 +76,9 @@ module OAuth
|
|
75
76
|
@secret = consumer_secret
|
76
77
|
|
77
78
|
# ensure that keys are symbols
|
78
|
-
@options = @@default_options.merge(options.inject({}) { |
|
79
|
-
|
80
|
-
|
79
|
+
@options = @@default_options.merge(options.inject({}) { |opts, (key, value)|
|
80
|
+
opts[key.to_sym] = value
|
81
|
+
opts
|
81
82
|
})
|
82
83
|
end
|
83
84
|
|
@@ -101,8 +102,8 @@ module OAuth
|
|
101
102
|
end
|
102
103
|
end
|
103
104
|
|
104
|
-
def get_access_token(request_token, request_options = {}, *arguments)
|
105
|
-
response = token_request(http_method, (access_token_url? ? access_token_url : access_token_path), request_token, request_options, *arguments)
|
105
|
+
def get_access_token(request_token, request_options = {}, *arguments, &block)
|
106
|
+
response = token_request(http_method, (access_token_url? ? access_token_url : access_token_path), request_token, request_options, *arguments, &block)
|
106
107
|
OAuth::AccessToken.from_hash(self, response)
|
107
108
|
end
|
108
109
|
|
@@ -120,12 +121,20 @@ module OAuth
|
|
120
121
|
# @request_token = @consumer.get_request_token({}, :foo => "bar")
|
121
122
|
#
|
122
123
|
# TODO oauth_callback should be a mandatory parameter
|
123
|
-
def get_request_token(request_options = {}, *arguments)
|
124
|
+
def get_request_token(request_options = {}, *arguments, &block)
|
124
125
|
# if oauth_callback wasn't provided, it is assumed that oauth_verifiers
|
125
126
|
# will be exchanged out of band
|
126
|
-
request_options[:oauth_callback] ||= OAuth::OUT_OF_BAND
|
127
|
-
|
128
|
-
|
127
|
+
request_options[:oauth_callback] ||= OAuth::OUT_OF_BAND unless request_options[:exclude_callback]
|
128
|
+
|
129
|
+
if block_given?
|
130
|
+
response = token_request(http_method,
|
131
|
+
(request_token_url? ? request_token_url : request_token_path),
|
132
|
+
nil,
|
133
|
+
request_options,
|
134
|
+
*arguments, &block)
|
135
|
+
else
|
136
|
+
response = token_request(http_method, (request_token_url? ? request_token_url : request_token_path), nil, request_options, *arguments)
|
137
|
+
end
|
129
138
|
OAuth::RequestToken.from_hash(self, response)
|
130
139
|
end
|
131
140
|
|
@@ -146,13 +155,16 @@ module OAuth
|
|
146
155
|
path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
|
147
156
|
end
|
148
157
|
|
149
|
-
|
158
|
+
# override the request with your own, this is useful for file uploads which Net::HTTP does not do
|
159
|
+
req = create_signed_request(http_method, path, token, request_options, *arguments)
|
160
|
+
return nil if block_given? and yield(req) == :done
|
161
|
+
rsp = http.request(req)
|
150
162
|
|
151
163
|
# check for an error reported by the Problem Reporting extension
|
152
164
|
# (http://wiki.oauth.net/ProblemReporting)
|
153
165
|
# note: a 200 may actually be an error; check for an oauth_problem key to be sure
|
154
166
|
if !(headers = rsp.to_hash["www-authenticate"]).nil? &&
|
155
|
-
(h = headers.select { |
|
167
|
+
(h = headers.select { |hdr| hdr =~ /^OAuth / }).any? &&
|
156
168
|
h.first =~ /oauth_problem/
|
157
169
|
|
158
170
|
# puts "Header: #{h.first}"
|
@@ -181,17 +193,20 @@ module OAuth
|
|
181
193
|
# Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.
|
182
194
|
def token_request(http_method, path, token = nil, request_options = {}, *arguments)
|
183
195
|
response = request(http_method, path, token, request_options, *arguments)
|
184
|
-
|
185
196
|
case response.code.to_i
|
186
197
|
|
187
198
|
when (200..299)
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
h
|
199
|
+
if block_given?
|
200
|
+
yield response.body
|
201
|
+
else
|
202
|
+
# symbolize keys
|
203
|
+
# TODO this could be considered unexpected behavior; symbols or not?
|
204
|
+
# TODO this also drops subsequent values from multi-valued keys
|
205
|
+
CGI.parse(response.body).inject({}) do |h,(k,v)|
|
206
|
+
h[k.strip.to_sym] = v.first
|
207
|
+
h[k.strip] = v.first
|
208
|
+
h
|
209
|
+
end
|
195
210
|
end
|
196
211
|
when (300..399)
|
197
212
|
# this is a redirect
|
@@ -298,7 +313,6 @@ module OAuth
|
|
298
313
|
|
299
314
|
if [:post, :put].include?(http_method)
|
300
315
|
data = arguments.shift
|
301
|
-
data.reject! { |k,v| v.nil? } if data.is_a?(Hash)
|
302
316
|
end
|
303
317
|
|
304
318
|
headers = arguments.first.is_a?(Hash) ? arguments.shift : {}
|
@@ -321,7 +335,9 @@ module OAuth
|
|
321
335
|
end
|
322
336
|
|
323
337
|
if data.is_a?(Hash)
|
324
|
-
|
338
|
+
form_data = {}
|
339
|
+
data.each {|k,v| form_data[k.to_s] = v if !v.nil?}
|
340
|
+
request.set_form_data(form_data)
|
325
341
|
elsif data
|
326
342
|
if data.respond_to?(:read)
|
327
343
|
request.body_stream = data
|
@@ -341,11 +357,15 @@ module OAuth
|
|
341
357
|
request
|
342
358
|
end
|
343
359
|
|
344
|
-
# Unset cached http instance because it cannot be marshalled when
|
345
|
-
# it has already been used and use_ssl is set to true
|
346
360
|
def marshal_dump(*args)
|
347
|
-
|
348
|
-
|
361
|
+
{:key => @key,
|
362
|
+
:secret => @secret,
|
363
|
+
:options => @options}
|
364
|
+
end
|
365
|
+
|
366
|
+
def marshal_load(data)
|
367
|
+
initialize(data[:key], data[:secret], data[:options])
|
349
368
|
end
|
369
|
+
|
350
370
|
end
|
351
371
|
end
|