oauth 0.1.1
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/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +35 -0
- data/README.txt +1 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +71 -0
- data/config/requirements.rb +17 -0
- data/lib/oauth.rb +14 -0
- data/lib/oauth/consumer.rb +123 -0
- data/lib/oauth/consumer_credentials.rb +12 -0
- data/lib/oauth/key.rb +15 -0
- data/lib/oauth/oauth_test_helper.rb +24 -0
- data/lib/oauth/request.rb +258 -0
- data/lib/oauth/server.rb +65 -0
- data/lib/oauth/signature.rb +155 -0
- data/lib/oauth/token.rb +83 -0
- data/lib/oauth/version.rb +9 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_consumer.rb +116 -0
- data/test/test_helper.rb +2 -0
- data/test/test_oauth.rb +11 -0
- data/test/test_request.rb +282 -0
- data/test/test_server.rb +47 -0
- data/test/test_signature.rb +113 -0
- data/website/index.html +133 -0
- data/website/index.txt +66 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +105 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Pelle Braendgaard
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
config/hoe.rb
|
7
|
+
config/requirements.rb
|
8
|
+
lib/oauth.rb
|
9
|
+
lib/oauth/consumer.rb
|
10
|
+
lib/oauth/consumer_credentials.rb
|
11
|
+
lib/oauth/key.rb
|
12
|
+
lib/oauth/oauth_test_helper.rb
|
13
|
+
lib/oauth/request.rb
|
14
|
+
lib/oauth/server.rb
|
15
|
+
lib/oauth/signature.rb
|
16
|
+
lib/oauth/token.rb
|
17
|
+
lib/oauth/version.rb
|
18
|
+
script/destroy
|
19
|
+
script/generate
|
20
|
+
script/txt2html
|
21
|
+
setup.rb
|
22
|
+
tasks/deployment.rake
|
23
|
+
tasks/environment.rake
|
24
|
+
tasks/website.rake
|
25
|
+
test/test_consumer.rb
|
26
|
+
test/test_helper.rb
|
27
|
+
test/test_oauth.rb
|
28
|
+
test/test_request.rb
|
29
|
+
test/test_server.rb
|
30
|
+
test/test_signature.rb
|
31
|
+
website/index.html
|
32
|
+
website/index.txt
|
33
|
+
website/javascripts/rounded_corners_lite.inc.js
|
34
|
+
website/stylesheets/screen.css
|
35
|
+
website/template.rhtml
|
data/README.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
README
|
data/Rakefile
ADDED
data/config/hoe.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'oauth/version'
|
2
|
+
|
3
|
+
AUTHOR = 'Pelle Braendgaard' # can also be an array of Authors
|
4
|
+
EMAIL = "pelleb@gmail.com"
|
5
|
+
DESCRIPTION = "OAuth Core Ruby implementation"
|
6
|
+
GEM_NAME = 'oauth' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'oauth' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
|
11
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
12
|
+
@config = nil
|
13
|
+
RUBYFORGE_USERNAME = "unknown"
|
14
|
+
def rubyforge_username
|
15
|
+
unless @config
|
16
|
+
begin
|
17
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
18
|
+
rescue
|
19
|
+
puts <<-EOS
|
20
|
+
ERROR: No rubyforge config file found: #{@config_file}
|
21
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
22
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
23
|
+
EOS
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
REV = nil
|
32
|
+
# UNCOMMENT IF REQUIRED:
|
33
|
+
# REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
|
34
|
+
VERS = Oauth::VERSION::STRING + (REV ? ".#{REV}" : "")
|
35
|
+
RDOC_OPTS = ['--quiet', '--title', 'oauth documentation',
|
36
|
+
"--opname", "index.html",
|
37
|
+
"--line-numbers",
|
38
|
+
"--main", "README",
|
39
|
+
"--inline-source"]
|
40
|
+
|
41
|
+
class Hoe
|
42
|
+
def extra_deps
|
43
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
44
|
+
@extra_deps
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Generate all the Rake tasks
|
49
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
50
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
51
|
+
p.author = AUTHOR
|
52
|
+
p.description = DESCRIPTION
|
53
|
+
p.email = EMAIL
|
54
|
+
p.summary = DESCRIPTION
|
55
|
+
p.url = HOMEPATH
|
56
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
57
|
+
p.test_globs = ["test/**/test_*.rb"]
|
58
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
59
|
+
|
60
|
+
# == Optional
|
61
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
62
|
+
p.extra_deps = [['ruby-hmac','>= 0.3.1'] ] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
63
|
+
|
64
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
69
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
70
|
+
hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
71
|
+
hoe.rsync_args = '-av --delete --ignore-errors'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe newgem rubigen].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
16
|
+
|
17
|
+
require 'oauth'
|
data/lib/oauth.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require 'oauth/key'
|
4
|
+
require 'oauth/request'
|
5
|
+
require 'oauth/signature'
|
6
|
+
require 'oauth/consumer_credentials'
|
7
|
+
require 'oauth/consumer'
|
8
|
+
require 'oauth/server'
|
9
|
+
require 'oauth/token'
|
10
|
+
require 'oauth/oauth_test_helper'
|
11
|
+
|
12
|
+
module OAuth
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module OAuth
|
2
|
+
class Consumer<ConsumerCredentials
|
3
|
+
|
4
|
+
@@default_params={
|
5
|
+
# Signature method used by server. Defaults to HMAC-SHA1
|
6
|
+
:oauth_signature_method=>'HMAC-SHA1',
|
7
|
+
|
8
|
+
# default paths on site. These are the same as the defaults set up by the generators
|
9
|
+
:request_token_path=>'/oauth/request_token',
|
10
|
+
:authorize_path=>'/oauth/authorize',
|
11
|
+
:access_token_path=>'/oauth/access_token',
|
12
|
+
|
13
|
+
# How do we send the oauth values to the server see
|
14
|
+
# http://oauth.googlecode.com/svn/spec/branches/1.0/drafts/6/spec.html#consumer_req_param for more info
|
15
|
+
#
|
16
|
+
# Possible values:
|
17
|
+
#
|
18
|
+
# :authorize - via the Authorize header (Default) ( option 1. in spec)
|
19
|
+
# :post - url form encoded in body of POST request ( option 2. in spec)
|
20
|
+
# :query - via the query part of the url ( option 3. in spec)
|
21
|
+
:auth_method=>:authorize,
|
22
|
+
|
23
|
+
# Default http method used for OAuth Token Requests (defaults to :post)
|
24
|
+
:http_method=>:post,
|
25
|
+
|
26
|
+
:oauth_version=>"1.0"
|
27
|
+
}
|
28
|
+
|
29
|
+
attr_accessor :site,:params
|
30
|
+
|
31
|
+
# Create a new consumer instance by passing it a configuration hash:
|
32
|
+
#
|
33
|
+
# @consumer=OAuth::Consumer.new( {
|
34
|
+
# :consumer_key=>"key",
|
35
|
+
# :consumer_secret=>"secret",
|
36
|
+
# :site=>"http://term.ie",
|
37
|
+
# :auth_method=>:authorize,
|
38
|
+
# :http_method=>:post,
|
39
|
+
# :request_token_path=>"/oauth/example/request_token.php",
|
40
|
+
# :access_token_path=>"/oauth/example/access_token.php",
|
41
|
+
# :authorize_path=>"/oauth/example/authorize.php"
|
42
|
+
# })
|
43
|
+
#
|
44
|
+
# Start the process by requesting a token
|
45
|
+
#
|
46
|
+
# @request_token=@consumer.request_token
|
47
|
+
# session[:request_token]=@request_token
|
48
|
+
# redirect_to @request_token.authorize_url
|
49
|
+
#
|
50
|
+
# When user returns create an access_token
|
51
|
+
#
|
52
|
+
# @access_token=@request_token.access_token
|
53
|
+
# @photos=@access_token.get('http://test.com/photos.xml')
|
54
|
+
#
|
55
|
+
#
|
56
|
+
|
57
|
+
def initialize(params)
|
58
|
+
# ensure that keys are symbols
|
59
|
+
@params=@@default_params.merge( params.inject({}) do |options, (key, value)|
|
60
|
+
options[key.to_sym] = value
|
61
|
+
options
|
62
|
+
end)
|
63
|
+
super @params[:consumer_key],@params[:consumer_secret]
|
64
|
+
@site=@params[:site]
|
65
|
+
raise ArgumentError, 'Missing site URI' unless @site
|
66
|
+
end
|
67
|
+
|
68
|
+
def http_method
|
69
|
+
@http_method||=@params[:http_method]||:post
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get a Request Token
|
73
|
+
def get_request_token
|
74
|
+
request=create_request(http_method,request_token_path)
|
75
|
+
response=request.perform_token_request(self.secret)
|
76
|
+
OAuth::RequestToken.new(self,response[:oauth_token],response[:oauth_token_secret])
|
77
|
+
end
|
78
|
+
|
79
|
+
def create_request(http_method,path, oauth_params={},*arguments)
|
80
|
+
OAuth::Request.new(http_method,site,path,oauth_params.merge({
|
81
|
+
:oauth_consumer_key=>self.key,
|
82
|
+
:realm=>authorize_url,
|
83
|
+
:oauth_signature_method=>params[:oauth_signature_method],
|
84
|
+
:oauth_version=>params[:oauth_version],
|
85
|
+
:auth_method=>auth_method
|
86
|
+
}),*arguments)
|
87
|
+
end
|
88
|
+
|
89
|
+
def signed_request(http_method, path, oauth_params={},token_secret=nil,*arguments)
|
90
|
+
request=create_request(http_method,path,oauth_params,*arguments)
|
91
|
+
request.sign(self.secret,token_secret)
|
92
|
+
request
|
93
|
+
end
|
94
|
+
|
95
|
+
def auth_method
|
96
|
+
@params[:auth_method]
|
97
|
+
end
|
98
|
+
|
99
|
+
def request_token_path
|
100
|
+
@params[:request_token_path]
|
101
|
+
end
|
102
|
+
|
103
|
+
def authorize_path
|
104
|
+
@params[:authorize_path]
|
105
|
+
end
|
106
|
+
|
107
|
+
def access_token_path
|
108
|
+
@params[:access_token_path]
|
109
|
+
end
|
110
|
+
|
111
|
+
def request_token_url
|
112
|
+
site+request_token_path
|
113
|
+
end
|
114
|
+
|
115
|
+
def authorize_url
|
116
|
+
site+authorize_path
|
117
|
+
end
|
118
|
+
|
119
|
+
def access_token_url
|
120
|
+
site+access_token_path
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/oauth/key.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
module OAuth
|
4
|
+
module Key
|
5
|
+
def generate_key(size=32)
|
6
|
+
Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/,'')
|
7
|
+
end
|
8
|
+
|
9
|
+
# Based on Blaine's example from the Oauth mailing list
|
10
|
+
def escape(value)
|
11
|
+
CGI.escape(value.to_s).gsub("%7E", "~").gsub("+", "%20")
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module OAuth
|
2
|
+
module OAuthTestHelper
|
3
|
+
|
4
|
+
def mock_incoming_request_with_query(request)
|
5
|
+
incoming=ActionController::TestRequest.new(request.to_hash)
|
6
|
+
incoming.request_uri=request.path
|
7
|
+
incoming.env["SERVER_PORT"]=request.uri.port
|
8
|
+
incoming.host=request.uri.host
|
9
|
+
incoming.env['REQUEST_METHOD']=request.http_method
|
10
|
+
incoming
|
11
|
+
end
|
12
|
+
|
13
|
+
def mock_incoming_request_with_authorize_header(request)
|
14
|
+
incoming=ActionController::TestRequest.new
|
15
|
+
incoming.env["HTTP_AUTHORIZATION"]=request.to_auth_string
|
16
|
+
incoming.request_uri=request.path
|
17
|
+
incoming.env["SERVER_PORT"]=request.uri.port
|
18
|
+
incoming.host=request.uri.host
|
19
|
+
incoming.env['REQUEST_METHOD']=request.http_method
|
20
|
+
incoming
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'net/http'
|
5
|
+
module OAuth
|
6
|
+
# This encapsulates all the request details for OAuth.
|
7
|
+
#
|
8
|
+
# On the consumer side you shouldn't use this directly but rather Use consumer.get_request_token for the initial token
|
9
|
+
# and access token for actual web service calls
|
10
|
+
#
|
11
|
+
# On the service provider side there are various interesting methods.
|
12
|
+
#
|
13
|
+
# To find the consumer_key for a request in a rails app do:
|
14
|
+
#
|
15
|
+
# @consumer_key=OAuth::Request.extract_consumer_key(request)
|
16
|
+
#
|
17
|
+
# To extract an OAuth::Request for a rails request in a rails app do:
|
18
|
+
#
|
19
|
+
# @oauth_request=OAuth::Request.incoming(request)
|
20
|
+
# @token=AccessToken.find_by_token @oauth_request.token
|
21
|
+
# return @oauth_request.verify?(@token.client_application.secret,@token.secret)
|
22
|
+
#
|
23
|
+
# This example assumes an ActiveRecord Model called AccessToken with a token and a secret column.
|
24
|
+
# This is associated with a ActiveRecord Model ClientApplication (the consumer), which has a key and secret column.
|
25
|
+
#
|
26
|
+
class Request
|
27
|
+
include OAuth::Key
|
28
|
+
|
29
|
+
attr_accessor :oauth_params,:headers,:site,:path,:realm,:body,:auth_method
|
30
|
+
|
31
|
+
@@default_oauth_params={:oauth_signature_method=>'HMAC-SHA1',:oauth_version=>"1.0",:realm=>''}
|
32
|
+
|
33
|
+
def initialize(http_method,site,path,oauth_params={},*arguments)
|
34
|
+
# ensure that keys are symbols
|
35
|
+
@oauth_params=@@default_oauth_params.merge( oauth_params.inject({}) do |options, (key, value)|
|
36
|
+
options[key.to_sym] = value
|
37
|
+
options
|
38
|
+
end)
|
39
|
+
self.http_method=http_method
|
40
|
+
self.site=site
|
41
|
+
self.path=path
|
42
|
+
self.realm=@oauth_params.delete(:realm)
|
43
|
+
self.auth_method=@oauth_params.delete(:auth_method)||:authorize
|
44
|
+
self.body=arguments.shift if ['POST','PUT'].include?(self.http_method)
|
45
|
+
self.headers=arguments.shift||{}
|
46
|
+
self.headers['Content-Type']||='application/x-www-form-urlencoded' if ['POST','PUT'].include?(self.http_method)
|
47
|
+
|
48
|
+
self[:oauth_timestamp]=create_timestamp unless self.timestamp
|
49
|
+
self[:oauth_nonce]=generate_key(24) unless self.nonce
|
50
|
+
|
51
|
+
# Default to Authorize header if http method doesn't support the specified auth_method
|
52
|
+
if ['GET','HEAD','DELETE'].include?(self.http_method)
|
53
|
+
self.auth_method=:authorize unless self.auth_method==:query
|
54
|
+
else
|
55
|
+
self.auth_method=:authorize unless self.auth_method==:post
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# Use to extract the consumer key from a http request object
|
61
|
+
# This is intended for use on the server
|
62
|
+
def self.extract_consumer_key(http_request)
|
63
|
+
auth=http_request.env["HTTP_AUTHORIZATION"]
|
64
|
+
if auth && auth[0..5]=="OAuth "&&auth=~/ oauth_consumer_key="([^, ]+)"/
|
65
|
+
$1
|
66
|
+
else
|
67
|
+
http_request.parameters[:oauth_consumer_key]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# This takes a rails like Request and returns an OAuth request object
|
72
|
+
def self.incoming(http_request)
|
73
|
+
auth=http_request.env["HTTP_AUTHORIZATION"]
|
74
|
+
if auth && auth[0..5]=="OAuth "
|
75
|
+
parameters=auth[6,auth.size].scan(/ ([^= ]+)="([^"]*)",?/).inject({}) do |h,(k,v)|
|
76
|
+
h[k.to_sym]=CGI.unescape(v)
|
77
|
+
h
|
78
|
+
end
|
79
|
+
_path=http_request.request_uri
|
80
|
+
else
|
81
|
+
parameters=http_request.query_parameters#.reject{|k,v| ['controller','action'].include?(k)}
|
82
|
+
# non_oauth=to_name_value_pair_array(http_request.query_parameters.reject(){|k,v| k.to_s=~/oauth_/}).join(/&/)
|
83
|
+
_path=http_request.request_uri
|
84
|
+
# _path=http_request.path+'?'+non_auth
|
85
|
+
end
|
86
|
+
if http_request.post?||http_request.put?
|
87
|
+
Request.new(http_request.method,"http://#{http_request.host_with_port}",_path,parameters,http_request.raw_post,{'Content-Type'=>http_request.content_type})
|
88
|
+
else
|
89
|
+
Request.new(http_request.method,"http://#{http_request.host_with_port}",_path,parameters)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def perform(consumer_secret,token_secret=nil)
|
94
|
+
http_klass=(uri.scheme=="https" ? Net::HTTPS : Net::HTTP)
|
95
|
+
http_klass.start(uri.host,uri.port) do |http|
|
96
|
+
sign(consumer_secret,token_secret)
|
97
|
+
|
98
|
+
case auth_method
|
99
|
+
when :query
|
100
|
+
_path="#{uri.path}?#{to_query}"
|
101
|
+
when :post
|
102
|
+
self.body=to_query
|
103
|
+
else
|
104
|
+
headers['Authorization']=to_auth_string
|
105
|
+
end
|
106
|
+
_path||=path
|
107
|
+
# TODO if realm is set use auth header
|
108
|
+
if (['POST','PUT'].include?(http_method))
|
109
|
+
# headers['Content-Length']=body.size.to_s unless body.nil?
|
110
|
+
http.send(http_method.downcase.to_sym,_path,body,headers)
|
111
|
+
else # any request without a body
|
112
|
+
http.send(http_method.downcase.to_sym,_path,headers)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def perform_token_request(consumer_secret,token_secret=nil)
|
118
|
+
response=perform(consumer_secret,token_secret)
|
119
|
+
if response.code=="200"
|
120
|
+
CGI.parse(response.body).inject({}){|h,(k,v)| h[k.to_sym]=v.first;h}
|
121
|
+
else
|
122
|
+
response.error!
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def http_method=(value)
|
127
|
+
@http_method=value.to_s.strip.upcase
|
128
|
+
end
|
129
|
+
|
130
|
+
def http_method
|
131
|
+
@http_method
|
132
|
+
end
|
133
|
+
|
134
|
+
def content_type
|
135
|
+
@content_type||=headers['Content-Type']
|
136
|
+
end
|
137
|
+
|
138
|
+
def site=(_site)
|
139
|
+
@site=_site.downcase
|
140
|
+
@uri=nil # invalidate uri
|
141
|
+
@site
|
142
|
+
end
|
143
|
+
|
144
|
+
def path=(_path)
|
145
|
+
@path=_path
|
146
|
+
@uri=nil # invalidate uri
|
147
|
+
@path
|
148
|
+
end
|
149
|
+
|
150
|
+
def uri
|
151
|
+
@uri||=URI.parse(url)
|
152
|
+
end
|
153
|
+
|
154
|
+
def url
|
155
|
+
(site+path)
|
156
|
+
end
|
157
|
+
|
158
|
+
# produces a hash of the query or post parameters depending on http method
|
159
|
+
def http_parameters
|
160
|
+
@http_params||=parse_url_form_encoded( body||uri.query||'')
|
161
|
+
end
|
162
|
+
|
163
|
+
def parse_url_form_encoded(string)
|
164
|
+
CGI.parse(string).inject({}){|h,(k,v)| h[k.to_sym]=v[0];h}
|
165
|
+
end
|
166
|
+
|
167
|
+
def normalized_url
|
168
|
+
uri=URI.split(url)
|
169
|
+
if uri[3].nil?||(uri[3]=='80'&&uri[0]=='http')||(uri[3]=='443'&&uri[0]=='https')
|
170
|
+
port=""
|
171
|
+
else
|
172
|
+
port=":#{uri[3]}"
|
173
|
+
end
|
174
|
+
"#{uri[0]}://#{uri[2]}#{port}#{uri[5]}"
|
175
|
+
end
|
176
|
+
|
177
|
+
def [](key)
|
178
|
+
oauth_params[key.to_sym]
|
179
|
+
end
|
180
|
+
|
181
|
+
def []=(key,value)
|
182
|
+
oauth_params[key.to_sym]=value
|
183
|
+
end
|
184
|
+
|
185
|
+
def timestamp
|
186
|
+
self[:oauth_timestamp]
|
187
|
+
end
|
188
|
+
|
189
|
+
def create_timestamp
|
190
|
+
Time.now.utc.to_i.to_s
|
191
|
+
end
|
192
|
+
|
193
|
+
def nonce
|
194
|
+
self[:oauth_nonce]
|
195
|
+
end
|
196
|
+
|
197
|
+
def token
|
198
|
+
self[:oauth_token]
|
199
|
+
end
|
200
|
+
|
201
|
+
def to_name_value_pair_array(hash,with={})
|
202
|
+
hash.merge(with).collect{|(key,value)| "#{escape(key.to_s)}=#{escape(value)}"}.sort
|
203
|
+
end
|
204
|
+
|
205
|
+
def to_hash(with={})
|
206
|
+
oauth_params.merge(http_parameters).merge(with)
|
207
|
+
end
|
208
|
+
|
209
|
+
def to_query(with={})
|
210
|
+
(to_name_value_pair_array(to_hash(with))).sort.join("&")
|
211
|
+
end
|
212
|
+
|
213
|
+
def to_query_without_signature(with={})
|
214
|
+
(to_name_value_pair_array(oauth_params_without_signature,with)).sort.join("&")
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_auth_string
|
218
|
+
"OAuth realm=\"#{realm}\", "+oauth_params.collect{|(key,value)| "#{escape(key.to_s)}=\"#{escape(value)}\""}.sort.join(", ")
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_base_string(secret)
|
222
|
+
to_query({:oauth_secret=>secret})
|
223
|
+
end
|
224
|
+
|
225
|
+
def oauth_params_without_signature
|
226
|
+
to_hash.reject{|key,value| key.to_sym==:oauth_signature}
|
227
|
+
end
|
228
|
+
|
229
|
+
def signature
|
230
|
+
self[:oauth_signature]
|
231
|
+
end
|
232
|
+
|
233
|
+
def signature=(_signature)
|
234
|
+
self[:oauth_signature]=_signature
|
235
|
+
end
|
236
|
+
|
237
|
+
def signature_method
|
238
|
+
self[:oauth_signature_method]
|
239
|
+
end
|
240
|
+
|
241
|
+
def signature_method=(_signature_method)
|
242
|
+
self[:oauth_signature_method]=_signature_method
|
243
|
+
end
|
244
|
+
|
245
|
+
def signed?
|
246
|
+
signature!=nil
|
247
|
+
end
|
248
|
+
|
249
|
+
def sign(consumer_secret,token_secret=nil)
|
250
|
+
OAuth::Signature.create(self,consumer_secret,token_secret).sign!
|
251
|
+
end
|
252
|
+
|
253
|
+
def verify?(consumer_secret,token_secret=nil)
|
254
|
+
OAuth::Signature.create(self,consumer_secret,token_secret).verify?
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
end
|