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
@@ -16,70 +16,133 @@ module OAuth::RequestProxy
|
|
16
16
|
@options = options
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
parameters['oauth_token']
|
21
|
-
end
|
19
|
+
## OAuth parameters
|
22
20
|
|
23
|
-
def
|
24
|
-
parameters['
|
21
|
+
def oauth_callback
|
22
|
+
parameters['oauth_callback']
|
25
23
|
end
|
26
24
|
|
27
|
-
def
|
28
|
-
|
29
|
-
p.delete("oauth_signature")
|
30
|
-
p
|
25
|
+
def oauth_consumer_key
|
26
|
+
parameters['oauth_consumer_key']
|
31
27
|
end
|
32
28
|
|
33
|
-
def
|
29
|
+
def oauth_nonce
|
34
30
|
parameters['oauth_nonce']
|
35
31
|
end
|
36
32
|
|
37
|
-
def
|
38
|
-
|
33
|
+
def oauth_signature
|
34
|
+
# TODO can this be nil?
|
35
|
+
parameters['oauth_signature'] || ""
|
39
36
|
end
|
40
37
|
|
41
|
-
def
|
38
|
+
def oauth_signature_method
|
42
39
|
case parameters['oauth_signature_method']
|
43
|
-
when Array
|
40
|
+
when Array
|
41
|
+
parameters['oauth_signature_method'].first
|
44
42
|
else
|
45
43
|
parameters['oauth_signature_method']
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
49
|
-
def
|
50
|
-
parameters['
|
47
|
+
def oauth_timestamp
|
48
|
+
parameters['oauth_timestamp']
|
49
|
+
end
|
50
|
+
|
51
|
+
def oauth_token
|
52
|
+
parameters['oauth_token']
|
53
|
+
end
|
54
|
+
|
55
|
+
def oauth_verifier
|
56
|
+
parameters['oauth_verifier']
|
57
|
+
end
|
58
|
+
|
59
|
+
def oauth_version
|
60
|
+
parameters["oauth_version"]
|
61
|
+
end
|
62
|
+
|
63
|
+
# TODO deprecate these
|
64
|
+
alias_method :consumer_key, :oauth_consumer_key
|
65
|
+
alias_method :token, :oauth_token
|
66
|
+
alias_method :nonce, :oauth_nonce
|
67
|
+
alias_method :timestamp, :oauth_timestamp
|
68
|
+
alias_method :signature, :oauth_signature
|
69
|
+
alias_method :signature_method, :oauth_signature_method
|
70
|
+
|
71
|
+
## Parameter accessors
|
72
|
+
|
73
|
+
def parameters
|
74
|
+
raise NotImplementedError, "Must be implemented by subclasses"
|
51
75
|
end
|
52
|
-
|
76
|
+
|
77
|
+
def parameters_for_signature
|
78
|
+
parameters.reject { |k,v| k == "oauth_signature" }
|
79
|
+
end
|
80
|
+
|
81
|
+
def oauth_parameters
|
82
|
+
parameters.select { |k,v| OAuth::PARAMETERS.include?(k) }.reject { |k,v| v == "" }
|
83
|
+
end
|
84
|
+
|
85
|
+
def non_oauth_parameters
|
86
|
+
parameters.reject { |k,v| OAuth::PARAMETERS.include?(k) }
|
87
|
+
end
|
88
|
+
|
53
89
|
# See 9.1.2 in specs
|
54
90
|
def normalized_uri
|
55
|
-
u=URI.parse(uri)
|
56
|
-
"#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.downcase=='http'&&u.port!=80)||(u.scheme.downcase=='https'&&u.port!=443) ? ":#{u.port}" : ""}#{(u.path&&u.path!='') ? u.path : '/'}"
|
91
|
+
u = URI.parse(uri)
|
92
|
+
"#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.downcase == 'http' && u.port != 80) || (u.scheme.downcase == 'https' && u.port != 443) ? ":#{u.port}" : ""}#{(u.path && u.path != '') ? u.path : '/'}"
|
57
93
|
end
|
58
|
-
|
94
|
+
|
59
95
|
# See 9.1.1. in specs Normalize Request Parameters
|
60
96
|
def normalized_parameters
|
61
|
-
parameters_for_signature
|
97
|
+
normalize(parameters_for_signature)
|
98
|
+
end
|
62
99
|
|
63
|
-
|
64
|
-
|
65
|
-
values.sort.collect do |v|
|
66
|
-
[escape(k),escape(v)] * "="
|
67
|
-
end
|
68
|
-
else
|
69
|
-
[escape(k),escape(values)] * "="
|
70
|
-
end
|
71
|
-
end * "&"
|
100
|
+
def sign(options = {})
|
101
|
+
OAuth::Signature.sign(self, options)
|
72
102
|
end
|
73
|
-
|
103
|
+
|
104
|
+
def sign!(options = {})
|
105
|
+
parameters["oauth_signature"] = sign(options)
|
106
|
+
@signed = true
|
107
|
+
signature
|
108
|
+
end
|
109
|
+
|
74
110
|
# See 9.1 in specs
|
75
111
|
def signature_base_string
|
76
112
|
base = [method, normalized_uri, normalized_parameters]
|
77
113
|
base.map { |v| escape(v) }.join("&")
|
78
114
|
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
115
|
+
|
116
|
+
# Has this request been signed yet?
|
117
|
+
def signed?
|
118
|
+
@signed
|
119
|
+
end
|
120
|
+
|
121
|
+
# URI, including OAuth parameters
|
122
|
+
def signed_uri(with_oauth = true)
|
123
|
+
if signed?
|
124
|
+
if with_oauth
|
125
|
+
params = parameters
|
126
|
+
else
|
127
|
+
params = non_oauth_parameters
|
128
|
+
end
|
129
|
+
|
130
|
+
[uri, normalize(params)] * "?"
|
131
|
+
else
|
132
|
+
STDERR.puts "This request has not yet been signed!"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Authorization header for OAuth
|
137
|
+
def oauth_header(options = {})
|
138
|
+
header_params_str = oauth_parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
|
139
|
+
|
140
|
+
realm = "realm=\"#{options[:realm]}\", " if options[:realm]
|
141
|
+
"OAuth #{realm}#{header_params_str}"
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
83
146
|
def header_params
|
84
147
|
%w( X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION ).each do |header|
|
85
148
|
next unless request.env.include?(header)
|
@@ -87,10 +150,10 @@ module OAuth::RequestProxy
|
|
87
150
|
header = request.env[header]
|
88
151
|
next unless header[0,6] == 'OAuth '
|
89
152
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
153
|
+
# parse the header into a Hash
|
154
|
+
oauth_params = OAuth::Helper.parse_header(header)
|
155
|
+
|
156
|
+
# remove non-OAuth parameters
|
94
157
|
oauth_params.reject! { |k,v| k !~ /^oauth_/ }
|
95
158
|
|
96
159
|
return oauth_params
|
@@ -98,10 +161,5 @@ module OAuth::RequestProxy
|
|
98
161
|
|
99
162
|
return {}
|
100
163
|
end
|
101
|
-
|
102
|
-
def unescape(value)
|
103
|
-
URI.unescape(value.gsub('+', '%2B'))
|
104
|
-
end
|
105
|
-
|
106
164
|
end
|
107
165
|
end
|
@@ -28,6 +28,14 @@ module OAuth
|
|
28
28
|
@request["method"]
|
29
29
|
end
|
30
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
|
+
|
31
39
|
def uri
|
32
40
|
@request["uri"]
|
33
41
|
end
|
@@ -25,7 +25,7 @@ module OAuth::RequestProxy::Net
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
private
|
29
29
|
|
30
30
|
def all_parameters
|
31
31
|
request_params = CGI.parse(query_string)
|
@@ -47,7 +47,7 @@ module OAuth::RequestProxy::Net
|
|
47
47
|
params << post_params if method.to_s.upcase == 'POST' && is_form_urlencoded
|
48
48
|
params.compact.join('&')
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def query_params
|
52
52
|
URI.parse(request.path).query
|
53
53
|
end
|
@@ -5,11 +5,11 @@ require 'rack'
|
|
5
5
|
module OAuth::RequestProxy
|
6
6
|
class RackRequest < OAuth::RequestProxy::Base
|
7
7
|
proxies Rack::Request
|
8
|
-
|
8
|
+
|
9
9
|
def method
|
10
|
-
request.request_method
|
10
|
+
request.env["rack.methodoverride.original_method"] || request.request_method
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def uri
|
14
14
|
request.url
|
15
15
|
end
|
@@ -22,12 +22,12 @@ module OAuth::RequestProxy
|
|
22
22
|
params.merge(options[:parameters] || {})
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def signature
|
27
27
|
parameters['oauth_signature']
|
28
28
|
end
|
29
|
-
|
30
|
-
|
29
|
+
|
30
|
+
protected
|
31
31
|
|
32
32
|
def query_params
|
33
33
|
request.GET
|
@@ -37,4 +37,4 @@ module OAuth::RequestProxy
|
|
37
37
|
request.params
|
38
38
|
end
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
data/lib/oauth/server.rb
CHANGED
@@ -1,68 +1,66 @@
|
|
1
1
|
require 'oauth/helper'
|
2
2
|
require 'oauth/consumer'
|
3
|
+
|
3
4
|
module OAuth
|
4
5
|
# This is mainly used to create consumer credentials and can pretty much be ignored if you want to create your own
|
5
6
|
class Server
|
6
7
|
include OAuth::Helper
|
7
8
|
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"
|
9
|
+
|
10
|
+
@@server_paths = {
|
11
|
+
:request_token_path => "/oauth/request_token",
|
12
|
+
:authorize_path => "/oauth/authorize",
|
13
|
+
:access_token_path => "/oauth/access_token"
|
13
14
|
}
|
15
|
+
|
14
16
|
# Create a new server instance
|
15
|
-
def initialize(base_url,paths={})
|
16
|
-
@base_url=base_url
|
17
|
-
@paths
|
17
|
+
def initialize(base_url, paths = {})
|
18
|
+
@base_url = base_url
|
19
|
+
@paths = @@server_paths.merge(paths)
|
18
20
|
end
|
19
|
-
|
20
|
-
def generate_credentials
|
21
|
-
[generate_key(16),generate_key]
|
21
|
+
|
22
|
+
def generate_credentials
|
23
|
+
[generate_key(16), generate_key]
|
22
24
|
end
|
23
|
-
|
24
|
-
def generate_consumer_credentials(params={})
|
25
|
-
Consumer.new(
|
25
|
+
|
26
|
+
def generate_consumer_credentials(params = {})
|
27
|
+
Consumer.new(*generate_credentials)
|
26
28
|
end
|
27
29
|
|
28
30
|
# mainly for testing purposes
|
29
31
|
def create_consumer
|
30
|
-
|
31
|
-
Consumer.new(
|
32
|
-
credentials[0],
|
33
|
-
credentials[1],
|
32
|
+
creds = generate_credentials
|
33
|
+
Consumer.new(creds[0], creds[1],
|
34
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
|
-
|
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
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def request_token_path
|
43
43
|
@paths[:request_token_path]
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def request_token_url
|
47
|
-
base_url+request_token_path
|
47
|
+
base_url + request_token_path
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def authorize_path
|
51
51
|
@paths[:authorize_path]
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
def authorize_url
|
55
|
-
base_url+authorize_path
|
55
|
+
base_url + authorize_path
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def access_token_path
|
59
59
|
@paths[:access_token_path]
|
60
60
|
end
|
61
61
|
|
62
62
|
def access_token_url
|
63
|
-
base_url+access_token_path
|
63
|
+
base_url + access_token_path
|
64
64
|
end
|
65
|
-
|
66
|
-
|
67
65
|
end
|
68
66
|
end
|
data/lib/oauth/signature/base.rb
CHANGED
@@ -6,9 +6,10 @@ require 'base64'
|
|
6
6
|
module OAuth::Signature
|
7
7
|
class Base
|
8
8
|
include OAuth::Helper
|
9
|
-
|
9
|
+
|
10
10
|
attr_accessor :options
|
11
|
-
|
11
|
+
attr_reader :token_secret, :consumer_secret, :request
|
12
|
+
|
12
13
|
def self.implements(signature_method)
|
13
14
|
OAuth::Signature.available_methods[signature_method] = self
|
14
15
|
end
|
@@ -18,32 +19,34 @@ module OAuth::Signature
|
|
18
19
|
@digest_class = digest_class
|
19
20
|
end
|
20
21
|
|
21
|
-
attr_reader :token_secret, :consumer_secret, :request
|
22
|
-
|
23
22
|
def initialize(request, options = {}, &block)
|
24
23
|
raise TypeError unless request.kind_of?(OAuth::RequestProxy::Base)
|
25
24
|
@request = request
|
26
25
|
@options = options
|
27
26
|
|
28
|
-
|
27
|
+
## consumer secret was determined beforehand
|
29
28
|
|
30
|
-
|
31
|
-
@token_secret, @consumer_secret = yield block.arity == 1 ? request : [token, consumer_key,nonce,request.timestamp]
|
29
|
+
@consumer_secret = options[:consumer].secret if options[:consumer]
|
32
30
|
|
33
|
-
|
34
|
-
|
31
|
+
# presence of :consumer_secret option will override any Consumer that's provided
|
32
|
+
@consumer_secret = options[:consumer_secret] if options[:consumer_secret]
|
35
33
|
|
36
|
-
|
34
|
+
## token secret was determined beforehand
|
37
35
|
|
38
|
-
|
39
|
-
@consumer_secret = options[:consumer_secret] if options[:consumer_secret]
|
36
|
+
@token_secret = options[:token].secret if options[:token]
|
40
37
|
|
41
|
-
|
38
|
+
# presence of :token_secret option will override any Token that's provided
|
39
|
+
@token_secret = options[:token_secret] if options[:token_secret]
|
42
40
|
|
43
|
-
@token_secret = options[:token].secret if options[:token]
|
44
41
|
|
45
|
-
|
46
|
-
|
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
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
@@ -62,17 +65,17 @@ module OAuth::Signature
|
|
62
65
|
def signature_base_string
|
63
66
|
request.signature_base_string
|
64
67
|
end
|
65
|
-
|
66
|
-
|
68
|
+
|
69
|
+
private
|
67
70
|
|
68
71
|
def token
|
69
72
|
request.token
|
70
73
|
end
|
71
|
-
|
74
|
+
|
72
75
|
def consumer_key
|
73
76
|
request.consumer_key
|
74
77
|
end
|
75
|
-
|
78
|
+
|
76
79
|
def nonce
|
77
80
|
request.nonce
|
78
81
|
end
|
@@ -84,6 +87,5 @@ module OAuth::Signature
|
|
84
87
|
def digest
|
85
88
|
self.class.digest_class.digest(signature_base_string)
|
86
89
|
end
|
87
|
-
|
88
90
|
end
|
89
91
|
end
|
@@ -18,9 +18,9 @@ module OAuth::Signature::RSA
|
|
18
18
|
consumer_secret
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
24
|
def decode_public_key
|
25
25
|
case consumer_secret
|
26
26
|
when /-----BEGIN CERTIFICATE-----/
|
@@ -29,7 +29,7 @@ module OAuth::Signature::RSA
|
|
29
29
|
OpenSSL::PKey::RSA.new( consumer_secret)
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def digest
|
34
34
|
private_key = OpenSSL::PKey::RSA.new(
|
35
35
|
if options[:private_key_file]
|
@@ -38,6 +38,7 @@ module OAuth::Signature::RSA
|
|
38
38
|
consumer_secret
|
39
39
|
end
|
40
40
|
)
|
41
|
+
|
41
42
|
private_key.sign(OpenSSL::Digest::SHA1.new, signature_base_string)
|
42
43
|
end
|
43
44
|
end
|
data/lib/oauth/signature.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
module OAuth
|
2
2
|
module Signature
|
3
|
+
# Returns a list of available signature methods
|
3
4
|
def self.available_methods
|
4
5
|
@available_methods ||= {}
|
5
6
|
end
|
6
7
|
|
8
|
+
# Build a signature from a +request+.
|
9
|
+
#
|
10
|
+
# Raises UnknownSignatureMethod exception if the signature method is unknown.
|
7
11
|
def self.build(request, options = {}, &block)
|
8
12
|
request = OAuth::RequestProxy.proxy(request, options)
|
9
13
|
klass = available_methods[(request.signature_method || "").downcase]
|
@@ -11,14 +15,19 @@ module OAuth
|
|
11
15
|
klass.new(request, options, &block)
|
12
16
|
end
|
13
17
|
|
18
|
+
# Sign a +request+
|
14
19
|
def self.sign(request, options = {}, &block)
|
15
20
|
self.build(request, options, &block).signature
|
16
21
|
end
|
17
22
|
|
23
|
+
# Verify the signature of +request+
|
18
24
|
def self.verify(request, options = {}, &block)
|
19
25
|
self.build(request, options, &block).verify
|
20
26
|
end
|
21
27
|
|
28
|
+
# Create the signature base string for +request+. This string is the normalized parameter information.
|
29
|
+
#
|
30
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
22
31
|
def self.signature_base_string(request, options = {}, &block)
|
23
32
|
self.build(request, options, &block).signature_base_string
|
24
33
|
end
|