metavida-oauth 0.3.2
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 +66 -0
- data/License.txt +20 -0
- data/Manifest.txt +83 -0
- data/README.rdoc +71 -0
- data/Rakefile +36 -0
- data/TODO +32 -0
- data/bin/oauth +5 -0
- data/examples/yql.rb +44 -0
- data/lib/oauth/cli.rb +300 -0
- data/lib/oauth/client/action_controller_request.rb +53 -0
- data/lib/oauth/client/helper.rb +71 -0
- data/lib/oauth/client/net_http.rb +78 -0
- data/lib/oauth/client.rb +4 -0
- data/lib/oauth/consumer.rb +296 -0
- 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 +55 -0
- data/lib/oauth/oauth.rb +7 -0
- data/lib/oauth/oauth_test_helper.rb +25 -0
- data/lib/oauth/request_proxy/action_controller_request.rb +68 -0
- data/lib/oauth/request_proxy/base.rb +157 -0
- data/lib/oauth/request_proxy/jabber_request.rb +41 -0
- data/lib/oauth/request_proxy/mock_request.rb +44 -0
- data/lib/oauth/request_proxy/net_http.rb +65 -0
- data/lib/oauth/request_proxy/rack_request.rb +40 -0
- data/lib/oauth/request_proxy.rb +24 -0
- data/lib/oauth/server.rb +66 -0
- data/lib/oauth/signature/base.rb +91 -0
- data/lib/oauth/signature/hmac/base.rb +12 -0
- data/lib/oauth/signature/hmac/md5.rb +9 -0
- data/lib/oauth/signature/hmac/rmd160.rb +9 -0
- data/lib/oauth/signature/hmac/sha1.rb +9 -0
- data/lib/oauth/signature/hmac/sha2.rb +9 -0
- data/lib/oauth/signature/md5.rb +13 -0
- data/lib/oauth/signature/plaintext.rb +23 -0
- data/lib/oauth/signature/rsa/sha1.rb +45 -0
- data/lib/oauth/signature/sha1.rb +13 -0
- data/lib/oauth/signature.rb +28 -0
- data/lib/oauth/token.rb +7 -0
- data/lib/oauth/tokens/access_token.rb +68 -0
- data/lib/oauth/tokens/consumer_token.rb +32 -0
- data/lib/oauth/tokens/request_token.rb +28 -0
- data/lib/oauth/tokens/server_token.rb +9 -0
- data/lib/oauth/tokens/token.rb +17 -0
- data/lib/oauth/version.rb +3 -0
- data/lib/oauth.rb +4 -0
- data/oauth.gemspec +49 -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/cases/oauth_case.rb +19 -0
- data/test/cases/spec/1_0-final/test_construct_request_url.rb +62 -0
- data/test/cases/spec/1_0-final/test_normalize_request_parameters.rb +88 -0
- data/test/cases/spec/1_0-final/test_parameter_encodings.rb +86 -0
- data/test/cases/spec/1_0-final/test_signature_base_strings.rb +77 -0
- data/test/keys/rsa.cert +11 -0
- data/test/keys/rsa.pem +16 -0
- data/test/test_access_token.rb +28 -0
- data/test/test_action_controller_request_proxy.rb +45 -0
- data/test/test_consumer.rb +327 -0
- data/test/test_helper.rb +11 -0
- data/test/test_hmac_sha1.rb +21 -0
- data/test/test_net_http_client.rb +169 -0
- data/test/test_net_http_request_proxy.rb +38 -0
- data/test/test_rack_request_proxy.rb +40 -0
- data/test/test_request_token.rb +53 -0
- data/test/test_rsa_sha1.rb +59 -0
- data/test/test_server.rb +40 -0
- data/test/test_signature.rb +11 -0
- data/test/test_signature_base.rb +32 -0
- data/test/test_signature_plain_text.rb +31 -0
- data/test/test_token.rb +14 -0
- data/website/index.html +87 -0
- data/website/index.txt +73 -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 +212 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'oauth/client/helper'
|
2
|
+
require 'oauth/request_proxy/action_controller_request'
|
3
|
+
require 'action_controller/test_process'
|
4
|
+
|
5
|
+
module ActionController
|
6
|
+
class Base
|
7
|
+
def process_with_oauth(request, response=nil)
|
8
|
+
request.apply_oauth!
|
9
|
+
process_without_oauth(request, response)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :process, :oauth
|
13
|
+
end
|
14
|
+
|
15
|
+
class TestRequest
|
16
|
+
def self.use_oauth=(bool)
|
17
|
+
@use_oauth = bool
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.use_oauth?
|
21
|
+
@use_oauth
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure_oauth(consumer = nil, token = nil, options = {})
|
25
|
+
@oauth_options = { :consumer => consumer,
|
26
|
+
:token => token,
|
27
|
+
:scheme => 'header',
|
28
|
+
:signature_method => nil,
|
29
|
+
:nonce => nil,
|
30
|
+
:timestamp => nil }.merge(options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def apply_oauth!
|
34
|
+
return unless ActionController::TestRequest.use_oauth? && @oauth_options
|
35
|
+
|
36
|
+
@oauth_helper = OAuth::Client::Helper.new(self, @oauth_options.merge(:request_uri => request_uri))
|
37
|
+
|
38
|
+
self.send("set_oauth_#{@oauth_options[:scheme]}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_oauth_header
|
42
|
+
env['Authorization'] = @oauth_helper.header
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_oauth_parameters
|
46
|
+
@query_parameters = @oauth_helper.parameters_with_oauth
|
47
|
+
@query_parameters.merge!(:oauth_signature => @oauth_helper.signature)
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_oauth_query_string
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'oauth/client'
|
2
|
+
require 'oauth/consumer'
|
3
|
+
require 'oauth/helper'
|
4
|
+
require 'oauth/token'
|
5
|
+
require 'oauth/signature/hmac/sha1'
|
6
|
+
|
7
|
+
module OAuth::Client
|
8
|
+
class Helper
|
9
|
+
include OAuth::Helper
|
10
|
+
|
11
|
+
def initialize(request, options = {})
|
12
|
+
@request = request
|
13
|
+
@options = options
|
14
|
+
@options[:signature_method] ||= 'HMAC-SHA1'
|
15
|
+
end
|
16
|
+
|
17
|
+
def options
|
18
|
+
@options
|
19
|
+
end
|
20
|
+
|
21
|
+
def nonce
|
22
|
+
options[:nonce] ||= generate_key
|
23
|
+
end
|
24
|
+
|
25
|
+
def timestamp
|
26
|
+
options[:timestamp] ||= generate_timestamp
|
27
|
+
end
|
28
|
+
|
29
|
+
def oauth_parameters
|
30
|
+
{
|
31
|
+
'oauth_consumer_key' => options[:consumer].key,
|
32
|
+
'oauth_token' => options[:token] ? options[:token].token : '',
|
33
|
+
'oauth_signature_method' => options[:signature_method],
|
34
|
+
'oauth_timestamp' => timestamp,
|
35
|
+
'oauth_nonce' => nonce,
|
36
|
+
'oauth_version' => '1.0'
|
37
|
+
}.reject { |k,v| v.to_s == "" }
|
38
|
+
end
|
39
|
+
|
40
|
+
def signature(extra_options = {})
|
41
|
+
OAuth::Signature.sign(@request, { :uri => options[:request_uri],
|
42
|
+
:consumer => options[:consumer],
|
43
|
+
:token => options[:token] }.merge(extra_options) )
|
44
|
+
end
|
45
|
+
|
46
|
+
def signature_base_string(extra_options = {})
|
47
|
+
OAuth::Signature.signature_base_string(@request, { :uri => options[:request_uri],
|
48
|
+
:consumer => options[:consumer],
|
49
|
+
:token => options[:token],
|
50
|
+
:parameters => oauth_parameters}.merge(extra_options) )
|
51
|
+
end
|
52
|
+
|
53
|
+
def header
|
54
|
+
parameters = oauth_parameters
|
55
|
+
parameters.merge!('oauth_signature' => signature(options.merge(:parameters => parameters)))
|
56
|
+
|
57
|
+
header_params_str = parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
|
58
|
+
|
59
|
+
realm = "realm=\"#{options[:realm]}\", " if options[:realm]
|
60
|
+
"OAuth #{realm}#{header_params_str}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def parameters
|
64
|
+
OAuth::RequestProxy.proxy(@request).parameters
|
65
|
+
end
|
66
|
+
|
67
|
+
def parameters_with_oauth
|
68
|
+
oauth_parameters.merge(parameters)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'oauth/helper'
|
2
|
+
require 'oauth/client/helper'
|
3
|
+
require 'oauth/request_proxy/net_http'
|
4
|
+
|
5
|
+
class Net::HTTPRequest
|
6
|
+
include OAuth::Helper
|
7
|
+
|
8
|
+
attr_reader :oauth_helper
|
9
|
+
|
10
|
+
def oauth!(http, consumer = nil, token = nil, options = {})
|
11
|
+
options = { :request_uri => oauth_full_request_uri(http),
|
12
|
+
:consumer => consumer,
|
13
|
+
:token => token,
|
14
|
+
:scheme => 'header',
|
15
|
+
:signature_method => nil,
|
16
|
+
:nonce => nil,
|
17
|
+
:timestamp => nil }.merge(options)
|
18
|
+
|
19
|
+
@oauth_helper = OAuth::Client::Helper.new(self, options)
|
20
|
+
self.send("set_oauth_#{options[:scheme]}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def signature_base_string(http, consumer = nil, token = nil, options = {})
|
24
|
+
options = { :request_uri => oauth_full_request_uri(http),
|
25
|
+
:consumer => consumer,
|
26
|
+
:token => token,
|
27
|
+
:scheme => 'header',
|
28
|
+
:signature_method => nil,
|
29
|
+
:nonce => nil,
|
30
|
+
:timestamp => nil }.merge(options)
|
31
|
+
|
32
|
+
OAuth::Client::Helper.new(self, options).signature_base_string
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def oauth_full_request_uri(http)
|
38
|
+
uri = URI.parse(self.path)
|
39
|
+
uri.host = http.address
|
40
|
+
uri.port = http.port
|
41
|
+
|
42
|
+
if http.respond_to?(:use_ssl?) && http.use_ssl?
|
43
|
+
uri.scheme = "https"
|
44
|
+
else
|
45
|
+
uri.scheme = "http"
|
46
|
+
end
|
47
|
+
|
48
|
+
uri.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_oauth_header
|
52
|
+
self['Authorization'] = @oauth_helper.header
|
53
|
+
end
|
54
|
+
|
55
|
+
# FIXME: if you're using a POST body and query string parameters, using this
|
56
|
+
# method will convert those parameters on the query string into parameters in
|
57
|
+
# the body. this is broken, and should be fixed.
|
58
|
+
def set_oauth_body
|
59
|
+
self.set_form_data(@oauth_helper.parameters_with_oauth)
|
60
|
+
params_with_sig = @oauth_helper.parameters.merge(:oauth_signature => @oauth_helper.signature)
|
61
|
+
self.set_form_data(params_with_sig)
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_oauth_query_string
|
65
|
+
oauth_params_str = @oauth_helper.oauth_parameters.map { |k,v| [escape(k), escape(v)] * "=" }.join("&")
|
66
|
+
|
67
|
+
uri = URI.parse(path)
|
68
|
+
if uri.query.to_s == ""
|
69
|
+
uri.query = oauth_params_str
|
70
|
+
else
|
71
|
+
uri.query = uri.query + "&" + oauth_params_str
|
72
|
+
end
|
73
|
+
|
74
|
+
@path = uri.to_s
|
75
|
+
|
76
|
+
@path << "&oauth_signature=#{escape(oauth_helper.signature)}"
|
77
|
+
end
|
78
|
+
end
|
data/lib/oauth/client.rb
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'oauth/client/net_http'
|
4
|
+
require 'oauth/errors'
|
5
|
+
|
6
|
+
module OAuth
|
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)
|
17
|
+
|
18
|
+
@@default_options = {
|
19
|
+
# Signature method used by server. Defaults to HMAC-SHA1
|
20
|
+
:signature_method => 'HMAC-SHA1',
|
21
|
+
|
22
|
+
# default paths on site. These are the same as the defaults set up by the generators
|
23
|
+
:request_token_path => '/oauth/request_token',
|
24
|
+
:authorize_path => '/oauth/authorize',
|
25
|
+
:access_token_path => '/oauth/access_token',
|
26
|
+
|
27
|
+
# How do we send the oauth values to the server see
|
28
|
+
# http://oauth.net/core/1.0/#consumer_req_param for more info
|
29
|
+
#
|
30
|
+
# Possible values:
|
31
|
+
#
|
32
|
+
# :header - via the Authorize header (Default) ( option 1. in spec)
|
33
|
+
# :body - url form encoded in body of POST request ( option 2. in spec)
|
34
|
+
# :query_string - via the query part of the url ( option 3. in spec)
|
35
|
+
:scheme => :header,
|
36
|
+
|
37
|
+
# Default http method used for OAuth Token Requests (defaults to :post)
|
38
|
+
:http_method => :post,
|
39
|
+
|
40
|
+
:oauth_version => "1.0"
|
41
|
+
}
|
42
|
+
|
43
|
+
attr_accessor :options, :key, :secret
|
44
|
+
attr_writer :site, :http
|
45
|
+
|
46
|
+
# Create a new consumer instance by passing it a configuration hash:
|
47
|
+
#
|
48
|
+
# @consumer = OAuth::Consumer.new(key, secret, {
|
49
|
+
# :site => "http://term.ie",
|
50
|
+
# :scheme => :header,
|
51
|
+
# :http_method => :post,
|
52
|
+
# :request_token_path => "/oauth/example/request_token.php",
|
53
|
+
# :access_token_path => "/oauth/example/access_token.php",
|
54
|
+
# :authorize_path => "/oauth/example/authorize.php"
|
55
|
+
# })
|
56
|
+
#
|
57
|
+
# Start the process by requesting a token
|
58
|
+
#
|
59
|
+
# @request_token = @consumer.get_request_token
|
60
|
+
# session[:request_token] = @request_token
|
61
|
+
# redirect_to @request_token.authorize_url
|
62
|
+
#
|
63
|
+
# When user returns create an access_token
|
64
|
+
#
|
65
|
+
# @access_token = @request_token.get_access_token
|
66
|
+
# @photos=@access_token.get('/photos.xml')
|
67
|
+
#
|
68
|
+
def initialize(consumer_key, consumer_secret, options = {})
|
69
|
+
@key = consumer_key
|
70
|
+
@secret = consumer_secret
|
71
|
+
|
72
|
+
# ensure that keys are symbols
|
73
|
+
@options = @@default_options.merge(options.inject({}) { |options, (key, value)|
|
74
|
+
options[key.to_sym] = value
|
75
|
+
options
|
76
|
+
})
|
77
|
+
end
|
78
|
+
|
79
|
+
# The default http method
|
80
|
+
def http_method
|
81
|
+
@http_method ||= @options[:http_method] || :post
|
82
|
+
end
|
83
|
+
|
84
|
+
# The HTTP object for the site. The HTTP Object is what you get when you do Net::HTTP.new
|
85
|
+
def http
|
86
|
+
@http ||= create_http
|
87
|
+
end
|
88
|
+
|
89
|
+
# Contains the root URI for this site
|
90
|
+
def uri(custom_uri = nil)
|
91
|
+
if custom_uri
|
92
|
+
@uri = custom_uri
|
93
|
+
@http = create_http # yike, oh well. less intrusive this way
|
94
|
+
else # if no custom passed, we use existing, which, if unset, is set to site uri
|
95
|
+
@uri ||= URI.parse(site)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Makes a request to the service for a new OAuth::RequestToken
|
100
|
+
#
|
101
|
+
# @request_token = @consumer.get_request_token
|
102
|
+
#
|
103
|
+
def get_request_token(request_options = {}, *arguments)
|
104
|
+
response = token_request(http_method, (request_token_url? ? request_token_url : request_token_path), nil, request_options, *arguments)
|
105
|
+
OAuth::RequestToken.new(self, response[:oauth_token], response[:oauth_token_secret])
|
106
|
+
end
|
107
|
+
|
108
|
+
# Creates, signs and performs an http request.
|
109
|
+
# It's recommended to use the OAuth::Token classes to set this up correctly.
|
110
|
+
# The arguments parameters are a hash or string encoded set of parameters if it's a post request as well as optional http headers.
|
111
|
+
#
|
112
|
+
# @consumer.request(:get, '/people', @token, { :scheme => :query_string })
|
113
|
+
# @consumer.request(:post, '/people', @token, {}, @person.to_xml, { 'Content-Type' => 'application/xml' })
|
114
|
+
#
|
115
|
+
def request(http_method, path, token = nil, request_options = {}, *arguments)
|
116
|
+
if path !~ /^\//
|
117
|
+
@http = create_http(path)
|
118
|
+
_uri = URI.parse(path)
|
119
|
+
path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
|
120
|
+
end
|
121
|
+
|
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
|
144
|
+
end
|
145
|
+
|
146
|
+
# Creates and signs an http request.
|
147
|
+
# It's recommended to use the Token classes to set this up correctly
|
148
|
+
def create_signed_request(http_method, path, token = nil, request_options = {}, *arguments)
|
149
|
+
request = create_http_request(http_method, path, *arguments)
|
150
|
+
sign!(request, token, request_options)
|
151
|
+
request
|
152
|
+
end
|
153
|
+
|
154
|
+
# Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.
|
155
|
+
def token_request(http_method, path, token = nil, request_options = {}, *arguments)
|
156
|
+
response = request(http_method, path, token, request_options, *arguments)
|
157
|
+
|
158
|
+
case response.code.to_i
|
159
|
+
|
160
|
+
when (200..299)
|
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
|
167
|
+
else
|
168
|
+
response.error!
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Sign the Request object. Use this if you have an externally generated http request object you want to sign.
|
173
|
+
def sign!(request, token = nil, request_options = {})
|
174
|
+
request.oauth!(http, self, token, options.merge(request_options))
|
175
|
+
end
|
176
|
+
|
177
|
+
# Return the signature_base_string
|
178
|
+
def signature_base_string(request, token = nil, request_options = {})
|
179
|
+
request.signature_base_string(http, self, token, options.merge(request_options))
|
180
|
+
end
|
181
|
+
|
182
|
+
def site
|
183
|
+
@options[:site].to_s
|
184
|
+
end
|
185
|
+
|
186
|
+
def scheme
|
187
|
+
@options[:scheme]
|
188
|
+
end
|
189
|
+
|
190
|
+
def request_token_path
|
191
|
+
@options[:request_token_path]
|
192
|
+
end
|
193
|
+
|
194
|
+
def authorize_path
|
195
|
+
@options[:authorize_path]
|
196
|
+
end
|
197
|
+
|
198
|
+
def access_token_path
|
199
|
+
@options[:access_token_path]
|
200
|
+
end
|
201
|
+
|
202
|
+
# TODO this is ugly, rewrite
|
203
|
+
def request_token_url
|
204
|
+
@options[:request_token_url] || site + request_token_path
|
205
|
+
end
|
206
|
+
|
207
|
+
def request_token_url?
|
208
|
+
@options.has_key?(:request_token_url)
|
209
|
+
end
|
210
|
+
|
211
|
+
def authorize_url
|
212
|
+
@options[:authorize_url] || site + authorize_path
|
213
|
+
end
|
214
|
+
|
215
|
+
def authorize_url?
|
216
|
+
@options.has_key?(:authorize_url)
|
217
|
+
end
|
218
|
+
|
219
|
+
def access_token_url
|
220
|
+
@options[:access_token_url] || site + access_token_path
|
221
|
+
end
|
222
|
+
|
223
|
+
def access_token_url?
|
224
|
+
@options.has_key?(:access_token_url)
|
225
|
+
end
|
226
|
+
|
227
|
+
protected
|
228
|
+
|
229
|
+
# Instantiates the http object
|
230
|
+
def create_http(_url = nil)
|
231
|
+
if _url.nil? || _url[0] =~ /^\//
|
232
|
+
our_uri = URI.parse(site)
|
233
|
+
else
|
234
|
+
our_uri = URI.parse(_url)
|
235
|
+
end
|
236
|
+
|
237
|
+
http_object = Net::HTTP.new(our_uri.host, our_uri.port)
|
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
|
248
|
+
|
249
|
+
http_object
|
250
|
+
end
|
251
|
+
|
252
|
+
# create the http request object for a given http_method and path
|
253
|
+
def create_http_request(http_method, path, *arguments)
|
254
|
+
http_method = http_method.to_sym
|
255
|
+
|
256
|
+
if [:post, :put].include?(http_method)
|
257
|
+
data = arguments.shift
|
258
|
+
end
|
259
|
+
|
260
|
+
headers = arguments.first.is_a?(Hash) ? arguments.shift : {}
|
261
|
+
|
262
|
+
case http_method
|
263
|
+
when :post
|
264
|
+
request = Net::HTTP::Post.new(path,headers)
|
265
|
+
request["Content-Length"] = 0 # Default to 0
|
266
|
+
when :put
|
267
|
+
request = Net::HTTP::Put.new(path,headers)
|
268
|
+
request["Content-Length"] = 0 # Default to 0
|
269
|
+
when :get
|
270
|
+
request = Net::HTTP::Get.new(path,headers)
|
271
|
+
when :delete
|
272
|
+
request = Net::HTTP::Delete.new(path,headers)
|
273
|
+
when :head
|
274
|
+
request = Net::HTTP::Head.new(path,headers)
|
275
|
+
else
|
276
|
+
raise ArgumentError, "Don't know how to handle http_method: :#{http_method.to_s}"
|
277
|
+
end
|
278
|
+
|
279
|
+
if data.is_a?(Hash)
|
280
|
+
request.set_form_data(data)
|
281
|
+
elsif data
|
282
|
+
request.body = data.to_s
|
283
|
+
request["Content-Length"] = request.body.length
|
284
|
+
end
|
285
|
+
|
286
|
+
request
|
287
|
+
end
|
288
|
+
|
289
|
+
# Unset cached http instance because it cannot be marshalled when
|
290
|
+
# it has already been used and use_ssl is set to true
|
291
|
+
def marshal_dump(*args)
|
292
|
+
@http = nil
|
293
|
+
self
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
data/lib/oauth/errors.rb
ADDED
data/lib/oauth/helper.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module OAuth
|
5
|
+
module Helper
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def escape(value)
|
9
|
+
URI::escape(value.to_s, OAuth::RESERVED_CHARACTERS)
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_key(size=32)
|
13
|
+
Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/, '')
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :generate_nonce, :generate_key
|
17
|
+
|
18
|
+
def generate_timestamp
|
19
|
+
Time.now.to_i.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def normalize(params)
|
23
|
+
params.sort.map do |k, values|
|
24
|
+
|
25
|
+
if values.is_a?(Array)
|
26
|
+
# multiple values were provided for a single key
|
27
|
+
values.sort.collect do |v|
|
28
|
+
[escape(k),escape(v)] * "="
|
29
|
+
end
|
30
|
+
else
|
31
|
+
[escape(k),escape(values)] * "="
|
32
|
+
end
|
33
|
+
end * "&"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Parse an Authorization / WWW-Authenticate header into a hash
|
37
|
+
def parse_header(header)
|
38
|
+
# decompose
|
39
|
+
params = header[6,header.length].split(/[,=]/)
|
40
|
+
|
41
|
+
# strip and unescape
|
42
|
+
params.map! { |v| unescape(v.strip) }
|
43
|
+
|
44
|
+
# strip quotes
|
45
|
+
params.map! { |v| v =~ /^\".*\"$/ ? v[1..-2] : v }
|
46
|
+
|
47
|
+
# convert into a Hash
|
48
|
+
Hash[*params.flatten]
|
49
|
+
end
|
50
|
+
|
51
|
+
def unescape(value)
|
52
|
+
URI.unescape(value.gsub('+', '%2B'))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/oauth/oauth.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
module OAuth
|
2
|
+
# required parameters, per sections 6.1.1, 6.3.1, and 7
|
3
|
+
PARAMETERS = %w(oauth_consumer_key oauth_token oauth_signature_method oauth_timestamp oauth_nonce oauth_version oauth_signature)
|
4
|
+
|
5
|
+
# reserved character regexp, per section 5.1
|
6
|
+
RESERVED_CHARACTERS = /[^\w\d\-\.\_\~]/
|
7
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
require 'action_controller/test_process'
|
3
|
+
|
4
|
+
module OAuth
|
5
|
+
module OAuthTestHelper
|
6
|
+
def mock_incoming_request_with_query(request)
|
7
|
+
incoming = ActionController::TestRequest.new(request.to_hash)
|
8
|
+
incoming.request_uri = request.path
|
9
|
+
incoming.host = request.uri.host
|
10
|
+
incoming.env["SERVER_PORT"] = request.uri.port
|
11
|
+
incoming.env['REQUEST_METHOD'] = request.http_method
|
12
|
+
incoming
|
13
|
+
end
|
14
|
+
|
15
|
+
def mock_incoming_request_with_authorize_header(request)
|
16
|
+
incoming = ActionController::TestRequest.new
|
17
|
+
incoming.request_uri = request.path
|
18
|
+
incoming.host = request.uri.host
|
19
|
+
incoming.env["HTTP_AUTHORIZATION"] = request.to_auth_string
|
20
|
+
incoming.env["SERVER_PORT"] = request.uri.port
|
21
|
+
incoming.env['REQUEST_METHOD'] = request.http_method
|
22
|
+
incoming
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|