rares-oauth 0.2.7
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 +33 -0
- data/License.txt +20 -0
- data/Manifest.txt +55 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +71 -0
- data/config/requirements.rb +17 -0
- data/lib/oauth.rb +3 -0
- data/lib/oauth/client.rb +4 -0
- data/lib/oauth/client/action_controller_request.rb +52 -0
- data/lib/oauth/client/helper.rb +88 -0
- data/lib/oauth/client/net_http.rb +75 -0
- data/lib/oauth/consumer.rb +218 -0
- data/lib/oauth/helper.rb +14 -0
- data/lib/oauth/request_proxy.rb +24 -0
- data/lib/oauth/request_proxy/action_controller_request.rb +64 -0
- data/lib/oauth/request_proxy/base.rb +76 -0
- data/lib/oauth/request_proxy/net_http.rb +67 -0
- data/lib/oauth/request_proxy/rack_request.rb +42 -0
- data/lib/oauth/server.rb +68 -0
- data/lib/oauth/signature.rb +28 -0
- data/lib/oauth/signature/base.rb +76 -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 +10 -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 +44 -0
- data/lib/oauth/signature/sha1.rb +13 -0
- data/lib/oauth/token.rb +163 -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_action_controller_request_proxy.rb +27 -0
- data/test/test_consumer.rb +285 -0
- data/test/test_helper.rb +7 -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_server.rb +40 -0
- data/test/test_signature.rb +11 -0
- data/test/test_signature_base.rb +32 -0
- data/test/test_token.rb +15 -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 +137 -0
data/lib/oauth/helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
module OAuth
|
4
|
+
module Helper
|
5
|
+
def escape(value)
|
6
|
+
CGI.escape(value.to_s).gsub("%7E", '~').gsub("+", "%20")
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate_key(size=32)
|
10
|
+
Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/,'')
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module OAuth
|
2
|
+
module RequestProxy
|
3
|
+
def self.available_proxies #:nodoc:
|
4
|
+
@available_proxies ||= {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.proxy(request, options = {})
|
8
|
+
return request if request.kind_of?(OAuth::RequestProxy::Base)
|
9
|
+
|
10
|
+
klass = available_proxies[request.class]
|
11
|
+
|
12
|
+
# Search for possible superclass matches.
|
13
|
+
if klass.nil?
|
14
|
+
request_parent = available_proxies.keys.find { |rc| request.kind_of?(rc) }
|
15
|
+
klass = available_proxies[request_parent]
|
16
|
+
end
|
17
|
+
|
18
|
+
raise UnknownRequestType, request.class.to_s unless klass
|
19
|
+
klass.new(request, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
class UnknownRequestType < Exception; end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support'
|
3
|
+
require 'action_controller/request'
|
4
|
+
require 'oauth/request_proxy/base'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module OAuth::RequestProxy
|
8
|
+
class ActionControllerRequest < OAuth::RequestProxy::Base
|
9
|
+
proxies ActionController::AbstractRequest
|
10
|
+
|
11
|
+
def method
|
12
|
+
request.method.to_s.upcase
|
13
|
+
end
|
14
|
+
|
15
|
+
def uri
|
16
|
+
uri = URI.parse(request.protocol + request.host + request.port_string + request.path)
|
17
|
+
uri.query = nil
|
18
|
+
uri.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def parameters
|
22
|
+
if options[:clobber_request]
|
23
|
+
options[:parameters] || {}
|
24
|
+
else
|
25
|
+
params = request_params.merge(query_params).merge(header_params)
|
26
|
+
params.stringify_keys! if params.respond_to?(:stringify_keys!)
|
27
|
+
params.merge(options[:parameters] || {})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Override from OAuth::RequestProxy::Base to avoid roundtrip
|
32
|
+
# conversion to Hash or Array and thus preserve the original
|
33
|
+
# parameter names
|
34
|
+
def parameters_for_signature
|
35
|
+
params = []
|
36
|
+
params << options[:parameters].to_query if options[:parameters]
|
37
|
+
|
38
|
+
unless options[:clobber_request]
|
39
|
+
params << header_params.to_query
|
40
|
+
params << request.query_string unless request.query_string.blank?
|
41
|
+
if request.content_type == Mime::Type.lookup("application/x-www-form-urlencoded")
|
42
|
+
params << CGI.unescape(request.raw_post)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
params.
|
47
|
+
join('&').split('&').
|
48
|
+
reject { |kv| kv =~ /^oauth_signature=.*/}.
|
49
|
+
reject(&:blank?).
|
50
|
+
map { |p| p.split('=') }
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def query_params
|
56
|
+
request.query_parameters
|
57
|
+
end
|
58
|
+
|
59
|
+
def request_params
|
60
|
+
request.request_parameters
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'oauth/request_proxy'
|
2
|
+
|
3
|
+
module OAuth::RequestProxy
|
4
|
+
class Base
|
5
|
+
def self.proxies(klass)
|
6
|
+
OAuth::RequestProxy.available_proxies[klass] = self
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :request, :options
|
10
|
+
|
11
|
+
def initialize(request, options = {})
|
12
|
+
@request = request
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def token
|
17
|
+
parameters['oauth_token']
|
18
|
+
end
|
19
|
+
|
20
|
+
def consumer_key
|
21
|
+
parameters['oauth_consumer_key']
|
22
|
+
end
|
23
|
+
|
24
|
+
def parameters_for_signature
|
25
|
+
p = parameters.dup
|
26
|
+
p.delete("oauth_signature")
|
27
|
+
p
|
28
|
+
end
|
29
|
+
|
30
|
+
def nonce
|
31
|
+
parameters['oauth_nonce']
|
32
|
+
end
|
33
|
+
|
34
|
+
def timestamp
|
35
|
+
parameters['oauth_timestamp']
|
36
|
+
end
|
37
|
+
|
38
|
+
def signature_method
|
39
|
+
case parameters['oauth_signature_method']
|
40
|
+
when Array: parameters['oauth_signature_method'].first
|
41
|
+
else
|
42
|
+
parameters['oauth_signature_method']
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def signature
|
47
|
+
parameters['oauth_signature'] || ""
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def header_params
|
53
|
+
%w( X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION ).each do |header|
|
54
|
+
next unless request.env.include?(header)
|
55
|
+
|
56
|
+
header = request.env[header]
|
57
|
+
next unless header[0,6] == 'OAuth '
|
58
|
+
|
59
|
+
oauth_param_string = header[6,header.length].split(/[,=]/)
|
60
|
+
oauth_param_string.map! { |v| unescape(v.strip) }
|
61
|
+
oauth_param_string.map! { |v| v =~ /^\".*\"$/ ? v[1..-2] : v }
|
62
|
+
oauth_params = Hash[*oauth_param_string.flatten]
|
63
|
+
oauth_params.reject! { |k,v| k !~ /^oauth_/ }
|
64
|
+
|
65
|
+
return oauth_params
|
66
|
+
end
|
67
|
+
|
68
|
+
return {}
|
69
|
+
end
|
70
|
+
|
71
|
+
def unescape(value)
|
72
|
+
URI.unescape(value.gsub('+', '%2B'))
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'oauth/request_proxy/base'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module OAuth::RequestProxy::Net
|
7
|
+
module HTTP
|
8
|
+
class HTTPRequest < OAuth::RequestProxy::Base
|
9
|
+
proxies ::Net::HTTPRequest
|
10
|
+
|
11
|
+
def method
|
12
|
+
request.method
|
13
|
+
end
|
14
|
+
|
15
|
+
def uri
|
16
|
+
uri = options[:uri]
|
17
|
+
uri = URI.parse(uri) unless uri.kind_of?(URI)
|
18
|
+
uri.query = nil
|
19
|
+
uri.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def parameters
|
23
|
+
if options[:clobber_request]
|
24
|
+
options[:parameters]
|
25
|
+
else
|
26
|
+
all_parameters
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def all_parameters
|
33
|
+
request_params = CGI.parse(query_string)
|
34
|
+
if options[:parameters]
|
35
|
+
options[:parameters].each do |k,v|
|
36
|
+
if request_params.has_key?(k)
|
37
|
+
request_params[k] << v
|
38
|
+
else
|
39
|
+
request_params[k] = [v].flatten
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
request_params
|
44
|
+
end
|
45
|
+
|
46
|
+
def query_string
|
47
|
+
params = [ query_params, auth_header_params ]
|
48
|
+
is_form_urlencoded = request['Content-Type'] != nil && request['Content-Type'].downcase == 'application/x-www-form-urlencoded'
|
49
|
+
params << post_params if method.to_s.upcase == 'POST' && is_form_urlencoded
|
50
|
+
params.compact.join('&')
|
51
|
+
end
|
52
|
+
|
53
|
+
def query_params
|
54
|
+
URI.parse(request.path).query
|
55
|
+
end
|
56
|
+
|
57
|
+
def post_params
|
58
|
+
request.body
|
59
|
+
end
|
60
|
+
|
61
|
+
def auth_header_params
|
62
|
+
return nil unless request['Authorization'] && request['Authorization'][0,5] == 'OAuth'
|
63
|
+
auth_params = request['Authorization']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'oauth/request_proxy/base'
|
2
|
+
require 'uri'
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
module OAuth::RequestProxy
|
6
|
+
class RackRequest < OAuth::RequestProxy::Base
|
7
|
+
proxies Rack::Request
|
8
|
+
|
9
|
+
def method
|
10
|
+
request.request_method
|
11
|
+
end
|
12
|
+
|
13
|
+
def uri
|
14
|
+
uri = URI.parse(request.url)
|
15
|
+
uri.query = nil
|
16
|
+
uri.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def parameters
|
20
|
+
if options[:clobber_request]
|
21
|
+
options[:parameters] || {}
|
22
|
+
else
|
23
|
+
params = request_params.merge(query_params).merge(header_params)
|
24
|
+
params.merge(options[:parameters] || {})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def signature
|
29
|
+
parameters['oauth_signature']
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def query_params
|
35
|
+
request.GET
|
36
|
+
end
|
37
|
+
|
38
|
+
def request_params
|
39
|
+
request.params
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/oauth/server.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'oauth/helper'
|
2
|
+
require 'oauth/consumer'
|
3
|
+
module OAuth
|
4
|
+
# This is mainly used to create consumer credentials and can pretty much be ignored if you want to create your own
|
5
|
+
class Server
|
6
|
+
include OAuth::Helper
|
7
|
+
attr_accessor :base_url
|
8
|
+
|
9
|
+
@@server_paths={
|
10
|
+
:request_token_path=>"/oauth/request_token",
|
11
|
+
:authorize_path=>"/oauth/authorize",
|
12
|
+
:access_token_path=>"/oauth/access_token"
|
13
|
+
}
|
14
|
+
# Create a new server instance
|
15
|
+
def initialize(base_url,paths={})
|
16
|
+
@base_url=base_url
|
17
|
+
@paths=@@server_paths.merge(paths)
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_credentials()
|
21
|
+
[generate_key(16),generate_key]
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_consumer_credentials(params={})
|
25
|
+
Consumer.new( *generate_credentials)
|
26
|
+
end
|
27
|
+
|
28
|
+
# mainly for testing purposes
|
29
|
+
def create_consumer
|
30
|
+
credentials=generate_credentials
|
31
|
+
Consumer.new(
|
32
|
+
credentials[0],
|
33
|
+
credentials[1],
|
34
|
+
{
|
35
|
+
:site=>base_url,
|
36
|
+
:request_token_path=>request_token_path,
|
37
|
+
:authorize_path=>authorize_path,
|
38
|
+
:access_token_path=>access_token_path
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_token_path
|
43
|
+
@paths[:request_token_path]
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_token_url
|
47
|
+
base_url+request_token_path
|
48
|
+
end
|
49
|
+
|
50
|
+
def authorize_path
|
51
|
+
@paths[:authorize_path]
|
52
|
+
end
|
53
|
+
|
54
|
+
def authorize_url
|
55
|
+
base_url+authorize_path
|
56
|
+
end
|
57
|
+
|
58
|
+
def access_token_path
|
59
|
+
@paths[:access_token_path]
|
60
|
+
end
|
61
|
+
|
62
|
+
def access_token_url
|
63
|
+
base_url+access_token_path
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module OAuth
|
2
|
+
module Signature
|
3
|
+
def self.available_methods
|
4
|
+
@available_methods ||= {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.build(request, options = {}, &block)
|
8
|
+
request = OAuth::RequestProxy.proxy(request, options)
|
9
|
+
klass = available_methods[(request.signature_method || "").downcase]
|
10
|
+
raise UnknownSignatureMethod, request.signature_method unless klass
|
11
|
+
klass.new(request, options, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.sign(request, options = {}, &block)
|
15
|
+
self.build(request, options, &block).signature
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.verify(request, options = {}, &block)
|
19
|
+
self.build(request, options, &block).verify
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.signature_base_string(request, options = {}, &block)
|
23
|
+
self.build(request, options, &block).signature_base_string
|
24
|
+
end
|
25
|
+
|
26
|
+
class UnknownSignatureMethod < Exception; end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'oauth/signature'
|
2
|
+
require 'oauth/helper'
|
3
|
+
require 'oauth/request_proxy/base'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
module OAuth::Signature
|
7
|
+
class Base
|
8
|
+
include OAuth::Helper
|
9
|
+
|
10
|
+
attr_accessor :options
|
11
|
+
|
12
|
+
def self.implements(signature_method)
|
13
|
+
OAuth::Signature.available_methods[signature_method] = self
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.digest_class(digest_class = nil)
|
17
|
+
return @digest_class if digest_class.nil?
|
18
|
+
@digest_class = digest_class
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :token_secret, :consumer_secret, :request
|
22
|
+
|
23
|
+
def initialize(request, options = {}, &block)
|
24
|
+
raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
|
25
|
+
@request = request
|
26
|
+
@options = options
|
27
|
+
if block_given?
|
28
|
+
@token_secret, @consumer_secret = yield block.arity == 1 ? token : [token, consumer_key,nonce,request.timestamp]
|
29
|
+
else
|
30
|
+
@consumer_secret = @options[:consumer].secret
|
31
|
+
@token_secret = @options[:token] ? @options[:token].secret : ''
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def signature
|
36
|
+
Base64.encode64(digest).chomp.gsub(/\n/,'')
|
37
|
+
end
|
38
|
+
|
39
|
+
def ==(cmp_signature)
|
40
|
+
Base64.decode64(signature) == Base64.decode64(cmp_signature)
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify
|
44
|
+
self == self.request.signature
|
45
|
+
end
|
46
|
+
|
47
|
+
def signature_base_string
|
48
|
+
normalized_params = request.parameters_for_signature.sort.map { |k,v| [escape(k), escape(v)] * "=" }.join("&")
|
49
|
+
base = [request.method, request.uri, normalized_params]
|
50
|
+
sbs = base.map { |v| escape(v) }.join("&")
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def token
|
56
|
+
request.token
|
57
|
+
end
|
58
|
+
|
59
|
+
def consumer_key
|
60
|
+
request.consumer_key
|
61
|
+
end
|
62
|
+
|
63
|
+
def nonce
|
64
|
+
request.nonce
|
65
|
+
end
|
66
|
+
|
67
|
+
def secret
|
68
|
+
"#{escape(consumer_secret)}&#{escape(token_secret)}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def digest
|
72
|
+
self.class.digest_class.digest(signature_base_string)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|