oauth 1.1.0 → 1.1.6
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +1 -0
- data/CHANGELOG.md +637 -269
- data/CITATION.cff +20 -0
- data/CODE_OF_CONDUCT.md +79 -29
- data/CONTRIBUTING.md +256 -24
- data/FUNDING.md +74 -0
- data/LICENSE.md +71 -0
- data/README.md +615 -287
- data/RUBOCOP.md +71 -0
- data/SECURITY.md +11 -16
- data/certs/pboling.pem +27 -0
- data/lib/oauth/auth_sanitizer.rb +36 -0
- data/lib/oauth/client/action_controller_request.rb +22 -13
- data/lib/oauth/client/em_http.rb +106 -99
- data/lib/oauth/client/helper.rb +15 -11
- data/lib/oauth/client/net_http.rb +39 -13
- data/lib/oauth/consumer.rb +194 -75
- data/lib/oauth/errors/problem.rb +1 -1
- data/lib/oauth/helper.rb +25 -3
- data/lib/oauth/oauth.rb +28 -6
- data/lib/oauth/optional.rb +20 -0
- data/lib/oauth/request_proxy/action_controller_request.rb +11 -7
- data/lib/oauth/request_proxy/action_dispatch_request.rb +34 -0
- data/lib/oauth/request_proxy/base.rb +38 -27
- data/lib/oauth/request_proxy/em_http_request.rb +53 -52
- data/lib/oauth/request_proxy/jabber_request.rb +9 -2
- data/lib/oauth/request_proxy/net_http.rb +1 -1
- data/lib/oauth/request_proxy/rack_request.rb +0 -4
- data/lib/oauth/request_proxy/rest_client_request.rb +4 -3
- data/lib/oauth/request_proxy.rb +17 -13
- data/lib/oauth/server.rb +12 -8
- data/lib/oauth/signature/base.rb +15 -5
- data/lib/oauth/signature/rsa/sha1.rb +11 -4
- data/lib/oauth/signature.rb +43 -39
- data/lib/oauth/tokens/access_token.rb +1 -1
- data/lib/oauth/tokens/consumer_token.rb +8 -6
- data/lib/oauth/tokens/request_token.rb +9 -4
- data/lib/oauth/tokens/token.rb +13 -1
- data/lib/oauth/version.rb +2 -1
- data/lib/oauth.rb +2 -0
- data/sig/oauth/consumer.rbs +9 -0
- data/sig/oauth/signature/base.rbs +12 -0
- data/sig/oauth/tokens/token.rbs +8 -0
- data/sig/oauth/version.rbs +6 -0
- data.tar.gz.sig +0 -0
- metadata +316 -79
- metadata.gz.sig +0 -0
- data/LICENSE +0 -22
- data/TODO +0 -32
|
@@ -8,8 +8,10 @@ module OAuth
|
|
|
8
8
|
class Base
|
|
9
9
|
include OAuth::Helper
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
class << self
|
|
12
|
+
def proxies(klass)
|
|
13
|
+
OAuth::RequestProxy.available_proxies[klass] = self
|
|
14
|
+
end
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
attr_accessor :request, :options, :unsigned_parameters
|
|
@@ -23,15 +25,15 @@ module OAuth
|
|
|
23
25
|
## OAuth parameters
|
|
24
26
|
|
|
25
27
|
def oauth_callback
|
|
26
|
-
parameters["oauth_callback"]
|
|
28
|
+
[parameters["oauth_callback"]].flatten.first
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
def oauth_consumer_key
|
|
30
|
-
parameters["oauth_consumer_key"]
|
|
32
|
+
[parameters["oauth_consumer_key"]].flatten.first
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def oauth_nonce
|
|
34
|
-
parameters["oauth_nonce"]
|
|
36
|
+
[parameters["oauth_nonce"]].flatten.first
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def oauth_signature
|
|
@@ -40,37 +42,35 @@ module OAuth
|
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
def oauth_signature_method
|
|
43
|
-
|
|
44
|
-
when Array
|
|
45
|
-
parameters["oauth_signature_method"].first
|
|
46
|
-
else
|
|
47
|
-
parameters["oauth_signature_method"]
|
|
48
|
-
end
|
|
45
|
+
[parameters["oauth_signature_method"]].flatten.first
|
|
49
46
|
end
|
|
50
47
|
|
|
51
48
|
def oauth_timestamp
|
|
52
|
-
parameters["oauth_timestamp"]
|
|
49
|
+
[parameters["oauth_timestamp"]].flatten.first
|
|
53
50
|
end
|
|
54
51
|
|
|
55
52
|
def oauth_token
|
|
56
|
-
parameters["oauth_token"]
|
|
53
|
+
[parameters["oauth_token"]].flatten.first
|
|
57
54
|
end
|
|
58
55
|
|
|
56
|
+
# OAuth 1.0a only: value returned to the Consumer after user authorization
|
|
57
|
+
# and required when exchanging a Request Token for an Access Token.
|
|
58
|
+
# Not present in OAuth 1.0 flows.
|
|
59
59
|
def oauth_verifier
|
|
60
|
-
parameters["oauth_verifier"]
|
|
60
|
+
[parameters["oauth_verifier"]].flatten.first
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def oauth_version
|
|
64
|
-
parameters["oauth_version"]
|
|
64
|
+
[parameters["oauth_version"]].flatten.first
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# TODO: deprecate these
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
alias_method :consumer_key, :oauth_consumer_key
|
|
69
|
+
alias_method :token, :oauth_token
|
|
70
|
+
alias_method :nonce, :oauth_nonce
|
|
71
|
+
alias_method :timestamp, :oauth_timestamp
|
|
72
|
+
alias_method :signature, :oauth_signature
|
|
73
|
+
alias_method :signature_method, :oauth_signature_method
|
|
74
74
|
|
|
75
75
|
## Parameter accessors
|
|
76
76
|
|
|
@@ -97,7 +97,7 @@ module OAuth
|
|
|
97
97
|
# See 9.1.2 in specs
|
|
98
98
|
def normalized_uri
|
|
99
99
|
u = URI.parse(uri)
|
|
100
|
-
"#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.casecmp("http").zero? && u.port != 80) || (u.scheme.casecmp("https").zero? && u.port != 443)
|
|
100
|
+
"#{u.scheme.downcase}://#{u.host.downcase}#{":#{u.port}" if (u.scheme.casecmp("http").zero? && u.port != 80) || (u.scheme.casecmp("https").zero? && u.port != 443)}#{(u.path && u.path != "") ? u.path : "/"}"
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
# See 9.1.1. in specs Normalize Request Parameters
|
|
@@ -130,14 +130,14 @@ module OAuth
|
|
|
130
130
|
def signed_uri(with_oauth: true)
|
|
131
131
|
if signed?
|
|
132
132
|
params = if with_oauth
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
parameters
|
|
134
|
+
else
|
|
135
|
+
non_oauth_parameters
|
|
136
|
+
end
|
|
137
137
|
|
|
138
138
|
[uri, normalize(params)].join("?")
|
|
139
139
|
else
|
|
140
|
-
warn
|
|
140
|
+
warn("This request has not yet been signed!")
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
143
|
|
|
@@ -177,6 +177,17 @@ module OAuth
|
|
|
177
177
|
|
|
178
178
|
{}
|
|
179
179
|
end
|
|
180
|
+
|
|
181
|
+
# Utility to make parameter values array-style (or keep nil) so that
|
|
182
|
+
# subclasses can rely on array values for parameter merging/signing.
|
|
183
|
+
# Mirrors the implementation previously present in
|
|
184
|
+
# ActionDispatchRequest#wrap_values.
|
|
185
|
+
def wrap_values(hash)
|
|
186
|
+
return {} unless hash
|
|
187
|
+
hash.each_with_object({}) do |(k, v), acc|
|
|
188
|
+
acc[k] = (v.is_a?(Array) || v.nil?) ? v : [v]
|
|
189
|
+
end
|
|
190
|
+
end
|
|
180
191
|
end
|
|
181
192
|
end
|
|
182
193
|
end
|
|
@@ -1,74 +1,75 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "oauth/request_proxy/base"
|
|
4
|
-
|
|
5
|
-
require "em-http"
|
|
4
|
+
require "oauth/optional"
|
|
6
5
|
require "cgi"
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
module
|
|
10
|
-
module
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
if OAuth::Optional.em_http_available?
|
|
8
|
+
module OAuth
|
|
9
|
+
module RequestProxy
|
|
10
|
+
module EventMachine
|
|
11
|
+
class HttpRequest < OAuth::RequestProxy::Base
|
|
12
|
+
# A Proxy for use when you need to sign EventMachine::HttpClient instances.
|
|
13
|
+
# It needs to be called once the client is construct but before data is sent.
|
|
14
|
+
# Also see oauth/client/em-http
|
|
15
|
+
proxies ::EventMachine::HttpClient
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
# Request in this con
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
def method
|
|
20
|
+
request.req[:method]
|
|
21
|
+
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
def uri
|
|
24
|
+
request.conn.normalize.to_s
|
|
25
|
+
end
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
def parameters
|
|
28
|
+
if options[:clobber_request]
|
|
29
|
+
options[:parameters]
|
|
30
|
+
else
|
|
31
|
+
all_parameters
|
|
32
|
+
end
|
|
32
33
|
end
|
|
33
|
-
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
protected
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
def all_parameters
|
|
38
|
+
merged_parameters({}, post_parameters, query_parameters, options[:parameters])
|
|
39
|
+
end
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
def query_parameters
|
|
42
|
+
quer = request.req[:query]
|
|
43
|
+
hash_quer = if quer.respond_to?(:merge)
|
|
44
|
+
quer
|
|
45
|
+
else
|
|
46
|
+
CGI.parse(quer.to_s)
|
|
47
|
+
end
|
|
48
|
+
CGI.parse(request.conn.query.to_s).merge(hash_quer)
|
|
49
|
+
end
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
def post_parameters
|
|
52
|
+
headers = request.req[:head] || {}
|
|
53
|
+
form_encoded = headers["Content-Type"].to_s.downcase.start_with?("application/x-www-form-urlencoded")
|
|
54
|
+
if %w[POST PUT].include?(method) && form_encoded
|
|
55
|
+
CGI.parse(request.normalize_body(request.req[:body]).to_s)
|
|
56
|
+
else
|
|
57
|
+
{}
|
|
58
|
+
end
|
|
58
59
|
end
|
|
59
|
-
end
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
def merged_parameters(params, *extra_params)
|
|
62
|
+
extra_params.compact.each do |params_pairs|
|
|
63
|
+
params_pairs.each_pair do |key, value|
|
|
64
|
+
if params.key?(key)
|
|
65
|
+
params[key.to_s] += value
|
|
66
|
+
else
|
|
67
|
+
params[key.to_s] = [value].flatten
|
|
68
|
+
end
|
|
68
69
|
end
|
|
69
70
|
end
|
|
71
|
+
params
|
|
70
72
|
end
|
|
71
|
-
params
|
|
72
73
|
end
|
|
73
74
|
end
|
|
74
75
|
end
|
|
@@ -18,8 +18,15 @@ module OAuth
|
|
|
18
18
|
oauth = @request.get_elements("//oauth").first
|
|
19
19
|
return @params unless oauth
|
|
20
20
|
|
|
21
|
-
%w[
|
|
22
|
-
|
|
21
|
+
%w[
|
|
22
|
+
oauth_token
|
|
23
|
+
oauth_consumer_key
|
|
24
|
+
oauth_signature_method
|
|
25
|
+
oauth_signature
|
|
26
|
+
oauth_timestamp
|
|
27
|
+
oauth_nonce
|
|
28
|
+
oauth_version
|
|
29
|
+
].each do |param|
|
|
23
30
|
next unless (element = oauth.first_element(param))
|
|
24
31
|
|
|
25
32
|
@params[param] = element.text
|
|
@@ -69,7 +69,7 @@ module OAuth
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def auth_header_params
|
|
72
|
-
return
|
|
72
|
+
return unless request["Authorization"] && request["Authorization"][0, 5] == "OAuth"
|
|
73
73
|
|
|
74
74
|
request["Authorization"]
|
|
75
75
|
end
|
|
@@ -34,7 +34,8 @@ module OAuth
|
|
|
34
34
|
query ? CGI.parse(query) : {}
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def request_params
|
|
37
|
+
def request_params
|
|
38
|
+
end
|
|
38
39
|
|
|
39
40
|
def post_parameters
|
|
40
41
|
# Post params are only used if posting form data
|
|
@@ -52,9 +53,9 @@ module OAuth
|
|
|
52
53
|
query.split("&").inject({}) do |result, q|
|
|
53
54
|
k, v = q.split("=")
|
|
54
55
|
if !v.nil?
|
|
55
|
-
result.merge({
|
|
56
|
+
result.merge({k => v})
|
|
56
57
|
elsif !result.key?(k)
|
|
57
|
-
result.merge({
|
|
58
|
+
result.merge({k => true})
|
|
58
59
|
else
|
|
59
60
|
result
|
|
60
61
|
end
|
data/lib/oauth/request_proxy.rb
CHANGED
|
@@ -2,24 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
module OAuth
|
|
4
4
|
module RequestProxy
|
|
5
|
-
|
|
6
|
-
@available_proxies ||= {}
|
|
7
|
-
end
|
|
5
|
+
AVAILABLE_PROXIES = {}
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
class << self
|
|
8
|
+
def available_proxies # :nodoc:
|
|
9
|
+
AVAILABLE_PROXIES
|
|
10
|
+
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
def proxy(request, options = {})
|
|
13
|
+
return request if request.is_a?(OAuth::RequestProxy::Base)
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
if klass.nil?
|
|
16
|
-
request_parent = available_proxies.keys.find { |rc| request.is_a?(rc) }
|
|
17
|
-
klass = available_proxies[request_parent]
|
|
18
|
-
end
|
|
15
|
+
klass = available_proxies[request.class]
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
# Search for possible superclass matches.
|
|
18
|
+
if klass.nil?
|
|
19
|
+
request_parent = available_proxies.keys.find { |rc| request.is_a?(rc) }
|
|
20
|
+
klass = available_proxies[request_parent]
|
|
21
|
+
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
raise UnknownRequestType, request.class.to_s unless klass
|
|
24
|
+
|
|
25
|
+
klass.new(request, options)
|
|
26
|
+
end
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
class UnknownRequestType < RuntimeError; end
|
data/lib/oauth/server.rb
CHANGED
|
@@ -7,12 +7,13 @@ module OAuth
|
|
|
7
7
|
# This is mainly used to create consumer credentials and can pretty much be ignored if you want to create your own
|
|
8
8
|
class Server
|
|
9
9
|
include OAuth::Helper
|
|
10
|
+
|
|
10
11
|
attr_accessor :base_url
|
|
11
12
|
|
|
12
13
|
@@server_paths = {
|
|
13
14
|
request_token_path: "/oauth/request_token",
|
|
14
15
|
authorize_path: "/oauth/authorize",
|
|
15
|
-
access_token_path: "/oauth/access_token"
|
|
16
|
+
access_token_path: "/oauth/access_token",
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
# Create a new server instance
|
|
@@ -32,13 +33,16 @@ module OAuth
|
|
|
32
33
|
# mainly for testing purposes
|
|
33
34
|
def create_consumer
|
|
34
35
|
creds = generate_credentials
|
|
35
|
-
Consumer.new(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
Consumer.new(
|
|
37
|
+
creds[0],
|
|
38
|
+
creds[1],
|
|
39
|
+
{
|
|
40
|
+
site: base_url,
|
|
41
|
+
request_token_path: request_token_path,
|
|
42
|
+
authorize_path: authorize_path,
|
|
43
|
+
access_token_path: access_token_path,
|
|
44
|
+
},
|
|
45
|
+
)
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def request_token_path
|
data/lib/oauth/signature/base.rb
CHANGED
|
@@ -7,17 +7,27 @@ require "base64"
|
|
|
7
7
|
|
|
8
8
|
module OAuth
|
|
9
9
|
module Signature
|
|
10
|
+
# Base class for OAuth signature implementations.
|
|
11
|
+
#
|
|
12
|
+
# Includes {OAuth::AUTH_SANITIZER::FilteredAttributes} so inspect output redacts
|
|
13
|
+
# secret-bearing fields captured during signature construction.
|
|
10
14
|
class Base
|
|
11
15
|
include OAuth::Helper
|
|
16
|
+
include OAuth::AUTH_SANITIZER::FilteredAttributes
|
|
12
17
|
|
|
18
|
+
# Signature construction options.
|
|
19
|
+
#
|
|
20
|
+
# @return [Hash]
|
|
13
21
|
attr_accessor :options
|
|
14
22
|
attr_reader :token_secret, :consumer_secret, :request
|
|
23
|
+
filtered_attributes :options, :consumer_secret, :token_secret
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
class << self
|
|
26
|
+
def implements(signature_method = nil)
|
|
27
|
+
return OAuth::Signature.available_methods.key(self) if signature_method.nil?
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
29
|
+
OAuth::Signature.available_methods[signature_method] = self
|
|
30
|
+
end
|
|
21
31
|
end
|
|
22
32
|
|
|
23
33
|
def initialize(request, options = {}, &block)
|
|
@@ -43,7 +53,7 @@ module OAuth
|
|
|
43
53
|
# override secrets based on the values returned from the block (if any)
|
|
44
54
|
if block
|
|
45
55
|
# consumer secret and token secret need to be looked up based on pieces of the request
|
|
46
|
-
secrets = yield block.arity == 1 ? request : [token, consumer_key, nonce, request.timestamp]
|
|
56
|
+
secrets = yield (block.arity == 1) ? request : [token, consumer_key, nonce, request.timestamp]
|
|
47
57
|
if secrets.is_a?(Array) && secrets.size == 2
|
|
48
58
|
@token_secret = secrets[0]
|
|
49
59
|
@consumer_secret = secrets[1]
|
|
@@ -9,8 +9,8 @@ module OAuth
|
|
|
9
9
|
implements "rsa-sha1"
|
|
10
10
|
|
|
11
11
|
def ==(other)
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
decoded = Base64.decode64(other.is_a?(Array) ? other.first : other)
|
|
13
|
+
public_key.verify(OpenSSL::Digest.new("SHA1"), decoded, signature_base_string)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def public_key
|
|
@@ -25,7 +25,14 @@ module OAuth
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def body_hash
|
|
28
|
-
|
|
28
|
+
# Use SHA1 body hash with compatibility across OpenSSL versions
|
|
29
|
+
data = request.body || ""
|
|
30
|
+
begin
|
|
31
|
+
digest_bytes = OpenSSL::Digest.digest("SHA1", data)
|
|
32
|
+
rescue StandardError
|
|
33
|
+
digest_bytes = ::Digest::SHA1.digest(data)
|
|
34
|
+
end
|
|
35
|
+
Base64.encode64(digest_bytes).chomp.delete("\n")
|
|
29
36
|
end
|
|
30
37
|
|
|
31
38
|
private
|
|
@@ -47,7 +54,7 @@ module OAuth
|
|
|
47
54
|
options[:private_key]
|
|
48
55
|
else
|
|
49
56
|
consumer_secret
|
|
50
|
-
end
|
|
57
|
+
end,
|
|
51
58
|
)
|
|
52
59
|
|
|
53
60
|
private_key.sign(OpenSSL::Digest.new("SHA1"), signature_base_string)
|
data/lib/oauth/signature.rb
CHANGED
|
@@ -2,45 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
module OAuth
|
|
4
4
|
module Signature
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
5
|
+
AVAILABLE_METHODS = {}
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
# Returns a list of available signature methods
|
|
9
|
+
def available_methods
|
|
10
|
+
AVAILABLE_METHODS
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Build a signature from a +request+.
|
|
14
|
+
#
|
|
15
|
+
# Raises UnknownSignatureMethod exception if the signature method is unknown.
|
|
16
|
+
def build(request, options = {}, &block)
|
|
17
|
+
request = OAuth::RequestProxy.proxy(request, options)
|
|
18
|
+
klass = available_methods[
|
|
19
|
+
(request.signature_method ||
|
|
20
|
+
((c = request.options[:consumer]) && c.options[:signature_method]) ||
|
|
21
|
+
"").downcase]
|
|
22
|
+
raise UnknownSignatureMethod, request.signature_method unless klass
|
|
23
|
+
|
|
24
|
+
klass.new(request, options, &block)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Sign a +request+
|
|
28
|
+
def sign(request, options = {}, &block)
|
|
29
|
+
build(request, options, &block).signature
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Verify the signature of +request+
|
|
33
|
+
def verify(request, options = {}, &block)
|
|
34
|
+
build(request, options, &block).verify
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Create the signature base string for +request+. This string is the normalized parameter information.
|
|
38
|
+
#
|
|
39
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
|
40
|
+
def signature_base_string(request, options = {}, &block)
|
|
41
|
+
build(request, options, &block).signature_base_string
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Create the body hash for a request
|
|
45
|
+
def body_hash(request, options = {}, &block)
|
|
46
|
+
build(request, options, &block).body_hash
|
|
47
|
+
end
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
class UnknownSignatureMethod < RuntimeError; end
|
|
@@ -8,7 +8,7 @@ module OAuth
|
|
|
8
8
|
def request(http_method, path, *arguments)
|
|
9
9
|
request_uri = URI.parse(path)
|
|
10
10
|
site_uri = consumer.uri
|
|
11
|
-
is_service_uri_different =
|
|
11
|
+
is_service_uri_different = request_uri.absolute? && request_uri != site_uri
|
|
12
12
|
begin
|
|
13
13
|
consumer.uri(request_uri) if is_service_uri_different
|
|
14
14
|
@response = super(http_method, path, *arguments)
|
|
@@ -4,18 +4,20 @@ module OAuth
|
|
|
4
4
|
# Superclass for tokens used by OAuth Clients
|
|
5
5
|
class ConsumerToken < Token
|
|
6
6
|
attr_accessor :consumer, :params
|
|
7
|
-
attr_reader
|
|
7
|
+
attr_reader :response
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
class << self
|
|
10
|
+
def from_hash(consumer, hash)
|
|
11
|
+
token = new(consumer, hash[:oauth_token], hash[:oauth_token_secret])
|
|
12
|
+
token.params = hash
|
|
13
|
+
token
|
|
14
|
+
end
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def initialize(consumer, token = "", secret = "")
|
|
16
18
|
super(token, secret)
|
|
17
19
|
@consumer = consumer
|
|
18
|
-
@params
|
|
20
|
+
@params = {}
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
# Make a signed request using given http_method to the path
|
|
@@ -6,14 +6,14 @@ module OAuth
|
|
|
6
6
|
class RequestToken < ConsumerToken
|
|
7
7
|
# Generate an authorization URL for user authorization
|
|
8
8
|
def authorize_url(params = nil)
|
|
9
|
-
return
|
|
9
|
+
return if token.nil?
|
|
10
10
|
|
|
11
11
|
params = (params || {}).merge(oauth_token: token)
|
|
12
12
|
build_url(consumer.authorize_url, params)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def authenticate_url(params = nil)
|
|
16
|
-
return
|
|
16
|
+
return if token.nil?
|
|
17
17
|
|
|
18
18
|
params = (params || {}).merge(oauth_token: token)
|
|
19
19
|
build_url(consumer.authenticate_url, params)
|
|
@@ -25,8 +25,13 @@ module OAuth
|
|
|
25
25
|
|
|
26
26
|
# exchange for AccessToken on server
|
|
27
27
|
def get_access_token(options = {}, *arguments)
|
|
28
|
-
response = consumer.token_request(
|
|
29
|
-
|
|
28
|
+
response = consumer.token_request(
|
|
29
|
+
consumer.http_method,
|
|
30
|
+
(consumer.access_token_url? ? consumer.access_token_url : consumer.access_token_path),
|
|
31
|
+
self,
|
|
32
|
+
options,
|
|
33
|
+
*arguments,
|
|
34
|
+
)
|
|
30
35
|
OAuth::AccessToken.from_hash(consumer, response)
|
|
31
36
|
end
|
|
32
37
|
|