monkeyhelper-oauth 0.3.1 → 0.3.5
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.
- data/History.txt +62 -17
- data/Manifest.txt +14 -1
- data/README.rdoc +7 -9
- data/Rakefile +7 -5
- data/TODO +17 -0
- data/bin/oauth +2 -2
- data/examples/yql.rb +44 -0
- data/lib/oauth/cli.rb +267 -31
- data/lib/oauth/client/action_controller_request.rb +14 -12
- data/lib/oauth/client/helper.rb +22 -14
- data/lib/oauth/client/net_http.rb +53 -22
- data/lib/oauth/consumer.rb +217 -111
- data/lib/oauth/errors/error.rb +4 -0
- data/lib/oauth/errors/problem.rb +14 -0
- data/lib/oauth/errors/unauthorized.rb +12 -0
- data/lib/oauth/errors.rb +3 -0
- data/lib/oauth/helper.rb +67 -6
- data/lib/oauth/oauth.rb +11 -0
- data/lib/oauth/oauth_test_helper.rb +12 -13
- data/lib/oauth/request_proxy/action_controller_request.rb +8 -8
- data/lib/oauth/request_proxy/base.rb +102 -44
- data/lib/oauth/request_proxy/jabber_request.rb +1 -2
- data/lib/oauth/request_proxy/mock_request.rb +8 -0
- data/lib/oauth/request_proxy/net_http.rb +2 -2
- data/lib/oauth/request_proxy/rack_request.rb +7 -7
- data/lib/oauth/server.rb +31 -33
- data/lib/oauth/signature/base.rb +23 -21
- data/lib/oauth/signature/hmac/base.rb +1 -1
- data/lib/oauth/signature/hmac/sha1.rb +0 -1
- data/lib/oauth/signature/plaintext.rb +2 -2
- data/lib/oauth/signature/rsa/sha1.rb +5 -4
- data/lib/oauth/signature.rb +9 -0
- data/lib/oauth/token.rb +6 -136
- data/lib/oauth/tokens/access_token.rb +68 -0
- data/lib/oauth/tokens/consumer_token.rb +33 -0
- data/lib/oauth/tokens/request_token.rb +32 -0
- data/lib/oauth/tokens/server_token.rb +9 -0
- data/lib/oauth/tokens/token.rb +17 -0
- data/lib/oauth/version.rb +1 -1
- data/lib/oauth.rb +1 -0
- data/oauth.gemspec +12 -6
- data/test/cases/spec/1_0-final/test_construct_request_url.rb +1 -1
- data/test/test_access_token.rb +28 -0
- data/test/test_action_controller_request_proxy.rb +105 -6
- data/test/test_consumer.rb +41 -5
- data/test/test_helper.rb +0 -5
- data/test/test_net_http_client.rb +38 -20
- data/test/test_net_http_request_proxy.rb +43 -8
- data/test/test_oauth_helper.rb +50 -0
- data/test/test_request_token.rb +53 -0
- data/test/test_server.rb +1 -1
- data/test/test_signature.rb +19 -11
- data/website/index.html +2 -2
- metadata +41 -3
data/lib/oauth/cli.rb
CHANGED
@@ -3,67 +3,198 @@ require 'oauth'
|
|
3
3
|
|
4
4
|
module OAuth
|
5
5
|
class CLI
|
6
|
-
SUPPORTED_COMMANDS =
|
6
|
+
SUPPORTED_COMMANDS = {
|
7
|
+
"authorize" => "Obtain an access token and secret for a user",
|
8
|
+
"debug" => "Verbosely generate an OAuth signature",
|
9
|
+
"query" => "Query a protected resource",
|
10
|
+
"sign" => "Generate an OAuth signature",
|
11
|
+
"version" => "Display the current version of the library"
|
12
|
+
}
|
7
13
|
|
8
14
|
attr_reader :command
|
9
15
|
attr_reader :options
|
10
|
-
attr_reader :stdout
|
16
|
+
attr_reader :stdout, :stdin
|
11
17
|
|
12
|
-
def self.execute(stdout, arguments = [])
|
13
|
-
self.new.execute(stdout, arguments)
|
18
|
+
def self.execute(stdout, stdin, stderr, arguments = [])
|
19
|
+
self.new.execute(stdout, stdin, stderr, arguments)
|
14
20
|
end
|
15
21
|
|
16
|
-
def
|
22
|
+
def initialize
|
23
|
+
@options = {}
|
24
|
+
|
25
|
+
# don't dump a backtrace on a ^C
|
26
|
+
trap(:INT) {
|
27
|
+
exit
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def execute(stdout, stdin, stderr, arguments = [])
|
17
32
|
@stdout = stdout
|
33
|
+
@stdin = stdin
|
34
|
+
@stderr = stderr
|
18
35
|
extract_command_and_parse_options(arguments)
|
19
36
|
|
20
37
|
if sufficient_options? && valid_command?
|
38
|
+
if command == "debug"
|
39
|
+
@command = "sign"
|
40
|
+
@options[:verbose] = true
|
41
|
+
end
|
42
|
+
|
21
43
|
case command
|
44
|
+
# TODO move command logic elsewhere
|
45
|
+
when "authorize"
|
46
|
+
begin
|
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 => options[:scheme]
|
54
|
+
|
55
|
+
# parameters for OAuth 1.0a
|
56
|
+
oauth_verifier = nil
|
57
|
+
|
58
|
+
# get a request token
|
59
|
+
request_token = consumer.get_request_token({ :oauth_callback => options[:oauth_callback] }, { :scope => options[:scope] })
|
60
|
+
|
61
|
+
if request_token.callback_confirmed?
|
62
|
+
stdout.puts "Server appears to support OAuth 1.0a; enabling support."
|
63
|
+
options[:version] = "1.0a"
|
64
|
+
end
|
65
|
+
|
66
|
+
stdout.puts "Please visit this url to authorize:"
|
67
|
+
stdout.puts request_token.authorize_url
|
68
|
+
|
69
|
+
if options[:version] == "1.0a"
|
70
|
+
stdout.puts "Please enter the verification code provided by the SP (oauth_verifier):"
|
71
|
+
oauth_verifier = stdin.gets.chomp
|
72
|
+
else
|
73
|
+
stdout.puts "Press return to continue..."
|
74
|
+
stdin.gets
|
75
|
+
end
|
76
|
+
|
77
|
+
begin
|
78
|
+
# get an access token
|
79
|
+
access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier)
|
80
|
+
|
81
|
+
stdout.puts "Response:"
|
82
|
+
access_token.params.each do |k,v|
|
83
|
+
stdout.puts " #{k}: #{v}" unless k.is_a?(Symbol)
|
84
|
+
end
|
85
|
+
rescue OAuth::Unauthorized => e
|
86
|
+
stderr.puts "A problem occurred while attempting to obtain an access token:"
|
87
|
+
stderr.puts e
|
88
|
+
stderr.puts e.request.body
|
89
|
+
end
|
90
|
+
rescue OAuth::Unauthorized => e
|
91
|
+
stderr.puts "A problem occurred while attempting to authorize:"
|
92
|
+
stderr.puts e
|
93
|
+
stderr.puts e.request.body
|
94
|
+
end
|
95
|
+
when "query"
|
96
|
+
consumer = OAuth::Consumer.new \
|
97
|
+
options[:oauth_consumer_key],
|
98
|
+
options[:oauth_consumer_secret],
|
99
|
+
:scheme => options[:scheme]
|
100
|
+
|
101
|
+
access_token = OAuth::AccessToken.new(consumer, options[:oauth_token], options[:oauth_token_secret])
|
102
|
+
|
103
|
+
response = access_token.request(options[:method].downcase.to_sym, options[:uri])
|
104
|
+
puts "#{response.code} #{response.message}"
|
105
|
+
puts response.body
|
22
106
|
when "sign"
|
107
|
+
parameters = prepare_parameters
|
108
|
+
|
23
109
|
request = OAuth::RequestProxy.proxy \
|
24
110
|
"method" => options[:method],
|
25
111
|
"uri" => options[:uri],
|
26
|
-
"parameters" =>
|
112
|
+
"parameters" => parameters
|
27
113
|
|
28
|
-
|
29
|
-
|
30
|
-
request,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
if
|
36
|
-
stdout.puts "
|
37
|
-
|
38
|
-
|
39
|
-
|
114
|
+
if verbose?
|
115
|
+
stdout.puts "OAuth parameters:"
|
116
|
+
request.oauth_parameters.each do |k,v|
|
117
|
+
stdout.puts " " + [k, v] * ": "
|
118
|
+
end
|
119
|
+
stdout.puts
|
120
|
+
|
121
|
+
if request.non_oauth_parameters.any?
|
122
|
+
stdout.puts "Parameters:"
|
123
|
+
request.non_oauth_parameters.each do |k,v|
|
124
|
+
stdout.puts " " + [k, v] * ": "
|
125
|
+
end
|
126
|
+
stdout.puts
|
40
127
|
end
|
41
128
|
end
|
42
129
|
|
130
|
+
request.sign! \
|
131
|
+
:consumer_secret => options[:oauth_consumer_secret],
|
132
|
+
:token_secret => options[:oauth_token_secret]
|
133
|
+
|
43
134
|
if verbose?
|
44
|
-
stdout.puts "
|
45
|
-
stdout.puts "
|
135
|
+
stdout.puts "Method: #{request.method}"
|
136
|
+
stdout.puts "URI: #{request.uri}"
|
137
|
+
stdout.puts "Normalized params: #{request.normalized_parameters}" unless options[:xmpp]
|
138
|
+
stdout.puts "Signature base string: #{request.signature_base_string}"
|
139
|
+
|
140
|
+
if options[:xmpp]
|
141
|
+
stdout.puts
|
142
|
+
stdout.puts "XMPP Stanza:"
|
143
|
+
stdout.puts <<-EOS
|
144
|
+
<oauth xmlns='urn:xmpp:oauth:0'>
|
145
|
+
<oauth_consumer_key>#{request.oauth_consumer_key}</oauth_consumer_key>
|
146
|
+
<oauth_token>#{request.oauth_token}</oauth_token>
|
147
|
+
<oauth_signature_method>#{request.oauth_signature_method}</oauth_signature_method>
|
148
|
+
<oauth_signature>#{request.oauth_signature}</oauth_signature>
|
149
|
+
<oauth_timestamp>#{request.oauth_timestamp}</oauth_timestamp>
|
150
|
+
<oauth_nonce>#{request.oauth_nonce}</oauth_nonce>
|
151
|
+
<oauth_version>#{request.oauth_version}</oauth_version>
|
152
|
+
</oauth>
|
153
|
+
EOS
|
154
|
+
stdout.puts
|
155
|
+
stdout.puts "Note: You may want to use bare JIDs in your URI."
|
156
|
+
stdout.puts
|
157
|
+
else
|
158
|
+
stdout.puts "OAuth Request URI: #{request.signed_uri}"
|
159
|
+
stdout.puts "Request URI: #{request.signed_uri(false)}"
|
160
|
+
stdout.puts "Authorization header: #{request.oauth_header(:realm => options[:realm])}"
|
161
|
+
end
|
162
|
+
stdout.puts "Signature: #{request.oauth_signature}"
|
163
|
+
stdout.puts "Escaped signature: #{OAuth::Helper.escape(request.oauth_signature)}"
|
46
164
|
else
|
47
|
-
stdout.puts
|
165
|
+
stdout.puts request.oauth_signature
|
48
166
|
end
|
167
|
+
when "version"
|
168
|
+
puts "OAuth for Ruby #{OAuth::VERSION}"
|
49
169
|
end
|
50
170
|
else
|
51
171
|
usage
|
52
172
|
end
|
53
173
|
end
|
54
174
|
|
175
|
+
protected
|
176
|
+
|
55
177
|
def extract_command_and_parse_options(arguments)
|
56
178
|
@command = arguments[-1]
|
57
179
|
parse_options(arguments[0..-1])
|
58
180
|
end
|
59
181
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
182
|
+
def option_parser(arguments = "")
|
183
|
+
# TODO add realm parameter
|
184
|
+
# TODO add user-agent parameter
|
185
|
+
option_parser = OptionParser.new do |opts|
|
63
186
|
opts.banner = "Usage: #{$0} [options] <command>"
|
64
187
|
|
65
188
|
# defaults
|
189
|
+
options[:oauth_nonce] = OAuth::Helper.generate_key
|
66
190
|
options[:oauth_signature_method] = "HMAC-SHA1"
|
191
|
+
options[:oauth_timestamp] = OAuth::Helper.generate_timestamp
|
192
|
+
options[:oauth_version] = "1.0"
|
193
|
+
options[:params] = []
|
194
|
+
options[:scheme] = :header
|
195
|
+
options[:version] = "1.0"
|
196
|
+
|
197
|
+
## Common Options
|
67
198
|
|
68
199
|
opts.on("--consumer-key KEY", "Specifies the consumer key to use.") do |v|
|
69
200
|
options[:oauth_consumer_key] = v
|
@@ -73,12 +204,32 @@ module OAuth
|
|
73
204
|
options[:oauth_consumer_secret] = v
|
74
205
|
end
|
75
206
|
|
207
|
+
opts.on("-H", "--header", "Use the 'Authorization' header for OAuth parameters (default).") do
|
208
|
+
options[:scheme] = :header
|
209
|
+
end
|
210
|
+
|
211
|
+
opts.on("-Q", "--query-string", "Use the query string for OAuth parameters.") do
|
212
|
+
options[:scheme] = :query_string
|
213
|
+
end
|
214
|
+
|
215
|
+
opts.on("-O", "--options FILE", "Read options from a file") do |v|
|
216
|
+
arguments.unshift(*open(v).readlines.map { |l| l.chomp.split(" ") }.flatten)
|
217
|
+
end
|
218
|
+
|
219
|
+
## Options for signing and making requests
|
220
|
+
|
221
|
+
opts.separator("\n options for signing and querying")
|
222
|
+
|
76
223
|
opts.on("--method METHOD", "Specifies the method (e.g. GET) to use when signing.") do |v|
|
77
224
|
options[:method] = v
|
78
225
|
end
|
79
226
|
|
227
|
+
opts.on("--nonce NONCE", "Specifies the none to use.") do |v|
|
228
|
+
options[:oauth_nonce] = v
|
229
|
+
end
|
230
|
+
|
80
231
|
opts.on("--parameters PARAMS", "Specifies the parameters to use when signing.") do |v|
|
81
|
-
options[:params]
|
232
|
+
options[:params] << v
|
82
233
|
end
|
83
234
|
|
84
235
|
opts.on("--signature-method METHOD", "Specifies the signature method to use; defaults to HMAC-SHA1.") do |v|
|
@@ -89,38 +240,123 @@ module OAuth
|
|
89
240
|
options[:oauth_token_secret] = v
|
90
241
|
end
|
91
242
|
|
243
|
+
opts.on("--timestamp TIMESTAMP", "Specifies the timestamp to use.") do |v|
|
244
|
+
options[:oauth_timestamp] = v
|
245
|
+
end
|
246
|
+
|
92
247
|
opts.on("--token TOKEN", "Specifies the token to use.") do |v|
|
93
248
|
options[:oauth_token] = v
|
94
249
|
end
|
95
250
|
|
251
|
+
opts.on("--realm REALM", "Specifies the realm to use.") do |v|
|
252
|
+
options[:realm] = v
|
253
|
+
end
|
254
|
+
|
96
255
|
opts.on("--uri URI", "Specifies the URI to use when signing.") do |v|
|
97
256
|
options[:uri] = v
|
98
257
|
end
|
99
258
|
|
259
|
+
opts.on(:OPTIONAL, "--version VERSION", "Specifies the OAuth version to use.") do |v|
|
260
|
+
if v
|
261
|
+
options[:oauth_version] = v
|
262
|
+
else
|
263
|
+
@command = "version"
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
opts.on("--no-version", "Omit oauth_version.") do
|
268
|
+
options[:oauth_version] = nil
|
269
|
+
end
|
270
|
+
|
271
|
+
opts.on("--xmpp", "Generate XMPP stanzas.") do
|
272
|
+
options[:xmpp] = true
|
273
|
+
options[:method] ||= "iq"
|
274
|
+
end
|
275
|
+
|
100
276
|
opts.on("-v", "--verbose", "Be verbose.") do
|
101
277
|
options[:verbose] = true
|
102
278
|
end
|
103
|
-
|
279
|
+
|
280
|
+
## Options for authorization
|
281
|
+
|
282
|
+
opts.separator("\n options for authorization")
|
283
|
+
|
284
|
+
opts.on("--access-token-url URL", "Specifies the access token URL.") do |v|
|
285
|
+
options[:access_token_url] = v
|
286
|
+
end
|
287
|
+
|
288
|
+
opts.on("--authorize-url URL", "Specifies the authorization URL.") do |v|
|
289
|
+
options[:authorize_url] = v
|
290
|
+
end
|
291
|
+
|
292
|
+
opts.on("--callback-url URL", "Specifies a callback URL.") do |v|
|
293
|
+
options[:oauth_callback] = v
|
294
|
+
end
|
295
|
+
|
296
|
+
opts.on("--request-token-url URL", "Specifies the request token URL.") do |v|
|
297
|
+
options[:request_token_url] = v
|
298
|
+
end
|
299
|
+
|
300
|
+
opts.on("--scope SCOPE", "Specifies the scope (Google-specific).") do |v|
|
301
|
+
options[:scope] = v
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def parse_options(arguments)
|
307
|
+
option_parser(arguments).parse!(arguments)
|
104
308
|
end
|
105
309
|
|
106
310
|
def prepare_parameters
|
311
|
+
escaped_pairs = options[:params].collect do |pair|
|
312
|
+
if pair =~ /:/
|
313
|
+
Hash[*pair.split(":", 2)].collect do |k,v|
|
314
|
+
[CGI.escape(k.strip), CGI.escape(v.strip)] * "="
|
315
|
+
end
|
316
|
+
else
|
317
|
+
pair
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
querystring = escaped_pairs * "&"
|
322
|
+
cli_params = CGI.parse(querystring)
|
323
|
+
|
107
324
|
{
|
108
325
|
"oauth_consumer_key" => options[:oauth_consumer_key],
|
326
|
+
"oauth_nonce" => options[:oauth_nonce],
|
327
|
+
"oauth_timestamp" => options[:oauth_timestamp],
|
109
328
|
"oauth_token" => options[:oauth_token],
|
110
|
-
"oauth_signature_method" => options[:oauth_signature_method]
|
111
|
-
|
329
|
+
"oauth_signature_method" => options[:oauth_signature_method],
|
330
|
+
"oauth_version" => options[:oauth_version]
|
331
|
+
}.reject { |k,v| v.nil? || v == "" }.merge(cli_params)
|
112
332
|
end
|
113
333
|
|
114
334
|
def sufficient_options?
|
115
|
-
|
335
|
+
case command
|
336
|
+
# TODO move command logic elsewhere
|
337
|
+
when "authorize"
|
338
|
+
options[:oauth_consumer_key] && options[:oauth_consumer_secret] &&
|
339
|
+
options[:access_token_url] && options[:authorize_url] &&
|
340
|
+
options[:request_token_url]
|
341
|
+
when "version"
|
342
|
+
true
|
343
|
+
else
|
344
|
+
options[:oauth_consumer_key] && options[:oauth_consumer_secret] &&
|
345
|
+
options[:method] && options[:uri]
|
346
|
+
end
|
116
347
|
end
|
117
348
|
|
118
349
|
def usage
|
119
|
-
stdout.puts
|
350
|
+
stdout.puts option_parser.help
|
351
|
+
stdout.puts
|
352
|
+
stdout.puts "Available commands:"
|
353
|
+
SUPPORTED_COMMANDS.each do |command, desc|
|
354
|
+
puts " #{command.ljust(15)}#{desc}"
|
355
|
+
end
|
120
356
|
end
|
121
357
|
|
122
358
|
def valid_command?
|
123
|
-
SUPPORTED_COMMANDS.include?(command)
|
359
|
+
SUPPORTED_COMMANDS.keys.include?(command)
|
124
360
|
end
|
125
361
|
|
126
362
|
def verbose?
|
@@ -4,9 +4,9 @@ require 'action_controller/test_process'
|
|
4
4
|
|
5
5
|
module ActionController
|
6
6
|
class Base
|
7
|
-
def process_with_oauth(request,response=nil)
|
7
|
+
def process_with_oauth(request, response=nil)
|
8
8
|
request.apply_oauth!
|
9
|
-
process_without_oauth(request,response)
|
9
|
+
process_without_oauth(request, response)
|
10
10
|
end
|
11
11
|
|
12
12
|
alias_method_chain :process, :oauth
|
@@ -18,21 +18,23 @@ module ActionController
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.use_oauth?
|
21
|
-
@use_oauth
|
21
|
+
@use_oauth
|
22
22
|
end
|
23
23
|
|
24
24
|
def configure_oauth(consumer = nil, token = nil, options = {})
|
25
|
-
@oauth_options = { :consumer
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
@oauth_options = { :consumer => consumer,
|
26
|
+
:token => token,
|
27
|
+
:scheme => 'header',
|
28
|
+
:signature_method => nil,
|
29
|
+
:nonce => nil,
|
30
|
+
:timestamp => nil }.merge(options)
|
31
31
|
end
|
32
32
|
|
33
33
|
def apply_oauth!
|
34
34
|
return unless ActionController::TestRequest.use_oauth? && @oauth_options
|
35
|
-
|
35
|
+
|
36
|
+
@oauth_helper = OAuth::Client::Helper.new(self, @oauth_options.merge(:request_uri => request_uri))
|
37
|
+
@oauth_helper.amend_user_agent_header(env)
|
36
38
|
|
37
39
|
self.send("set_oauth_#{@oauth_options[:scheme]}")
|
38
40
|
end
|
@@ -43,9 +45,9 @@ module ActionController
|
|
43
45
|
|
44
46
|
def set_oauth_parameters
|
45
47
|
@query_parameters = @oauth_helper.parameters_with_oauth
|
46
|
-
@query_parameters.merge!(
|
48
|
+
@query_parameters.merge!(:oauth_signature => @oauth_helper.signature)
|
47
49
|
end
|
48
|
-
|
50
|
+
|
49
51
|
def set_oauth_query_string
|
50
52
|
end
|
51
53
|
end
|
data/lib/oauth/client/helper.rb
CHANGED
@@ -2,12 +2,13 @@ require 'oauth/client'
|
|
2
2
|
require 'oauth/consumer'
|
3
3
|
require 'oauth/helper'
|
4
4
|
require 'oauth/token'
|
5
|
+
require 'oauth/version'
|
5
6
|
require 'oauth/signature/hmac/sha1'
|
6
7
|
|
7
8
|
module OAuth::Client
|
8
9
|
class Helper
|
9
10
|
include OAuth::Helper
|
10
|
-
|
11
|
+
|
11
12
|
def initialize(request, options = {})
|
12
13
|
@request = request
|
13
14
|
@options = options
|
@@ -26,37 +27,44 @@ module OAuth::Client
|
|
26
27
|
options[:timestamp] ||= generate_timestamp
|
27
28
|
end
|
28
29
|
|
29
|
-
def generate_timestamp
|
30
|
-
Time.now.to_i.to_s
|
31
|
-
end
|
32
|
-
|
33
30
|
def oauth_parameters
|
34
31
|
{
|
32
|
+
'oauth_callback' => options[:oauth_callback],
|
35
33
|
'oauth_consumer_key' => options[:consumer].key,
|
36
34
|
'oauth_token' => options[:token] ? options[:token].token : '',
|
37
35
|
'oauth_signature_method' => options[:signature_method],
|
38
36
|
'oauth_timestamp' => timestamp,
|
39
37
|
'oauth_nonce' => nonce,
|
38
|
+
'oauth_verifier' => options[:oauth_verifier],
|
40
39
|
'oauth_version' => '1.0'
|
41
|
-
}.reject { |k,v| v == "" }
|
40
|
+
}.reject { |k,v| v.to_s == "" }
|
42
41
|
end
|
43
42
|
|
44
43
|
def signature(extra_options = {})
|
45
44
|
OAuth::Signature.sign(@request, { :uri => options[:request_uri],
|
46
|
-
|
47
|
-
|
45
|
+
:consumer => options[:consumer],
|
46
|
+
:token => options[:token] }.merge(extra_options) )
|
48
47
|
end
|
49
48
|
|
50
49
|
def signature_base_string(extra_options = {})
|
51
|
-
OAuth::Signature.signature_base_string(@request, { :uri
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
OAuth::Signature.signature_base_string(@request, { :uri => options[:request_uri],
|
51
|
+
:consumer => options[:consumer],
|
52
|
+
:token => options[:token],
|
53
|
+
:parameters => oauth_parameters}.merge(extra_options) )
|
54
|
+
end
|
55
|
+
|
56
|
+
def amend_user_agent_header(headers)
|
57
|
+
@oauth_ua_string ||= "OAuth gem v#{OAuth::VERSION}"
|
58
|
+
if headers['User-Agent']
|
59
|
+
headers['User-Agent'] += " (#{@oauth_ua_string})"
|
60
|
+
else
|
61
|
+
headers['User-Agent'] = @oauth_ua_string
|
62
|
+
end
|
55
63
|
end
|
56
64
|
|
57
65
|
def header
|
58
66
|
parameters = oauth_parameters
|
59
|
-
parameters.merge!(
|
67
|
+
parameters.merge!('oauth_signature' => signature(options.merge(:parameters => parameters)))
|
60
68
|
|
61
69
|
header_params_str = parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
|
62
70
|
|
@@ -69,7 +77,7 @@ module OAuth::Client
|
|
69
77
|
end
|
70
78
|
|
71
79
|
def parameters_with_oauth
|
72
|
-
oauth_parameters.merge(
|
80
|
+
oauth_parameters.merge(parameters)
|
73
81
|
end
|
74
82
|
end
|
75
83
|
end
|
@@ -5,43 +5,74 @@ require 'oauth/request_proxy/net_http'
|
|
5
5
|
class Net::HTTPRequest
|
6
6
|
include OAuth::Helper
|
7
7
|
|
8
|
+
attr_reader :oauth_helper
|
9
|
+
|
10
|
+
# Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
|
11
|
+
# this may add a header, additional query string parameters, or additional POST body parameters.
|
12
|
+
# The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
|
13
|
+
# header.
|
14
|
+
#
|
15
|
+
# * http - Configured Net::HTTP instance
|
16
|
+
# * consumer - OAuth::Consumer instance
|
17
|
+
# * token - OAuth::Token instance
|
18
|
+
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
|
19
|
+
# +signature_method+, +nonce+, +timestamp+)
|
20
|
+
#
|
21
|
+
# This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
|
22
|
+
#
|
23
|
+
# See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1]
|
8
24
|
def oauth!(http, consumer = nil, token = nil, options = {})
|
9
|
-
options = { :request_uri
|
10
|
-
:consumer
|
11
|
-
:token
|
12
|
-
:scheme
|
25
|
+
options = { :request_uri => oauth_full_request_uri(http),
|
26
|
+
:consumer => consumer,
|
27
|
+
:token => token,
|
28
|
+
:scheme => 'header',
|
13
29
|
:signature_method => nil,
|
14
|
-
:nonce
|
15
|
-
:timestamp
|
30
|
+
:nonce => nil,
|
31
|
+
:timestamp => nil }.merge(options)
|
16
32
|
|
17
33
|
@oauth_helper = OAuth::Client::Helper.new(self, options)
|
34
|
+
@oauth_helper.amend_user_agent_header(self)
|
18
35
|
self.send("set_oauth_#{options[:scheme]}")
|
19
36
|
end
|
20
37
|
|
38
|
+
# Create a string suitable for signing for an HTTP request. This process involves parameter
|
39
|
+
# normalization as specified in the OAuth specification. The exact normalization also depends
|
40
|
+
# on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
|
41
|
+
# itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
|
42
|
+
# header.
|
43
|
+
#
|
44
|
+
# * http - Configured Net::HTTP instance
|
45
|
+
# * consumer - OAuth::Consumer instance
|
46
|
+
# * token - OAuth::Token instance
|
47
|
+
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
|
48
|
+
# +signature_method+, +nonce+, +timestamp+)
|
49
|
+
#
|
50
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
21
51
|
def signature_base_string(http, consumer = nil, token = nil, options = {})
|
22
|
-
options = { :request_uri
|
23
|
-
:consumer
|
24
|
-
:token
|
25
|
-
:scheme
|
52
|
+
options = { :request_uri => oauth_full_request_uri(http),
|
53
|
+
:consumer => consumer,
|
54
|
+
:token => token,
|
55
|
+
:scheme => 'header',
|
26
56
|
:signature_method => nil,
|
27
|
-
:nonce
|
28
|
-
:timestamp
|
57
|
+
:nonce => nil,
|
58
|
+
:timestamp => nil }.merge(options)
|
29
59
|
|
30
60
|
OAuth::Client::Helper.new(self, options).signature_base_string
|
31
61
|
end
|
32
|
-
|
33
|
-
|
34
|
-
@oauth_helper
|
35
|
-
end
|
36
|
-
private
|
62
|
+
|
63
|
+
private
|
37
64
|
|
38
65
|
def oauth_full_request_uri(http)
|
39
66
|
uri = URI.parse(self.path)
|
40
67
|
uri.host = http.address
|
41
68
|
uri.port = http.port
|
42
|
-
|
43
|
-
|
69
|
+
|
70
|
+
if http.respond_to?(:use_ssl?) && http.use_ssl?
|
71
|
+
uri.scheme = "https"
|
72
|
+
else
|
73
|
+
uri.scheme = "http"
|
44
74
|
end
|
75
|
+
|
45
76
|
uri.to_s
|
46
77
|
end
|
47
78
|
|
@@ -59,10 +90,10 @@ class Net::HTTPRequest
|
|
59
90
|
end
|
60
91
|
|
61
92
|
def set_oauth_query_string
|
62
|
-
oauth_params_str = @oauth_helper.oauth_parameters.map { |k,v|
|
93
|
+
oauth_params_str = @oauth_helper.oauth_parameters.map { |k,v| [escape(k), escape(v)] * "=" }.join("&")
|
63
94
|
|
64
95
|
uri = URI.parse(path)
|
65
|
-
if
|
96
|
+
if uri.query.to_s == ""
|
66
97
|
uri.query = oauth_params_str
|
67
98
|
else
|
68
99
|
uri.query = uri.query + "&" + oauth_params_str
|
@@ -70,6 +101,6 @@ class Net::HTTPRequest
|
|
70
101
|
|
71
102
|
@path = uri.to_s
|
72
103
|
|
73
|
-
@path << "&oauth_signature=#{escape(
|
104
|
+
@path << "&oauth_signature=#{escape(oauth_helper.signature)}"
|
74
105
|
end
|
75
106
|
end
|