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
@@ -1,207 +1,213 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OAuth
|
4
|
+
class CLI
|
5
|
+
class BaseCommand
|
6
|
+
def initialize(stdout, stdin, stderr, arguments)
|
7
|
+
@stdout = stdout
|
8
|
+
@stdin = stdin
|
9
|
+
@stderr = stderr
|
10
|
+
|
11
|
+
@options = {}
|
12
|
+
option_parser.parse!(arguments)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
missing = required_options - options.keys
|
17
|
+
if missing.empty?
|
18
|
+
_run
|
19
|
+
else
|
20
|
+
show_missing(missing)
|
21
|
+
puts option_parser.help
|
22
|
+
end
|
17
23
|
end
|
18
|
-
end
|
19
24
|
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
def required_options
|
26
|
+
[]
|
27
|
+
end
|
23
28
|
|
24
|
-
|
29
|
+
protected
|
25
30
|
|
26
|
-
|
31
|
+
attr_reader :options
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
def show_missing(array)
|
34
|
+
array = array.map { |s| "--#{s}" }.join(" ")
|
35
|
+
OAuth::CLI.puts_red "Options missing to OAuth CLI: #{array}"
|
36
|
+
end
|
32
37
|
|
33
|
-
|
34
|
-
|
35
|
-
|
38
|
+
def xmpp?
|
39
|
+
options[:xmpp]
|
40
|
+
end
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
def verbose?
|
43
|
+
options[:verbose]
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
def puts(string = nil)
|
47
|
+
@stdout.puts(string)
|
48
|
+
end
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
def alert(string = nil)
|
51
|
+
@stderr.puts(string)
|
52
|
+
end
|
48
53
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
def parameters
|
55
|
+
@parameters ||= begin
|
56
|
+
escaped_pairs = options[:params].collect do |pair|
|
57
|
+
if /:/.match?(pair)
|
58
|
+
Hash[*pair.split(":", 2)].collect do |k, v|
|
59
|
+
[CGI.escape(k.strip), CGI.escape(v.strip)].join("=")
|
60
|
+
end
|
61
|
+
else
|
62
|
+
pair
|
55
63
|
end
|
56
|
-
else
|
57
|
-
pair
|
58
64
|
end
|
59
|
-
end
|
60
|
-
|
61
|
-
querystring = escaped_pairs * "&"
|
62
|
-
cli_params = CGI.parse(querystring)
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
querystring = escaped_pairs * "&"
|
67
|
+
cli_params = CGI.parse(querystring)
|
68
|
+
|
69
|
+
{
|
70
|
+
"oauth_consumer_key" => options[:oauth_consumer_key],
|
71
|
+
"oauth_nonce" => options[:oauth_nonce],
|
72
|
+
"oauth_timestamp" => options[:oauth_timestamp],
|
73
|
+
"oauth_token" => options[:oauth_token],
|
74
|
+
"oauth_signature_method" => options[:oauth_signature_method],
|
75
|
+
"oauth_version" => options[:oauth_version]
|
76
|
+
}.reject { |_k, v| v.nil? || v == "" }.merge(cli_params)
|
77
|
+
end
|
72
78
|
end
|
73
|
-
end
|
74
79
|
|
75
|
-
|
76
|
-
|
77
|
-
|
80
|
+
def option_parser
|
81
|
+
@option_parser ||= OptionParser.new do |opts|
|
82
|
+
opts.banner = "Usage: oauth <command> [ARGS]"
|
78
83
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
84
|
+
_option_parser_defaults
|
85
|
+
_option_parser_common(opts)
|
86
|
+
_option_parser_sign_and_query(opts)
|
87
|
+
_option_parser_authorization(opts)
|
88
|
+
end
|
83
89
|
end
|
84
|
-
end
|
85
90
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
def _option_parser_defaults
|
92
|
+
options[:oauth_nonce] = OAuth::Helper.generate_key
|
93
|
+
options[:oauth_signature_method] = "HMAC-SHA1"
|
94
|
+
options[:oauth_timestamp] = OAuth::Helper.generate_timestamp
|
95
|
+
options[:oauth_version] = "1.0"
|
96
|
+
options[:method] = :post
|
97
|
+
options[:params] = []
|
98
|
+
options[:scheme] = :header
|
99
|
+
options[:version] = "1.0"
|
100
|
+
end
|
96
101
|
|
97
|
-
|
98
|
-
|
102
|
+
def _option_parser_common(opts)
|
103
|
+
## Common Options
|
99
104
|
|
100
|
-
|
101
|
-
|
102
|
-
|
105
|
+
opts.on("-B", "--body", "Use the request body for OAuth parameters.") do
|
106
|
+
options[:scheme] = :body
|
107
|
+
end
|
103
108
|
|
104
|
-
|
105
|
-
|
106
|
-
|
109
|
+
opts.on("--consumer-key KEY", "Specifies the consumer key to use.") do |v|
|
110
|
+
options[:oauth_consumer_key] = v
|
111
|
+
end
|
107
112
|
|
108
|
-
|
109
|
-
|
110
|
-
|
113
|
+
opts.on("--consumer-secret SECRET", "Specifies the consumer secret to use.") do |v|
|
114
|
+
options[:oauth_consumer_secret] = v
|
115
|
+
end
|
111
116
|
|
112
|
-
|
113
|
-
|
114
|
-
|
117
|
+
opts.on("-H", "--header", "Use the 'Authorization' header for OAuth parameters (default).") do
|
118
|
+
options[:scheme] = :header
|
119
|
+
end
|
115
120
|
|
116
|
-
|
117
|
-
|
118
|
-
|
121
|
+
opts.on("-Q", "--query-string", "Use the query string for OAuth parameters.") do
|
122
|
+
options[:scheme] = :query_string
|
123
|
+
end
|
119
124
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
125
|
+
opts.on("-O", "--options FILE", "Read options from a file") do |v|
|
126
|
+
arguments = open(v).readlines.map { |l| l.chomp.split }.flatten
|
127
|
+
options2 = parse_options(arguments)
|
128
|
+
options.merge!(options2)
|
129
|
+
end
|
124
130
|
end
|
125
|
-
end
|
126
131
|
|
127
|
-
|
128
|
-
|
132
|
+
def _option_parser_sign_and_query(opts)
|
133
|
+
opts.separator("\n options for signing and querying")
|
129
134
|
|
130
|
-
|
131
|
-
|
132
|
-
|
135
|
+
opts.on("--method METHOD", "Specifies the method (e.g. GET) to use when signing.") do |v|
|
136
|
+
options[:method] = v
|
137
|
+
end
|
133
138
|
|
134
|
-
|
135
|
-
|
136
|
-
|
139
|
+
opts.on("--nonce NONCE", "Specifies the nonce to use.") do |v|
|
140
|
+
options[:oauth_nonce] = v
|
141
|
+
end
|
137
142
|
|
138
|
-
|
139
|
-
|
140
|
-
|
143
|
+
opts.on("--parameters PARAMS", "Specifies the parameters to use when signing.") do |v|
|
144
|
+
options[:params] << v
|
145
|
+
end
|
141
146
|
|
142
|
-
|
143
|
-
|
144
|
-
|
147
|
+
opts.on("--signature-method METHOD", "Specifies the signature method to use; defaults to HMAC-SHA1.") do |v|
|
148
|
+
options[:oauth_signature_method] = v
|
149
|
+
end
|
145
150
|
|
146
|
-
|
147
|
-
|
148
|
-
|
151
|
+
opts.on("--token TOKEN", "Specifies the token to use.") do |v|
|
152
|
+
options[:oauth_token] = v
|
153
|
+
end
|
149
154
|
|
150
|
-
|
151
|
-
|
152
|
-
|
155
|
+
opts.on("--secret SECRET", "Specifies the token secret to use.") do |v|
|
156
|
+
options[:oauth_token_secret] = v
|
157
|
+
end
|
153
158
|
|
154
|
-
|
155
|
-
|
156
|
-
|
159
|
+
opts.on("--timestamp TIMESTAMP", "Specifies the timestamp to use.") do |v|
|
160
|
+
options[:oauth_timestamp] = v
|
161
|
+
end
|
157
162
|
|
158
|
-
|
159
|
-
|
160
|
-
|
163
|
+
opts.on("--realm REALM", "Specifies the realm to use.") do |v|
|
164
|
+
options[:realm] = v
|
165
|
+
end
|
161
166
|
|
162
|
-
|
163
|
-
|
164
|
-
|
167
|
+
opts.on("--uri URI", "Specifies the URI to use when signing.") do |v|
|
168
|
+
options[:uri] = v
|
169
|
+
end
|
165
170
|
|
166
|
-
|
167
|
-
|
168
|
-
|
171
|
+
opts.on("--version [VERSION]", "Specifies the OAuth version to use.") do |v|
|
172
|
+
options[:oauth_version] = v
|
173
|
+
end
|
169
174
|
|
170
|
-
|
171
|
-
|
172
|
-
|
175
|
+
opts.on("--no-version", "Omit oauth_version.") do
|
176
|
+
options[:oauth_version] = nil
|
177
|
+
end
|
173
178
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
179
|
+
opts.on("--xmpp", "Generate XMPP stanzas.") do
|
180
|
+
options[:xmpp] = true
|
181
|
+
options[:method] ||= "iq"
|
182
|
+
end
|
178
183
|
|
179
|
-
|
180
|
-
|
184
|
+
opts.on("-v", "--verbose", "Be verbose.") do
|
185
|
+
options[:verbose] = true
|
186
|
+
end
|
181
187
|
end
|
182
|
-
end
|
183
188
|
|
184
|
-
|
185
|
-
|
189
|
+
def _option_parser_authorization(opts)
|
190
|
+
opts.separator("\n options for authorization")
|
186
191
|
|
187
|
-
|
188
|
-
|
189
|
-
|
192
|
+
opts.on("--access-token-url URL", "Specifies the access token URL.") do |v|
|
193
|
+
options[:access_token_url] = v
|
194
|
+
end
|
190
195
|
|
191
|
-
|
192
|
-
|
193
|
-
|
196
|
+
opts.on("--authorize-url URL", "Specifies the authorization URL.") do |v|
|
197
|
+
options[:authorize_url] = v
|
198
|
+
end
|
194
199
|
|
195
|
-
|
196
|
-
|
197
|
-
|
200
|
+
opts.on("--callback-url URL", "Specifies a callback URL.") do |v|
|
201
|
+
options[:oauth_callback] = v
|
202
|
+
end
|
198
203
|
|
199
|
-
|
200
|
-
|
201
|
-
|
204
|
+
opts.on("--request-token-url URL", "Specifies the request token URL.") do |v|
|
205
|
+
options[:request_token_url] = v
|
206
|
+
end
|
202
207
|
|
203
|
-
|
204
|
-
|
208
|
+
opts.on("--scope SCOPE", "Specifies the scope (Google-specific).") do |v|
|
209
|
+
options[:scope] = v
|
210
|
+
end
|
205
211
|
end
|
206
212
|
end
|
207
213
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OAuth
|
4
|
+
class CLI
|
5
|
+
class HelpCommand < BaseCommand
|
6
|
+
def run
|
7
|
+
puts <<-EOT
|
5
8
|
Usage: oauth COMMAND [ARGS]
|
6
9
|
|
7
10
|
Available oauth commands are:
|
@@ -16,7 +19,8 @@ class OAuth::CLI
|
|
16
19
|
Tip: All commands can be run without args for specific help.
|
17
20
|
|
18
21
|
|
19
|
-
|
22
|
+
EOT
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
end
|
@@ -1,25 +1,34 @@
|
|
1
|
-
|
2
|
-
class QueryCommand < BaseCommand
|
3
|
-
extend OAuth::Helper
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module OAuth
|
4
|
+
class CLI
|
5
|
+
class QueryCommand < BaseCommand
|
6
|
+
extend OAuth::Helper
|
7
|
+
|
8
|
+
def required_options
|
9
|
+
%i[oauth_consumer_key oauth_consumer_secret oauth_token oauth_token_secret]
|
10
|
+
end
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
def _run
|
13
|
+
consumer = OAuth::Consumer.new(options[:oauth_consumer_key], options[:oauth_consumer_secret],
|
14
|
+
scheme: options[:scheme])
|
11
15
|
|
12
|
-
|
16
|
+
access_token = OAuth::AccessToken.new(consumer, options[:oauth_token], options[:oauth_token_secret])
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
# append params to the URL
|
19
|
+
uri = URI.parse(options[:uri])
|
20
|
+
params = parameters.map do |k, v|
|
21
|
+
Array(v).map do |v2|
|
22
|
+
"#{OAuth::Helper.escape(k)}=#{OAuth::Helper.escape(v2)}"
|
23
|
+
end * "&"
|
24
|
+
end
|
25
|
+
uri.query = [uri.query, *params].compact * "&"
|
26
|
+
puts uri.to_s
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
28
|
+
response = access_token.request(options[:method].to_s.downcase.to_sym, uri.to_s)
|
29
|
+
puts "#{response.code} #{response.message}"
|
30
|
+
puts response.body
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
25
34
|
end
|
@@ -1,71 +1,73 @@
|
|
1
|
-
|
2
|
-
class SignCommand < BaseCommand
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
request = OAuth::RequestProxy.proxy \
|
10
|
-
"method" => options[:method],
|
11
|
-
"uri" => options[:uri],
|
12
|
-
"parameters" => parameters
|
13
|
-
|
14
|
-
if verbose?
|
15
|
-
puts_verbose_parameters(request)
|
3
|
+
module OAuth
|
4
|
+
class CLI
|
5
|
+
class SignCommand < BaseCommand
|
6
|
+
def required_options
|
7
|
+
%i[oauth_consumer_key oauth_consumer_secret oauth_token oauth_token_secret]
|
16
8
|
end
|
17
9
|
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
def _run
|
11
|
+
request = OAuth::RequestProxy.proxy \
|
12
|
+
"method" => options[:method],
|
13
|
+
"uri" => options[:uri],
|
14
|
+
"parameters" => parameters
|
21
15
|
|
22
|
-
|
23
|
-
puts_verbose_request(request)
|
24
|
-
else
|
25
|
-
puts request.oauth_signature
|
26
|
-
end
|
27
|
-
end
|
16
|
+
puts_verbose_parameters(request) if verbose?
|
28
17
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
18
|
+
request.sign! \
|
19
|
+
consumer_secret: options[:oauth_consumer_secret],
|
20
|
+
token_secret: options[:oauth_token_secret]
|
21
|
+
|
22
|
+
if verbose?
|
23
|
+
puts_verbose_request(request)
|
24
|
+
else
|
25
|
+
puts request.oauth_signature
|
26
|
+
end
|
33
27
|
end
|
34
|
-
puts
|
35
28
|
|
36
|
-
|
37
|
-
puts "
|
38
|
-
request.
|
39
|
-
puts "
|
29
|
+
def puts_verbose_parameters(request)
|
30
|
+
puts "OAuth parameters:"
|
31
|
+
request.oauth_parameters.each do |k, v|
|
32
|
+
puts " #{[k, v].join(": ")}"
|
40
33
|
end
|
41
34
|
puts
|
35
|
+
|
36
|
+
if request.non_oauth_parameters.any?
|
37
|
+
puts "Parameters:"
|
38
|
+
request.non_oauth_parameters.each do |k, v|
|
39
|
+
puts " #{[k, v].join(": ")}"
|
40
|
+
end
|
41
|
+
puts
|
42
|
+
end
|
42
43
|
end
|
43
|
-
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def puts_verbose_request(request)
|
46
|
+
puts "Method: #{request.method}"
|
47
|
+
puts "URI: #{request.uri}"
|
48
|
+
unless options[:xmpp]
|
49
|
+
puts "Normalized params: #{request.normalized_parameters}"
|
50
|
+
end
|
51
|
+
puts "Signature base string: #{request.signature_base_string}"
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
if xmpp?
|
54
|
+
puts
|
55
|
+
puts "XMPP Stanza:"
|
56
|
+
puts xmpp_output(request)
|
57
|
+
puts
|
58
|
+
puts "Note: You may want to use bare JIDs in your URI."
|
59
|
+
puts
|
60
|
+
else
|
61
|
+
puts "OAuth Request URI: #{request.signed_uri}"
|
62
|
+
puts "Request URI: #{request.signed_uri(with_oauth: false)}"
|
63
|
+
puts "Authorization header: #{request.oauth_header(realm: options[:realm])}"
|
64
|
+
end
|
65
|
+
puts "Signature: #{request.oauth_signature}"
|
66
|
+
puts "Escaped signature: #{OAuth::Helper.escape(request.oauth_signature)}"
|
62
67
|
end
|
63
|
-
puts "Signature: #{request.oauth_signature}"
|
64
|
-
puts "Escaped signature: #{OAuth::Helper.escape(request.oauth_signature)}"
|
65
|
-
end
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
+
def xmpp_output(request)
|
70
|
+
<<-EOS
|
69
71
|
<oauth xmlns='urn:xmpp:oauth:0'>
|
70
72
|
<oauth_consumer_key>#{request.oauth_consumer_key}</oauth_consumer_key>
|
71
73
|
<oauth_token>#{request.oauth_token}</oauth_token>
|
@@ -75,7 +77,8 @@ class OAuth::CLI
|
|
75
77
|
<oauth_nonce>#{request.oauth_nonce}</oauth_nonce>
|
76
78
|
<oauth_version>#{request.oauth_version}</oauth_version>
|
77
79
|
</oauth>
|
78
|
-
|
80
|
+
EOS
|
81
|
+
end
|
79
82
|
end
|
80
83
|
end
|
81
84
|
end
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OAuth
|
4
|
+
class CLI
|
5
|
+
class VersionCommand < BaseCommand
|
6
|
+
def run
|
7
|
+
puts "OAuth Gem #{OAuth::Version::VERSION}"
|
8
|
+
end
|
5
9
|
end
|
6
10
|
end
|
7
11
|
end
|