oauth 0.5.6 → 0.6.2
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
- data/CHANGELOG.md +478 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/CONTRIBUTING.md +23 -0
- data/LICENSE +18 -17
- data/README.md +383 -0
- data/SECURITY.md +20 -0
- data/bin/oauth +10 -6
- data/lib/oauth/cli/authorize_command.rb +57 -55
- data/lib/oauth/cli/base_command.rb +163 -157
- data/lib/oauth/cli/help_command.rb +9 -5
- data/lib/oauth/cli/query_command.rb +26 -17
- data/lib/oauth/cli/sign_command.rb +58 -55
- data/lib/oauth/cli/version_command.rb +8 -4
- data/lib/oauth/cli.rb +21 -19
- data/lib/oauth/client/action_controller_request.rb +23 -21
- data/lib/oauth/client/em_http.rb +101 -99
- data/lib/oauth/client/helper.rb +83 -82
- data/lib/oauth/client/net_http.rb +112 -105
- data/lib/oauth/client.rb +2 -0
- data/lib/oauth/consumer.rb +157 -135
- data/lib/oauth/errors/error.rb +2 -0
- data/lib/oauth/errors/problem.rb +3 -0
- data/lib/oauth/errors/unauthorized.rb +7 -1
- data/lib/oauth/errors.rb +5 -3
- data/lib/oauth/helper.rb +26 -18
- data/lib/oauth/oauth.rb +6 -4
- data/lib/oauth/oauth_test_helper.rb +6 -4
- data/lib/oauth/request_proxy/action_controller_request.rb +56 -57
- data/lib/oauth/request_proxy/action_dispatch_request.rb +8 -4
- data/lib/oauth/request_proxy/base.rb +136 -132
- data/lib/oauth/request_proxy/curb_request.rb +49 -43
- data/lib/oauth/request_proxy/em_http_request.rb +59 -49
- data/lib/oauth/request_proxy/jabber_request.rb +12 -9
- data/lib/oauth/request_proxy/mock_request.rb +5 -3
- data/lib/oauth/request_proxy/net_http.rb +63 -54
- data/lib/oauth/request_proxy/rack_request.rb +35 -31
- data/lib/oauth/request_proxy/rest_client_request.rb +54 -50
- data/lib/oauth/request_proxy/typhoeus_request.rb +51 -45
- data/lib/oauth/request_proxy.rb +7 -4
- data/lib/oauth/server.rb +14 -12
- data/lib/oauth/signature/base.rb +80 -71
- data/lib/oauth/signature/hmac/sha1.rb +16 -10
- data/lib/oauth/signature/hmac/sha256.rb +16 -10
- data/lib/oauth/signature/plaintext.rb +18 -20
- data/lib/oauth/signature/rsa/sha1.rb +46 -38
- data/lib/oauth/signature.rb +8 -5
- data/lib/oauth/token.rb +7 -5
- data/lib/oauth/tokens/access_token.rb +5 -3
- data/lib/oauth/tokens/consumer_token.rb +4 -2
- data/lib/oauth/tokens/request_token.rb +12 -10
- data/lib/oauth/tokens/server_token.rb +2 -1
- data/lib/oauth/tokens/token.rb +2 -0
- data/lib/oauth/version.rb +5 -1
- data/lib/oauth.rb +17 -9
- metadata +94 -98
- data/README.rdoc +0 -88
data/lib/oauth/cli.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "oauth/cli/base_command"
|
5
|
+
require "oauth/cli/help_command"
|
6
|
+
require "oauth/cli/query_command"
|
7
|
+
require "oauth/cli/authorize_command"
|
8
|
+
require "oauth/cli/sign_command"
|
9
|
+
require "oauth/cli/version_command"
|
10
|
+
require "active_support/core_ext/string/inflections"
|
9
11
|
|
10
12
|
module OAuth
|
11
13
|
class CLI
|
@@ -14,12 +16,12 @@ module OAuth
|
|
14
16
|
end
|
15
17
|
|
16
18
|
ALIASES = {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
}
|
19
|
+
"h" => "help",
|
20
|
+
"v" => "version",
|
21
|
+
"q" => "query",
|
22
|
+
"a" => "authorize",
|
23
|
+
"s" => "sign"
|
24
|
+
}.freeze
|
23
25
|
|
24
26
|
def initialize(stdout, stdin, stderr, command, arguments)
|
25
27
|
klass = get_command_class(parse_command(command))
|
@@ -39,17 +41,17 @@ module OAuth
|
|
39
41
|
|
40
42
|
def parse_command(command)
|
41
43
|
case command = command.to_s.downcase
|
42
|
-
when
|
43
|
-
|
44
|
-
when
|
45
|
-
|
44
|
+
when "--version", "-v"
|
45
|
+
"version"
|
46
|
+
when "--help", "-h", nil, ""
|
47
|
+
"help"
|
46
48
|
when *ALIASES.keys
|
47
49
|
ALIASES[command]
|
48
50
|
when *ALIASES.values
|
49
51
|
command
|
50
52
|
else
|
51
53
|
OAuth::CLI.puts_red "Command '#{command}' not found"
|
52
|
-
|
54
|
+
"help"
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -1,21 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
if defined? ActionDispatch
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require "oauth/request_proxy/rack_request"
|
5
|
+
require "oauth/request_proxy/action_dispatch_request"
|
6
|
+
require "action_dispatch/testing/test_process"
|
5
7
|
else
|
6
|
-
require
|
7
|
-
require
|
8
|
+
require "oauth/request_proxy/action_controller_request"
|
9
|
+
require "action_controller/test_process"
|
8
10
|
end
|
9
11
|
|
10
12
|
module ActionController
|
11
13
|
class Base
|
12
14
|
if defined? ActionDispatch
|
13
|
-
def process_with_new_base_test(request, response=nil)
|
15
|
+
def process_with_new_base_test(request, response = nil)
|
14
16
|
request.apply_oauth! if request.respond_to?(:apply_oauth!)
|
15
17
|
super(request, response)
|
16
18
|
end
|
17
19
|
else
|
18
|
-
def process_with_oauth(request, response=nil)
|
20
|
+
def process_with_oauth(request, response = nil)
|
19
21
|
request.apply_oauth! if request.respond_to?(:apply_oauth!)
|
20
22
|
process_without_oauth(request, response)
|
21
23
|
end
|
@@ -24,8 +26,8 @@ module ActionController
|
|
24
26
|
end
|
25
27
|
|
26
28
|
class TestRequest
|
27
|
-
|
28
|
-
|
29
|
+
class << self
|
30
|
+
attr_writer :use_oauth
|
29
31
|
end
|
30
32
|
|
31
33
|
def self.use_oauth?
|
@@ -33,33 +35,33 @@ module ActionController
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def configure_oauth(consumer = nil, token = nil, options = {})
|
36
|
-
@oauth_options = { :
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
38
|
+
@oauth_options = { consumer: consumer,
|
39
|
+
token: token,
|
40
|
+
scheme: "header",
|
41
|
+
signature_method: nil,
|
42
|
+
nonce: nil,
|
43
|
+
timestamp: nil }.merge(options)
|
42
44
|
end
|
43
45
|
|
44
46
|
def apply_oauth!
|
45
47
|
return unless ActionController::TestRequest.use_oauth? && @oauth_options
|
46
48
|
|
47
|
-
@oauth_helper = OAuth::Client::Helper.new(self,
|
49
|
+
@oauth_helper = OAuth::Client::Helper.new(self,
|
50
|
+
@oauth_options.merge(request_uri: (respond_to?(:fullpath) ? fullpath : request_uri)))
|
48
51
|
@oauth_helper.amend_user_agent_header(env)
|
49
52
|
|
50
|
-
|
53
|
+
send("set_oauth_#{@oauth_options[:scheme]}")
|
51
54
|
end
|
52
55
|
|
53
56
|
def set_oauth_header
|
54
|
-
env[
|
57
|
+
env["Authorization"] = @oauth_helper.header
|
55
58
|
end
|
56
59
|
|
57
60
|
def set_oauth_parameters
|
58
61
|
@query_parameters = @oauth_helper.parameters_with_oauth
|
59
|
-
@query_parameters.merge!(:
|
62
|
+
@query_parameters.merge!(oauth_signature: @oauth_helper.signature)
|
60
63
|
end
|
61
64
|
|
62
|
-
def set_oauth_query_string
|
63
|
-
end
|
65
|
+
def set_oauth_query_string; end
|
64
66
|
end
|
65
67
|
end
|
data/lib/oauth/client/em_http.rb
CHANGED
@@ -1,119 +1,121 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "em-http"
|
4
|
+
require "oauth/helper"
|
5
|
+
require "oauth/request_proxy/em_http_request"
|
4
6
|
|
5
7
|
# Extensions for em-http so that we can use consumer.sign! with an EventMachine::HttpClient
|
6
8
|
# instance. This is purely syntactic sugar.
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
module EventMachine
|
10
|
+
class HttpClient
|
11
|
+
attr_reader :oauth_helper
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
13
|
+
# Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
|
14
|
+
# this may add a header, additional query string parameters, or additional POST body parameters.
|
15
|
+
# The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
|
16
|
+
# header.
|
17
|
+
#
|
18
|
+
# * http - Configured Net::HTTP instance, ignored in this scenario except for getting host.
|
19
|
+
# * consumer - OAuth::Consumer instance
|
20
|
+
# * token - OAuth::Token instance
|
21
|
+
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
|
22
|
+
# +signature_method+, +nonce+, +timestamp+)
|
23
|
+
#
|
24
|
+
# This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
|
25
|
+
#
|
26
|
+
# See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1]
|
27
|
+
def oauth!(http, consumer = nil, token = nil, options = {})
|
28
|
+
options = { request_uri: normalized_oauth_uri(http),
|
29
|
+
consumer: consumer,
|
30
|
+
token: token,
|
31
|
+
scheme: "header",
|
32
|
+
signature_method: nil,
|
33
|
+
nonce: nil,
|
34
|
+
timestamp: nil }.merge(options)
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
@oauth_helper = OAuth::Client::Helper.new(self, options)
|
37
|
+
__send__(:"set_oauth_#{options[:scheme]}")
|
38
|
+
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
40
|
+
# Create a string suitable for signing for an HTTP request. This process involves parameter
|
41
|
+
# normalization as specified in the OAuth specification. The exact normalization also depends
|
42
|
+
# on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
|
43
|
+
# itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
|
44
|
+
# header.
|
45
|
+
#
|
46
|
+
# * http - Configured Net::HTTP instance
|
47
|
+
# * consumer - OAuth::Consumer instance
|
48
|
+
# * token - OAuth::Token instance
|
49
|
+
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
|
50
|
+
# +signature_method+, +nonce+, +timestamp+)
|
51
|
+
#
|
52
|
+
# See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
|
53
|
+
def signature_base_string(http, consumer = nil, token = nil, options = {})
|
54
|
+
options = { request_uri: normalized_oauth_uri(http),
|
55
|
+
consumer: consumer,
|
56
|
+
token: token,
|
57
|
+
scheme: "header",
|
58
|
+
signature_method: nil,
|
59
|
+
nonce: nil,
|
60
|
+
timestamp: nil }.merge(options)
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
+
OAuth::Client::Helper.new(self, options).signature_base_string
|
63
|
+
end
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
65
|
+
# This code was lifted from the em-http-request because it was removed from
|
66
|
+
# the gem June 19, 2010
|
67
|
+
# see: http://github.com/igrigorik/em-http-request/commit/d536fc17d56dbe55c487eab01e2ff9382a62598b
|
68
|
+
def normalize_uri
|
69
|
+
@normalized_uri ||= begin
|
70
|
+
uri = @conn.dup
|
71
|
+
encoded_query = encode_query(@conn, @req[:query])
|
72
|
+
path, query = encoded_query.split("?", 2)
|
73
|
+
uri.query = query unless encoded_query.empty?
|
74
|
+
uri.path = path
|
75
|
+
uri
|
76
|
+
end
|
74
77
|
end
|
75
|
-
end
|
76
78
|
|
77
|
-
|
79
|
+
protected
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
81
|
+
def combine_query(path, query, uri_query)
|
82
|
+
combined_query = if query.is_a?(Hash)
|
83
|
+
query.map { |k, v| encode_param(k, v) }.join("&")
|
84
|
+
else
|
85
|
+
query.to_s
|
86
|
+
end
|
87
|
+
unless uri_query.to_s.empty?
|
88
|
+
combined_query = [combined_query, uri_query].reject(&:empty?).join("&")
|
89
|
+
end
|
90
|
+
combined_query.to_s.empty? ? path : "#{path}?#{combined_query}"
|
87
91
|
end
|
88
|
-
combined_query.to_s.empty? ? path : "#{path}?#{combined_query}"
|
89
|
-
end
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
93
|
+
# Since we expect to get the host etc details from the http instance (...),
|
94
|
+
# we create a fake url here. Surely this is a horrible, horrible idea?
|
95
|
+
def normalized_oauth_uri(http)
|
96
|
+
uri = URI.parse(normalize_uri.path)
|
97
|
+
uri.host = http.address
|
98
|
+
uri.port = http.port
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
uri.scheme = if http.respond_to?(:use_ssl?) && http.use_ssl?
|
101
|
+
"https"
|
102
|
+
else
|
103
|
+
"http"
|
104
|
+
end
|
105
|
+
uri.to_s
|
102
106
|
end
|
103
|
-
uri.to_s
|
104
|
-
end
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
108
|
+
def set_oauth_header
|
109
|
+
req[:head] ||= {}
|
110
|
+
req[:head].merge!("Authorization" => @oauth_helper.header)
|
111
|
+
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
113
|
+
def set_oauth_body
|
114
|
+
raise NotImplementedError, "please use the set_oauth_header method instead"
|
115
|
+
end
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
+
def set_oauth_query_string
|
118
|
+
raise NotImplementedError, "please use the set_oauth_header method instead"
|
119
|
+
end
|
117
120
|
end
|
118
|
-
|
119
121
|
end
|
data/lib/oauth/client/helper.rb
CHANGED
@@ -1,101 +1,102 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "oauth/client"
|
4
|
+
require "oauth/consumer"
|
5
|
+
require "oauth/helper"
|
6
|
+
require "oauth/token"
|
7
|
+
require "oauth/signature/hmac/sha1"
|
8
|
+
|
9
|
+
module OAuth
|
10
|
+
module Client
|
11
|
+
class Helper
|
12
|
+
include OAuth::Helper
|
13
|
+
|
14
|
+
def initialize(request, options = {})
|
15
|
+
@request = request
|
16
|
+
@options = options
|
17
|
+
@options[:signature_method] ||= "HMAC-SHA1"
|
18
|
+
end
|
16
19
|
|
17
|
-
|
18
|
-
@options
|
19
|
-
end
|
20
|
+
attr_reader :options
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def nonce
|
23
|
+
options[:nonce] ||= generate_key
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
def timestamp
|
27
|
+
options[:timestamp] ||= generate_timestamp
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
def oauth_parameters
|
31
|
+
out = {
|
32
|
+
"oauth_body_hash" => options[:body_hash],
|
33
|
+
"oauth_callback" => options[:oauth_callback],
|
34
|
+
"oauth_consumer_key" => options[:consumer].key,
|
35
|
+
"oauth_token" => options[:token] ? options[:token].token : "",
|
36
|
+
"oauth_signature_method" => options[:signature_method],
|
37
|
+
"oauth_timestamp" => timestamp,
|
38
|
+
"oauth_nonce" => nonce,
|
39
|
+
"oauth_verifier" => options[:oauth_verifier],
|
40
|
+
"oauth_version" => (options[:oauth_version] || "1.0"),
|
41
|
+
"oauth_session_handle" => options[:oauth_session_handle]
|
42
|
+
}
|
43
|
+
allowed_empty_params = options[:allow_empty_params]
|
44
|
+
if allowed_empty_params != true && !allowed_empty_params.is_a?(Array)
|
45
|
+
allowed_empty_params = allowed_empty_params == false ? [] : [allowed_empty_params]
|
46
|
+
end
|
47
|
+
out.select! { |k, v| v.to_s != "" || allowed_empty_params == true || allowed_empty_params.include?(k) }
|
48
|
+
out
|
45
49
|
end
|
46
|
-
out.select! { |k,v| v.to_s != '' || allowed_empty_params == true || allowed_empty_params.include?(k) }
|
47
|
-
out
|
48
|
-
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
51
|
+
def signature(extra_options = {})
|
52
|
+
OAuth::Signature.sign(@request, { uri: options[:request_uri],
|
53
|
+
consumer: options[:consumer],
|
54
|
+
token: options[:token],
|
55
|
+
unsigned_parameters: options[:unsigned_parameters] }.merge(extra_options))
|
56
|
+
end
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
def signature_base_string(extra_options = {})
|
59
|
+
OAuth::Signature.signature_base_string(@request, { uri: options[:request_uri],
|
60
|
+
consumer: options[:consumer],
|
61
|
+
token: options[:token],
|
62
|
+
parameters: oauth_parameters }.merge(extra_options))
|
63
|
+
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
def token_request?
|
66
|
+
@options[:token_request].eql?(true)
|
67
|
+
end
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
def hash_body
|
70
|
+
@options[:body_hash] = OAuth::Signature.body_hash(@request, parameters: oauth_parameters)
|
71
|
+
end
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
def amend_user_agent_header(headers)
|
74
|
+
@oauth_ua_string ||= "OAuth gem v#{OAuth::Version::VERSION}"
|
75
|
+
# Net::HTTP in 1.9 appends Ruby
|
76
|
+
if headers["User-Agent"] && headers["User-Agent"] != "Ruby"
|
77
|
+
headers["User-Agent"] += " (#{@oauth_ua_string})"
|
78
|
+
else
|
79
|
+
headers["User-Agent"] = @oauth_ua_string
|
80
|
+
end
|
80
81
|
end
|
81
|
-
end
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
def header
|
84
|
+
parameters = oauth_parameters
|
85
|
+
parameters["oauth_signature"] = signature(options.merge(parameters: parameters))
|
86
86
|
|
87
|
-
|
87
|
+
header_params_str = parameters.sort.map { |k, v| "#{k}=\"#{escape(v)}\"" }.join(", ")
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
realm = "realm=\"#{options[:realm]}\", " if options[:realm]
|
90
|
+
"OAuth #{realm}#{header_params_str}"
|
91
|
+
end
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
def parameters
|
94
|
+
OAuth::RequestProxy.proxy(@request).parameters
|
95
|
+
end
|
96
96
|
|
97
|
-
|
98
|
-
|
97
|
+
def parameters_with_oauth
|
98
|
+
oauth_parameters.merge(parameters)
|
99
|
+
end
|
99
100
|
end
|
100
101
|
end
|
101
102
|
end
|