monkeyhelper-oauth 0.3.1 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|