qoobaa-oauth 0.3.8
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/.document +5 -0
- data/.gitignore +21 -0
- data/History.txt +114 -0
- data/LICENSE +20 -0
- data/README.rdoc +71 -0
- data/Rakefile +58 -0
- data/TODO +31 -0
- data/VERSION +1 -0
- data/lib/oauth.rb +4 -0
- data/lib/oauth/cli.rb +378 -0
- data/lib/oauth/client.rb +4 -0
- data/lib/oauth/client/action_controller_request.rb +54 -0
- data/lib/oauth/client/helper.rb +85 -0
- data/lib/oauth/client/net_http.rb +106 -0
- data/lib/oauth/consumer.rb +370 -0
- data/lib/oauth/errors.rb +3 -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/helper.rb +78 -0
- data/lib/oauth/oauth.rb +11 -0
- data/lib/oauth/oauth_test_helper.rb +25 -0
- data/lib/oauth/request_proxy.rb +24 -0
- data/lib/oauth/request_proxy/action_controller_request.rb +73 -0
- data/lib/oauth/request_proxy/base.rb +166 -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/typhoeus_request.rb +53 -0
- data/lib/oauth/server.rb +66 -0
- data/lib/oauth/signature.rb +40 -0
- data/lib/oauth/signature/base.rb +87 -0
- data/lib/oauth/signature/hmac/md5.rb +21 -0
- data/lib/oauth/signature/hmac/rmd160.rb +21 -0
- data/lib/oauth/signature/hmac/sha1.rb +22 -0
- data/lib/oauth/signature/hmac/sha2.rb +21 -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/token.rb +7 -0
- 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 +3 -0
- data/qoobaa-oauth.gemspec +149 -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/integration/consumer_test.rb +304 -0
- data/test/keys/rsa.cert +11 -0
- data/test/keys/rsa.pem +16 -0
- data/test/test_access_token.rb +26 -0
- data/test/test_action_controller_request_proxy.rb +133 -0
- data/test/test_consumer.rb +159 -0
- data/test/test_helper.rb +14 -0
- data/test/test_hmac_sha1.rb +20 -0
- data/test/test_net_http_client.rb +224 -0
- data/test/test_net_http_request_proxy.rb +72 -0
- data/test/test_oauth_helper.rb +49 -0
- data/test/test_rack_request_proxy.rb +40 -0
- data/test/test_request_token.rb +51 -0
- data/test/test_rsa_sha1.rb +59 -0
- data/test/test_server.rb +40 -0
- data/test/test_signature.rb +21 -0
- data/test/test_signature_base.rb +32 -0
- data/test/test_signature_plain_text.rb +26 -0
- data/test/test_token.rb +14 -0
- data/test/test_typhoeus_request_proxy.rb +72 -0
- metadata +209 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'oauth/request_proxy/base'
|
2
|
+
|
3
|
+
module OAuth
|
4
|
+
module RequestProxy
|
5
|
+
# RequestProxy for Hashes to facilitate simpler signature creation.
|
6
|
+
# Usage:
|
7
|
+
# request = OAuth::RequestProxy.proxy \
|
8
|
+
# "method" => "iq",
|
9
|
+
# "uri" => [from, to] * "&",
|
10
|
+
# "parameters" => {
|
11
|
+
# "oauth_consumer_key" => oauth_consumer_key,
|
12
|
+
# "oauth_token" => oauth_token,
|
13
|
+
# "oauth_signature_method" => "HMAC-SHA1"
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# signature = OAuth::Signature.sign \
|
17
|
+
# request,
|
18
|
+
# :consumer_secret => oauth_consumer_secret,
|
19
|
+
# :token_secret => oauth_token_secret,
|
20
|
+
class MockRequest < OAuth::RequestProxy::Base
|
21
|
+
proxies Hash
|
22
|
+
|
23
|
+
def parameters
|
24
|
+
@request["parameters"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def method
|
28
|
+
@request["method"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def normalized_uri
|
32
|
+
super
|
33
|
+
rescue
|
34
|
+
# if this is a non-standard URI, it may not parse properly
|
35
|
+
# in that case, assume that it's already been normalized
|
36
|
+
uri
|
37
|
+
end
|
38
|
+
|
39
|
+
def uri
|
40
|
+
@request["uri"]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def parameters
|
21
|
+
if options[:clobber_request]
|
22
|
+
options[:parameters]
|
23
|
+
else
|
24
|
+
all_parameters
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def all_parameters
|
31
|
+
request_params = CGI.parse(query_string)
|
32
|
+
if options[:parameters]
|
33
|
+
options[:parameters].each do |k,v|
|
34
|
+
if request_params.has_key?(k)
|
35
|
+
request_params[k] << v
|
36
|
+
else
|
37
|
+
request_params[k] = [v].flatten
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
request_params
|
42
|
+
end
|
43
|
+
|
44
|
+
def query_string
|
45
|
+
params = [ query_params, auth_header_params ]
|
46
|
+
is_form_urlencoded = request['Content-Type'] != nil && request['Content-Type'].downcase == 'application/x-www-form-urlencoded'
|
47
|
+
params << post_params if method.to_s.upcase == 'POST' && is_form_urlencoded
|
48
|
+
params.compact.join('&')
|
49
|
+
end
|
50
|
+
|
51
|
+
def query_params
|
52
|
+
URI.parse(request.path).query
|
53
|
+
end
|
54
|
+
|
55
|
+
def post_params
|
56
|
+
request.body
|
57
|
+
end
|
58
|
+
|
59
|
+
def auth_header_params
|
60
|
+
return nil unless request['Authorization'] && request['Authorization'][0,5] == 'OAuth'
|
61
|
+
auth_params = request['Authorization']
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,40 @@
|
|
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.env["rack.methodoverride.original_method"] || request.request_method
|
11
|
+
end
|
12
|
+
|
13
|
+
def uri
|
14
|
+
request.url
|
15
|
+
end
|
16
|
+
|
17
|
+
def parameters
|
18
|
+
if options[:clobber_request]
|
19
|
+
options[:parameters] || {}
|
20
|
+
else
|
21
|
+
params = request_params.merge(query_params).merge(header_params)
|
22
|
+
params.merge(options[:parameters] || {})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def signature
|
27
|
+
parameters['oauth_signature']
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def query_params
|
33
|
+
request.GET
|
34
|
+
end
|
35
|
+
|
36
|
+
def request_params
|
37
|
+
request.params
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'oauth/request_proxy/base'
|
2
|
+
require 'typhoeus'
|
3
|
+
require 'typhoeus/request'
|
4
|
+
require 'uri'
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
module OAuth::RequestProxy::Typhoeus
|
8
|
+
class Request < OAuth::RequestProxy::Base
|
9
|
+
# Proxy for signing Typhoeus::Request requests
|
10
|
+
# Usage example:
|
11
|
+
# oauth_params = {:consumer => oauth_consumer, :token => access_token}
|
12
|
+
# req = Typhoeus::Request.new(uri, options)
|
13
|
+
# oauth_helper = OAuth::Client::Helper.new(req, oauth_params.merge(:request_uri => uri))
|
14
|
+
# req.headers.merge!({"Authorization" => oauth_helper.header})
|
15
|
+
# hydra = Typhoeus::Hydra.new()
|
16
|
+
# hydra.queue(req)
|
17
|
+
# hydra.run
|
18
|
+
# response = req.response
|
19
|
+
proxies Typhoeus::Request
|
20
|
+
|
21
|
+
def method
|
22
|
+
request.method.to_s.upcase
|
23
|
+
end
|
24
|
+
|
25
|
+
def uri
|
26
|
+
options[:uri].to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def parameters
|
30
|
+
if options[:clobber_request]
|
31
|
+
options[:parameters]
|
32
|
+
else
|
33
|
+
post_parameters.merge(query_parameters).merge(options[:parameters] || {})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def query_parameters
|
40
|
+
query = URI.parse(request.url).query
|
41
|
+
return(query ? CGI.parse(query) : {})
|
42
|
+
end
|
43
|
+
|
44
|
+
def post_parameters
|
45
|
+
# Post params are only used if posting form data
|
46
|
+
if(method == 'POST' && request.headers['Content-Type'] && request.headers['Content-Type'].downcase == 'application/x-www-form-urlencoded')
|
47
|
+
request.body || {}
|
48
|
+
else
|
49
|
+
{}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/oauth/server.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'oauth/helper'
|
2
|
+
require 'oauth/consumer'
|
3
|
+
|
4
|
+
module OAuth
|
5
|
+
# This is mainly used to create consumer credentials and can pretty much be ignored if you want to create your own
|
6
|
+
class Server
|
7
|
+
include OAuth::Helper
|
8
|
+
attr_accessor :base_url
|
9
|
+
|
10
|
+
@@server_paths = {
|
11
|
+
:request_token_path => "/oauth/request_token",
|
12
|
+
:authorize_path => "/oauth/authorize",
|
13
|
+
:access_token_path => "/oauth/access_token"
|
14
|
+
}
|
15
|
+
|
16
|
+
# Create a new server instance
|
17
|
+
def initialize(base_url, paths = {})
|
18
|
+
@base_url = base_url
|
19
|
+
@paths = @@server_paths.merge(paths)
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_credentials
|
23
|
+
[generate_key(16), generate_key]
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_consumer_credentials(params = {})
|
27
|
+
Consumer.new(*generate_credentials)
|
28
|
+
end
|
29
|
+
|
30
|
+
# mainly for testing purposes
|
31
|
+
def create_consumer
|
32
|
+
creds = generate_credentials
|
33
|
+
Consumer.new(creds[0], creds[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
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module OAuth
|
2
|
+
module Signature
|
3
|
+
# Returns a list of available signature methods
|
4
|
+
def self.available_methods
|
5
|
+
@available_methods ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
# Build a signature from a +request+.
|
9
|
+
#
|
10
|
+
# Raises UnknownSignatureMethod exception if the signature method is unknown.
|
11
|
+
def self.build(request, options = {}, &block)
|
12
|
+
request = OAuth::RequestProxy.proxy(request, options)
|
13
|
+
klass = available_methods[
|
14
|
+
(request.signature_method ||
|
15
|
+
((c = request.options[:consumer]) && c.options[:signature_method]) ||
|
16
|
+
"").downcase]
|
17
|
+
raise UnknownSignatureMethod, request.signature_method unless klass
|
18
|
+
klass.new(request, options, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sign a +request+
|
22
|
+
def self.sign(request, options = {}, &block)
|
23
|
+
self.build(request, options, &block).signature
|
24
|
+
end
|
25
|
+
|
26
|
+
# Verify the signature of +request+
|
27
|
+
def self.verify(request, options = {}, &block)
|
28
|
+
self.build(request, options, &block).verify
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create the signature base string for +request+. This string is the normalized parameter information.
|
32
|
+
#
|
33
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
34
|
+
def self.signature_base_string(request, options = {}, &block)
|
35
|
+
self.build(request, options, &block).signature_base_string
|
36
|
+
end
|
37
|
+
|
38
|
+
class UnknownSignatureMethod < Exception; end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,87 @@
|
|
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
|
+
attr_reader :token_secret, :consumer_secret, :request
|
12
|
+
|
13
|
+
def self.implements(signature_method)
|
14
|
+
OAuth::Signature.available_methods[signature_method] = self
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.digest_class(digest_class = nil)
|
18
|
+
return @digest_class if digest_class.nil?
|
19
|
+
@digest_class = digest_class
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(request, options = {}, &block)
|
23
|
+
raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
|
24
|
+
@request = request
|
25
|
+
@options = options
|
26
|
+
|
27
|
+
## consumer secret was determined beforehand
|
28
|
+
|
29
|
+
@consumer_secret = options[:consumer].secret if options[:consumer]
|
30
|
+
|
31
|
+
# presence of :consumer_secret option will override any Consumer that's provided
|
32
|
+
@consumer_secret = options[:consumer_secret] if options[:consumer_secret]
|
33
|
+
|
34
|
+
## token secret was determined beforehand
|
35
|
+
|
36
|
+
@token_secret = options[:token].secret if options[:token]
|
37
|
+
|
38
|
+
# presence of :token_secret option will override any Token that's provided
|
39
|
+
@token_secret = options[:token_secret] if options[:token_secret]
|
40
|
+
|
41
|
+
|
42
|
+
# override secrets based on the values returned from the block (if any)
|
43
|
+
if block_given?
|
44
|
+
# consumer secret and token secret need to be looked up based on pieces of the request
|
45
|
+
secrets = yield block.arity == 1 ? request : [token, consumer_key, nonce, request.timestamp]
|
46
|
+
if secrets.is_a?(Array) && secrets.size == 2
|
47
|
+
@token_secret = secrets[0]
|
48
|
+
@consumer_secret = secrets[1]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def signature
|
54
|
+
Base64.encode64(digest).chomp.gsub(/\n/, "")
|
55
|
+
end
|
56
|
+
|
57
|
+
def ==(cmp_signature)
|
58
|
+
Base64.decode64(signature) == Base64.decode64(cmp_signature)
|
59
|
+
end
|
60
|
+
|
61
|
+
def verify
|
62
|
+
self == (request.signature.is_a?(Array) ? request.signature.first : request.signature)
|
63
|
+
end
|
64
|
+
|
65
|
+
def signature_base_string
|
66
|
+
request.signature_base_string
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def token
|
72
|
+
request.token
|
73
|
+
end
|
74
|
+
|
75
|
+
def consumer_key
|
76
|
+
request.consumer_key
|
77
|
+
end
|
78
|
+
|
79
|
+
def nonce
|
80
|
+
request.nonce
|
81
|
+
end
|
82
|
+
|
83
|
+
def secret
|
84
|
+
"#{escape(consumer_secret)}&#{escape(token_secret)}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'oauth/signature/base'
|
2
|
+
|
3
|
+
if RUBY_VERSION >= "1.9"
|
4
|
+
require 'digest/hmac'
|
5
|
+
else
|
6
|
+
require 'hmac-md5'
|
7
|
+
end
|
8
|
+
|
9
|
+
module OAuth::Signature::HMAC
|
10
|
+
class MD5 < OAuth::Signature::Base
|
11
|
+
implements 'hmac-md5'
|
12
|
+
|
13
|
+
def digest
|
14
|
+
if RUBY_VERSION >= "1.9"
|
15
|
+
Digest::HMAC.new(secret, Digest::MD5).digest(signature_base_string)
|
16
|
+
else
|
17
|
+
::HMAC::MD5.digest(secret, signature_base_string)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'oauth/signature/base'
|
2
|
+
|
3
|
+
if RUBY_VERSION >= "1.9"
|
4
|
+
require 'digest/hmac'
|
5
|
+
else
|
6
|
+
require 'hmac-rmd160'
|
7
|
+
end
|
8
|
+
|
9
|
+
module OAuth::Signature::HMAC
|
10
|
+
class RMD160 < OAuth::Signature::Base
|
11
|
+
implements 'hmac-rmd160'
|
12
|
+
|
13
|
+
def digest
|
14
|
+
if RUBY_VERSION >= "1.9"
|
15
|
+
Digest::HMAC.new(secret, Digest::RMD160).digest(signature_base_string)
|
16
|
+
else
|
17
|
+
::HMAC::RMD160.digest(secret, signature_base_string)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|