oauth 0.5.14 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -3
  3. data/README.md +56 -46
  4. data/SECURITY.md +0 -2
  5. data/bin/oauth +8 -4
  6. data/lib/oauth/cli/authorize_command.rb +58 -54
  7. data/lib/oauth/cli/base_command.rb +163 -159
  8. data/lib/oauth/cli/help_command.rb +9 -5
  9. data/lib/oauth/cli/query_command.rb +26 -17
  10. data/lib/oauth/cli/sign_command.rb +58 -52
  11. data/lib/oauth/cli/version_command.rb +8 -4
  12. data/lib/oauth/cli.rb +2 -0
  13. data/lib/oauth/client/action_controller_request.rb +4 -1
  14. data/lib/oauth/client/em_http.rb +3 -1
  15. data/lib/oauth/client/helper.rb +76 -72
  16. data/lib/oauth/client/net_http.rb +111 -104
  17. data/lib/oauth/client.rb +2 -0
  18. data/lib/oauth/consumer.rb +89 -68
  19. data/lib/oauth/errors/error.rb +2 -0
  20. data/lib/oauth/errors/problem.rb +3 -0
  21. data/lib/oauth/errors/unauthorized.rb +4 -0
  22. data/lib/oauth/errors.rb +2 -0
  23. data/lib/oauth/helper.rb +9 -5
  24. data/lib/oauth/oauth.rb +4 -2
  25. data/lib/oauth/oauth_test_helper.rb +2 -0
  26. data/lib/oauth/request_proxy/base.rb +4 -4
  27. data/lib/oauth/request_proxy/mock_request.rb +1 -1
  28. data/lib/oauth/request_proxy/net_http.rb +8 -8
  29. data/lib/oauth/request_proxy/rest_client_request.rb +4 -3
  30. data/lib/oauth/request_proxy.rb +4 -1
  31. data/lib/oauth/server.rb +8 -4
  32. data/lib/oauth/signature/base.rb +73 -65
  33. data/lib/oauth/signature/hmac/sha1.rb +15 -9
  34. data/lib/oauth/signature/hmac/sha256.rb +15 -9
  35. data/lib/oauth/signature/plaintext.rb +18 -20
  36. data/lib/oauth/signature/rsa/sha1.rb +46 -38
  37. data/lib/oauth/signature.rb +3 -0
  38. data/lib/oauth/token.rb +2 -0
  39. data/lib/oauth/tokens/access_token.rb +2 -0
  40. data/lib/oauth/tokens/consumer_token.rb +2 -0
  41. data/lib/oauth/tokens/request_token.rb +5 -2
  42. data/lib/oauth/tokens/server_token.rb +2 -0
  43. data/lib/oauth/tokens/token.rb +2 -0
  44. data/lib/oauth/version.rb +5 -1
  45. data/lib/oauth.rb +9 -2
  46. metadata +43 -32
@@ -1,98 +1,102 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "oauth/client"
2
4
  require "oauth/consumer"
3
5
  require "oauth/helper"
4
6
  require "oauth/token"
5
7
  require "oauth/signature/hmac/sha1"
6
8
 
7
- module OAuth::Client
8
- class Helper
9
- include OAuth::Helper
9
+ module OAuth
10
+ module Client
11
+ class Helper
12
+ include OAuth::Helper
10
13
 
11
- def initialize(request, options = {})
12
- @request = request
13
- @options = options
14
- @options[:signature_method] ||= "HMAC-SHA1"
15
- end
14
+ def initialize(request, options = {})
15
+ @request = request
16
+ @options = options
17
+ @options[:signature_method] ||= "HMAC-SHA1"
18
+ end
16
19
 
17
- attr_reader :options
20
+ attr_reader :options
18
21
 
19
- def nonce
20
- options[:nonce] ||= generate_key
21
- end
22
+ def nonce
23
+ options[:nonce] ||= generate_key
24
+ end
22
25
 
23
- def timestamp
24
- options[:timestamp] ||= generate_timestamp
25
- end
26
+ def timestamp
27
+ options[:timestamp] ||= generate_timestamp
28
+ end
26
29
 
27
- def oauth_parameters
28
- out = {
29
- "oauth_body_hash" => options[:body_hash],
30
- "oauth_callback" => options[:oauth_callback],
31
- "oauth_consumer_key" => options[:consumer].key,
32
- "oauth_token" => options[:token] ? options[:token].token : "",
33
- "oauth_signature_method" => options[:signature_method],
34
- "oauth_timestamp" => timestamp,
35
- "oauth_nonce" => nonce,
36
- "oauth_verifier" => options[:oauth_verifier],
37
- "oauth_version" => (options[:oauth_version] || "1.0"),
38
- "oauth_session_handle" => options[:oauth_session_handle]
39
- }
40
- allowed_empty_params = options[:allow_empty_params]
41
- if allowed_empty_params != true && !allowed_empty_params.is_a?(Array)
42
- allowed_empty_params = allowed_empty_params == false ? [] : [allowed_empty_params]
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
43
49
  end
44
- out.select! { |k, v| v.to_s != "" || allowed_empty_params == true || allowed_empty_params.include?(k) }
45
- out
46
- end
47
50
 
48
- def signature(extra_options = {})
49
- OAuth::Signature.sign(@request, { uri: options[:request_uri],
50
- consumer: options[:consumer],
51
- token: options[:token],
52
- unsigned_parameters: options[:unsigned_parameters] }.merge(extra_options))
53
- 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
54
57
 
55
- def signature_base_string(extra_options = {})
56
- OAuth::Signature.signature_base_string(@request, { uri: options[:request_uri],
57
- consumer: options[:consumer],
58
- token: options[:token],
59
- parameters: oauth_parameters }.merge(extra_options))
60
- end
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
61
64
 
62
- def token_request?
63
- @options[:token_request].eql?(true)
64
- end
65
+ def token_request?
66
+ @options[:token_request].eql?(true)
67
+ end
65
68
 
66
- def hash_body
67
- @options[:body_hash] = OAuth::Signature.body_hash(@request, parameters: oauth_parameters)
68
- end
69
+ def hash_body
70
+ @options[:body_hash] = OAuth::Signature.body_hash(@request, parameters: oauth_parameters)
71
+ end
69
72
 
70
- def amend_user_agent_header(headers)
71
- @oauth_ua_string ||= "OAuth gem v#{OAuth::VERSION}"
72
- # Net::HTTP in 1.9 appends Ruby
73
- if headers["User-Agent"] && headers["User-Agent"] != "Ruby"
74
- headers["User-Agent"] += " (#{@oauth_ua_string})"
75
- else
76
- headers["User-Agent"] = @oauth_ua_string
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
77
81
  end
78
- end
79
82
 
80
- def header
81
- parameters = oauth_parameters
82
- parameters["oauth_signature"] = signature(options.merge(parameters: parameters))
83
+ def header
84
+ parameters = oauth_parameters
85
+ parameters["oauth_signature"] = signature(options.merge(parameters: parameters))
83
86
 
84
- header_params_str = parameters.sort.map { |k, v| "#{k}=\"#{escape(v)}\"" }.join(", ")
87
+ header_params_str = parameters.sort.map { |k, v| "#{k}=\"#{escape(v)}\"" }.join(", ")
85
88
 
86
- realm = "realm=\"#{options[:realm]}\", " if options[:realm]
87
- "OAuth #{realm}#{header_params_str}"
88
- end
89
+ realm = "realm=\"#{options[:realm]}\", " if options[:realm]
90
+ "OAuth #{realm}#{header_params_str}"
91
+ end
89
92
 
90
- def parameters
91
- OAuth::RequestProxy.proxy(@request).parameters
92
- end
93
+ def parameters
94
+ OAuth::RequestProxy.proxy(@request).parameters
95
+ end
93
96
 
94
- def parameters_with_oauth
95
- oauth_parameters.merge(parameters)
97
+ def parameters_with_oauth
98
+ oauth_parameters.merge(parameters)
99
+ end
96
100
  end
97
101
  end
98
102
  end
@@ -1,121 +1,128 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "oauth/helper"
2
4
  require "oauth/request_proxy/net_http"
3
5
 
4
- class Net::HTTPGenericRequest
5
- include OAuth::Helper
6
-
7
- attr_reader :oauth_helper
8
-
9
- # Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
10
- # this may add a header, additional query string parameters, or additional POST body parameters.
11
- # The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
12
- # header.
13
- #
14
- # * http - Configured Net::HTTP instance
15
- # * consumer - OAuth::Consumer instance
16
- # * token - OAuth::Token instance
17
- # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
18
- # +signature_method+, +nonce+, +timestamp+)
19
- #
20
- # This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
21
- #
22
- # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1],
23
- # {OAuth Request Body Hash 1.0 Draft 4}[http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/4/spec.html,
24
- # http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html#when_to_include]
25
- def oauth!(http, consumer = nil, token = nil, options = {})
26
- helper_options = oauth_helper_options(http, consumer, token, options)
27
- @oauth_helper = OAuth::Client::Helper.new(self, helper_options)
28
- @oauth_helper.amend_user_agent_header(self)
29
- @oauth_helper.hash_body if oauth_body_hash_required?
30
- send("set_oauth_#{helper_options[:scheme]}")
31
- end
32
-
33
- # Create a string suitable for signing for an HTTP request. This process involves parameter
34
- # normalization as specified in the OAuth specification. The exact normalization also depends
35
- # on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
36
- # itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
37
- # header.
38
- #
39
- # * http - Configured Net::HTTP instance
40
- # * consumer - OAuth::Consumer instance
41
- # * token - OAuth::Token instance
42
- # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
43
- # +signature_method+, +nonce+, +timestamp+)
44
- #
45
- # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1],
46
- # {OAuth Request Body Hash 1.0 Draft 4}[http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/4/spec.html,
47
- # http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html#when_to_include]
48
- def signature_base_string(http, consumer = nil, token = nil, options = {})
49
- helper_options = oauth_helper_options(http, consumer, token, options)
50
- @oauth_helper = OAuth::Client::Helper.new(self, helper_options)
51
- @oauth_helper.hash_body if oauth_body_hash_required?
52
- @oauth_helper.signature_base_string
53
- end
6
+ module Net
7
+ class HTTPGenericRequest
8
+ include OAuth::Helper
9
+
10
+ attr_reader :oauth_helper
11
+
12
+ # Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
13
+ # this may add a header, additional query string parameters, or additional POST body parameters.
14
+ # The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
15
+ # header.
16
+ #
17
+ # * http - Configured Net::HTTP instance
18
+ # * consumer - OAuth::Consumer instance
19
+ # * token - OAuth::Token instance
20
+ # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
21
+ # +signature_method+, +nonce+, +timestamp+, +body_hash+)
22
+ #
23
+ # This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
24
+ #
25
+ # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1],
26
+ # {OAuth Request Body Hash 1.0 Draft 4}[http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/4/spec.html,
27
+ # http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html#when_to_include]
28
+ def oauth!(http, consumer = nil, token = nil, options = {})
29
+ helper_options = oauth_helper_options(http, consumer, token, options)
30
+ @oauth_helper = OAuth::Client::Helper.new(self, helper_options)
31
+ @oauth_helper.amend_user_agent_header(self)
32
+ @oauth_helper.hash_body if oauth_body_hash_required?(helper_options)
33
+ send("set_oauth_#{helper_options[:scheme]}")
34
+ end
54
35
 
55
- private
36
+ # Create a string suitable for signing for an HTTP request. This process involves parameter
37
+ # normalization as specified in the OAuth specification. The exact normalization also depends
38
+ # on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
39
+ # itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
40
+ # header.
41
+ #
42
+ # * http - Configured Net::HTTP instance
43
+ # * consumer - OAuth::Consumer instance
44
+ # * token - OAuth::Token instance
45
+ # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
46
+ # +signature_method+, +nonce+, +timestamp+)
47
+ #
48
+ # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1],
49
+ # {OAuth Request Body Hash 1.0 Draft 4}[http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/4/spec.html,
50
+ # http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html#when_to_include]
51
+ def signature_base_string(http, consumer = nil, token = nil, options = {})
52
+ helper_options = oauth_helper_options(http, consumer, token, options)
53
+ @oauth_helper = OAuth::Client::Helper.new(self, helper_options)
54
+ @oauth_helper.hash_body if oauth_body_hash_required?(helper_options)
55
+ @oauth_helper.signature_base_string
56
+ end
56
57
 
57
- def oauth_helper_options(http, consumer, token, options)
58
- { request_uri: oauth_full_request_uri(http, options),
59
- consumer: consumer,
60
- token: token,
61
- scheme: "header",
62
- signature_method: nil,
63
- nonce: nil,
64
- timestamp: nil }.merge(options)
65
- end
58
+ private
59
+
60
+ def oauth_helper_options(http, consumer, token, options)
61
+ { request_uri: oauth_full_request_uri(http, options),
62
+ consumer: consumer,
63
+ token: token,
64
+ scheme: "header",
65
+ signature_method: nil,
66
+ nonce: nil,
67
+ timestamp: nil,
68
+ body_hash_enabled: true }.merge(options)
69
+ end
66
70
 
67
- def oauth_full_request_uri(http, options)
68
- uri = URI.parse(path)
69
- uri.host = http.address
70
- uri.port = http.port
71
+ def oauth_full_request_uri(http, options)
72
+ uri = URI.parse(path)
73
+ uri.host = http.address
74
+ uri.port = http.port
71
75
 
72
- if options[:request_endpoint] && options[:site]
73
- is_https = options[:site].match(%r{^https://})
74
- uri.host = options[:site].gsub(%r{^https?://}, "")
75
- uri.port ||= is_https ? 443 : 80
76
- end
76
+ if options[:request_endpoint] && options[:site]
77
+ is_https = options[:site].match(%r{^https://})
78
+ uri.host = options[:site].gsub(%r{^https?://}, "")
79
+ uri.port ||= is_https ? 443 : 80
80
+ end
77
81
 
78
- uri.scheme = if http.respond_to?(:use_ssl?) && http.use_ssl?
79
- "https"
80
- else
81
- "http"
82
- end
82
+ uri.scheme = if http.respond_to?(:use_ssl?) && http.use_ssl?
83
+ "https"
84
+ else
85
+ "http"
86
+ end
83
87
 
84
- uri.to_s
85
- end
88
+ uri.to_s
89
+ end
86
90
 
87
- def oauth_body_hash_required?
88
- !@oauth_helper.token_request? && request_body_permitted? && !content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded")
89
- end
91
+ def oauth_body_hash_required?(options)
92
+ !@oauth_helper.token_request? && request_body_permitted? && !content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded") && options[:body_hash_enabled]
93
+ end
90
94
 
91
- def set_oauth_header
92
- self["Authorization"] = @oauth_helper.header
93
- end
95
+ def set_oauth_header
96
+ self["Authorization"] = @oauth_helper.header
97
+ end
94
98
 
95
- # FIXME: if you're using a POST body and query string parameters, this method
96
- # will move query string parameters into the body unexpectedly. This may
97
- # cause problems with non-x-www-form-urlencoded bodies submitted to URLs
98
- # containing query string params. If duplicate parameters are present in both
99
- # places, all instances should be included when calculating the signature
100
- # base string.
101
-
102
- def set_oauth_body
103
- set_form_data(@oauth_helper.stringify_keys(@oauth_helper.parameters_with_oauth))
104
- params_with_sig = @oauth_helper.parameters.merge(oauth_signature: @oauth_helper.signature)
105
- set_form_data(@oauth_helper.stringify_keys(params_with_sig))
106
- end
99
+ # FIXME: if you're using a POST body and query string parameters, this method
100
+ # will move query string parameters into the body unexpectedly. This may
101
+ # cause problems with non-x-www-form-urlencoded bodies submitted to URLs
102
+ # containing query string params. If duplicate parameters are present in both
103
+ # places, all instances should be included when calculating the signature
104
+ # base string.
105
+
106
+ def set_oauth_body
107
+ # NOTE: OAuth::Helper and @oauth_helper are not the same, despite sharing all methods defined in OAuth::Helper
108
+ # see: https://stackoverflow.com/a/53447775/213191
109
+ set_form_data(OAuth::Helper.stringify_keys(@oauth_helper.parameters_with_oauth))
110
+ params_with_sig = @oauth_helper.parameters.merge(oauth_signature: @oauth_helper.signature)
111
+ set_form_data(OAuth::Helper.stringify_keys(params_with_sig))
112
+ end
107
113
 
108
- def set_oauth_query_string
109
- oauth_params_str = @oauth_helper.oauth_parameters.map { |k, v| [escape(k), escape(v)].join("=") }.join("&")
110
- uri = URI.parse(path)
111
- uri.query = if uri.query.to_s == ""
112
- oauth_params_str
113
- else
114
- uri.query + "&" + oauth_params_str
115
- end
114
+ def set_oauth_query_string
115
+ oauth_params_str = @oauth_helper.oauth_parameters.map { |k, v| [escape(k), escape(v)].join("=") }.join("&")
116
+ uri = URI.parse(path)
117
+ uri.query = if uri.query.to_s == ""
118
+ oauth_params_str
119
+ else
120
+ "#{uri.query}&#{oauth_params_str}"
121
+ end
116
122
 
117
- @path = uri.to_s
123
+ @path = uri.to_s
118
124
 
119
- @path << "&oauth_signature=#{escape(oauth_helper.signature)}"
125
+ @path << "&oauth_signature=#{escape(oauth_helper.signature)}"
126
+ end
120
127
  end
121
128
  end
data/lib/oauth/client.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth
2
4
  module Client
3
5
  end