oauth 0.5.6 → 1.1.0

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