oauth 0.5.14 → 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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -0
  3. data/CHANGELOG.md +663 -239
  4. data/CITATION.cff +20 -0
  5. data/CODE_OF_CONDUCT.md +79 -29
  6. data/CONTRIBUTING.md +264 -15
  7. data/FUNDING.md +74 -0
  8. data/LICENSE.md +71 -0
  9. data/README.md +642 -297
  10. data/RUBOCOP.md +71 -0
  11. data/SECURITY.md +11 -12
  12. data/certs/pboling.pem +27 -0
  13. data/lib/oauth/auth_sanitizer.rb +36 -0
  14. data/lib/oauth/client/action_controller_request.rb +24 -12
  15. data/lib/oauth/client/em_http.rb +107 -100
  16. data/lib/oauth/client/helper.rb +80 -72
  17. data/lib/oauth/client/net_http.rb +139 -106
  18. data/lib/oauth/client.rb +2 -0
  19. data/lib/oauth/consumer.rb +250 -118
  20. data/lib/oauth/errors/error.rb +2 -0
  21. data/lib/oauth/errors/problem.rb +4 -1
  22. data/lib/oauth/errors/unauthorized.rb +4 -0
  23. data/lib/oauth/errors.rb +2 -0
  24. data/lib/oauth/helper.rb +34 -8
  25. data/lib/oauth/oauth.rb +32 -8
  26. data/lib/oauth/oauth_test_helper.rb +2 -0
  27. data/lib/oauth/optional.rb +20 -0
  28. data/lib/oauth/request_proxy/action_controller_request.rb +14 -31
  29. data/lib/oauth/request_proxy/action_dispatch_request.rb +34 -0
  30. data/lib/oauth/request_proxy/base.rb +42 -31
  31. data/lib/oauth/request_proxy/em_http_request.rb +53 -52
  32. data/lib/oauth/request_proxy/jabber_request.rb +9 -2
  33. data/lib/oauth/request_proxy/mock_request.rb +1 -1
  34. data/lib/oauth/request_proxy/net_http.rb +6 -8
  35. data/lib/oauth/request_proxy/rack_request.rb +0 -4
  36. data/lib/oauth/request_proxy/rest_client_request.rb +6 -4
  37. data/lib/oauth/request_proxy.rb +20 -13
  38. data/lib/oauth/server.rb +14 -6
  39. data/lib/oauth/signature/base.rb +82 -66
  40. data/lib/oauth/signature/hmac/sha1.rb +15 -9
  41. data/lib/oauth/signature/hmac/sha256.rb +15 -9
  42. data/lib/oauth/signature/plaintext.rb +18 -20
  43. data/lib/oauth/signature/rsa/sha1.rb +53 -38
  44. data/lib/oauth/signature.rb +40 -33
  45. data/lib/oauth/token.rb +2 -0
  46. data/lib/oauth/tokens/access_token.rb +3 -1
  47. data/lib/oauth/tokens/consumer_token.rb +10 -6
  48. data/lib/oauth/tokens/request_token.rb +12 -4
  49. data/lib/oauth/tokens/server_token.rb +2 -0
  50. data/lib/oauth/tokens/token.rb +15 -1
  51. data/lib/oauth/version.rb +6 -1
  52. data/lib/oauth.rb +11 -2
  53. data/sig/oauth/consumer.rbs +9 -0
  54. data/sig/oauth/signature/base.rbs +12 -0
  55. data/sig/oauth/tokens/token.rbs +8 -0
  56. data/sig/oauth/version.rbs +6 -0
  57. data.tar.gz.sig +0 -0
  58. metadata +349 -90
  59. metadata.gz.sig +0 -0
  60. data/LICENSE +0 -21
  61. data/TODO +0 -32
  62. data/bin/oauth +0 -11
  63. data/lib/oauth/cli/authorize_command.rb +0 -69
  64. data/lib/oauth/cli/base_command.rb +0 -210
  65. data/lib/oauth/cli/help_command.rb +0 -22
  66. data/lib/oauth/cli/query_command.rb +0 -25
  67. data/lib/oauth/cli/sign_command.rb +0 -78
  68. data/lib/oauth/cli/version_command.rb +0 -7
  69. data/lib/oauth/cli.rb +0 -56
data/RUBOCOP.md ADDED
@@ -0,0 +1,71 @@
1
+ # RuboCop Usage Guide
2
+
3
+ ## Overview
4
+
5
+ A tale of two RuboCop plugin gems.
6
+
7
+ ### RuboCop Gradual
8
+
9
+ This project uses `rubocop_gradual` instead of vanilla RuboCop for code style checking. The `rubocop_gradual` tool allows for gradual adoption of RuboCop rules by tracking violations in a lock file.
10
+
11
+ ### RuboCop LTS
12
+
13
+ This project uses `rubocop-lts` to ensure, on a best-effort basis, compatibility with Ruby >= 1.9.2.
14
+ RuboCop rules are meticulously configured by the `rubocop-lts` family of gems to ensure that a project is compatible with a specific version of Ruby. See: https://rubocop-lts.gitlab.io for more.
15
+
16
+ ## Checking RuboCop Violations
17
+
18
+ To check for RuboCop violations in this project, always use:
19
+
20
+ ```bash
21
+ bundle exec rake rubocop_gradual:check
22
+ ```
23
+
24
+ **Do not use** the standard RuboCop commands like:
25
+ - `bundle exec rubocop`
26
+ - `rubocop`
27
+
28
+ ## Understanding the Lock File
29
+
30
+ The `.rubocop_gradual.lock` file tracks all current RuboCop violations in the project. This allows the team to:
31
+
32
+ 1. Prevent new violations while gradually fixing existing ones
33
+ 2. Track progress on code style improvements
34
+ 3. Ensure CI builds don't fail due to pre-existing violations
35
+
36
+ ## Common Commands
37
+
38
+ - **Check violations**
39
+ - `bundle exec rake rubocop_gradual`
40
+ - `bundle exec rake rubocop_gradual:check`
41
+ - **(Safe) Autocorrect violations, and update lockfile if no new violations**
42
+ - `bundle exec rake rubocop_gradual:autocorrect`
43
+ - **Force update the lock file (w/o autocorrect) to match violations present in code**
44
+ - `bundle exec rake rubocop_gradual:force_update`
45
+
46
+ ## Workflow
47
+
48
+ 1. Before submitting a PR, run `bundle exec rake rubocop_gradual:autocorrect`
49
+ a. or just the default `bundle exec rake`, as autocorrection is a pre-requisite of the default task.
50
+ 2. If there are new violations, either:
51
+ - Fix them in your code
52
+ - Run `bundle exec rake rubocop_gradual:force_update` to update the lock file (only for violations you can't fix immediately)
53
+ 3. Commit the updated `.rubocop_gradual.lock` file along with your changes
54
+
55
+ ## Never add inline RuboCop disables
56
+
57
+ Do not add inline `rubocop:disable` / `rubocop:enable` comments anywhere in the codebase (including specs, except when following the few existing `rubocop:disable` patterns for a rule already being disabled elsewhere in the code). We handle exceptions in two supported ways:
58
+
59
+ - Permanent/structural exceptions: prefer adjusting the RuboCop configuration (e.g., in `.rubocop.yml`) to exclude a rule for a path or file pattern when it makes sense project-wide.
60
+ - Temporary exceptions while improving code: record the current violations in `.rubocop_gradual.lock` via the gradual workflow:
61
+ - `bundle exec rake rubocop_gradual:autocorrect` (preferred; will autocorrect what it can and update the lock only if no new violations were introduced)
62
+ - If needed, `bundle exec rake rubocop_gradual:force_update` (as a last resort when you cannot fix the newly reported violations immediately)
63
+
64
+ In general, treat the rules as guidance to follow; fix violations rather than ignore them. For example, RSpec conventions in this project expect `described_class` to be used in specs that target a specific class under test.
65
+
66
+ ## Benefits of rubocop_gradual
67
+
68
+ - Allows incremental adoption of code style rules
69
+ - Prevents CI failures due to pre-existing violations
70
+ - Provides a clear record of code style debt
71
+ - Enables focused efforts on improving code quality over time
data/SECURITY.md CHANGED
@@ -2,21 +2,20 @@
2
2
 
3
3
  ## Supported Versions
4
4
 
5
- | Version | Supported |
6
- |---------|--------------------|
7
- | 0.6.x | :white_check_mark: |
8
- | 0.5.x | :white_check_mark: |
9
- | <= 0.5 | :x: |
5
+ | Version | Supported |
6
+ |----------|-----------|
7
+ | 1.1.latest | |
10
8
 
11
- NOTE: Support for version 0.5.x will end in April, 2023
9
+ ## Security contact information
12
10
 
13
- ## Reporting a Vulnerability
14
-
15
- To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
11
+ To report a security vulnerability, please use the
12
+ [Tidelift security contact](https://tidelift.com/security).
16
13
  Tidelift will coordinate the fix and disclosure.
17
14
 
18
- ## OAuth for Enterprise
15
+ ## Additional Support
19
16
 
20
- Available as part of the Tidelift Subscription.
17
+ If you are interested in support for versions older than the latest release,
18
+ please consider sponsoring the project / maintainer @ https://liberapay.com/pboling/donate,
19
+ or find other sponsorship links in the [README].
21
20
 
22
- The maintainers of oauth and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.](https://tidelift.com/subscription/pkg/rubygems-oauth?utm_source=rubygems-oauth&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
21
+ [README]: README.md
data/certs/pboling.pem ADDED
@@ -0,0 +1,27 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl
3
+ ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
4
+ A2NvbTAeFw0yNTA1MDQxNTMzMDlaFw00NTA0MjkxNTMzMDlaMEMxFTATBgNVBAMM
5
+ DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
6
+ LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAruUoo0WA
7
+ uoNuq6puKWYeRYiZekz/nsDeK5x/0IEirzcCEvaHr3Bmz7rjo1I6On3gGKmiZs61
8
+ LRmQ3oxy77ydmkGTXBjruJB+pQEn7UfLSgQ0xa1/X3kdBZt6RmabFlBxnHkoaGY5
9
+ mZuZ5+Z7walmv6sFD9ajhzj+oIgwWfnEHkXYTR8I6VLN7MRRKGMPoZ/yvOmxb2DN
10
+ coEEHWKO9CvgYpW7asIihl/9GMpKiRkcYPm9dGQzZc6uTwom1COfW0+ZOFrDVBuV
11
+ FMQRPswZcY4Wlq0uEBLPU7hxnCL9nKK6Y9IhdDcz1mY6HZ91WImNslOSI0S8hRpj
12
+ yGOWxQIhBT3fqCBlRIqFQBudrnD9jSNpSGsFvbEijd5ns7Z9ZMehXkXDycpGAUj1
13
+ to/5cuTWWw1JqUWrKJYoifnVhtE1o1DZ+LkPtWxHtz5kjDG/zR3MG0Ula0UOavlD
14
+ qbnbcXPBnwXtTFeZ3C+yrWpE4pGnl3yGkZj9SMTlo9qnTMiPmuWKQDatAgMBAAGj
15
+ fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQE8uWvNbPVNRXZ
16
+ HlgPbc2PCzC4bjAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG
17
+ A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD
18
+ ggGBAJbnUwfJQFPkBgH9cL7hoBfRtmWiCvdqdjeTmi04u8zVNCUox0A4gT982DE9
19
+ wmuN12LpdajxZONqbXuzZvc+nb0StFwmFYZG6iDwaf4BPywm2e/Vmq0YG45vZXGR
20
+ L8yMDSK1cQXjmA+ZBKOHKWavxP6Vp7lWvjAhz8RFwqF9GuNIdhv9NpnCAWcMZtpm
21
+ GUPyIWw/Cw/2wZp74QzZj6Npx+LdXoLTF1HMSJXZ7/pkxLCsB8m4EFVdb/IrW/0k
22
+ kNSfjtAfBHO8nLGuqQZVH9IBD1i9K6aSs7pT6TW8itXUIlkIUI2tg5YzW6OFfPzq
23
+ QekSkX3lZfY+HTSp/o+YvKkqWLUV7PQ7xh1ZYDtocpaHwgxe/j3bBqHE+CUPH2vA
24
+ 0V/FwdTRWcwsjVoOJTrYcff8pBZ8r2MvtAc54xfnnhGFzeRHfcltobgFxkAXdE6p
25
+ DVjBtqT23eugOqQ73umLcYDZkc36vnqGxUBSsXrzY9pzV5gGr2I8YUxMqf6ATrZt
26
+ L9nRqA==
27
+ -----END CERTIFICATE-----
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OAuth
4
+ AUTH_SANITIZER = begin
5
+ auth_sanitizer_requirement = Gem::Requirement.new("~> 0.1", ">= 0.1.3")
6
+ auth_sanitizer_spec = Gem.loaded_specs["auth-sanitizer"]
7
+ unless auth_sanitizer_spec && auth_sanitizer_requirement.satisfied_by?(auth_sanitizer_spec.version)
8
+ # :nocov:
9
+ auth_sanitizer_spec = Gem::Specification.find_by_name("auth-sanitizer", auth_sanitizer_requirement)
10
+ # :nocov:
11
+ end
12
+
13
+ auth_sanitizer_loader_path = File.join(
14
+ auth_sanitizer_spec.full_gem_path,
15
+ "lib/auth_sanitizer/loader.rb",
16
+ )
17
+ unless File.file?(auth_sanitizer_loader_path)
18
+ # :nocov:
19
+ raise LoadError, "oauth requires auth-sanitizer #{auth_sanitizer_requirement}; " \
20
+ "loader not found at #{auth_sanitizer_loader_path}"
21
+ # :nocov:
22
+ end
23
+
24
+ auth_sanitizer_loader_namespace = Module.new
25
+ auth_sanitizer_loader_namespace.module_eval(
26
+ File.read(auth_sanitizer_loader_path),
27
+ auth_sanitizer_loader_path,
28
+ 1,
29
+ )
30
+
31
+ auth_sanitizer_loader_namespace
32
+ .const_get(:AuthSanitizer)
33
+ .const_get(:Loader)
34
+ .load_isolated
35
+ end
36
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  if defined? ActionDispatch
2
4
  require "oauth/request_proxy/rack_request"
3
5
  require "oauth/request_proxy/action_dispatch_request"
@@ -24,27 +26,36 @@ module ActionController
24
26
  end
25
27
 
26
28
  class TestRequest
29
+ OAUTH_ENABLED_KEY = :oauth_action_controller_test_request_use_oauth
30
+
27
31
  class << self
28
- attr_writer :use_oauth
29
- end
32
+ def use_oauth=(value)
33
+ Thread.current[OAUTH_ENABLED_KEY] = value
34
+ end
30
35
 
31
- def self.use_oauth?
32
- @use_oauth
36
+ def use_oauth?
37
+ Thread.current[OAUTH_ENABLED_KEY]
38
+ end
33
39
  end
34
40
 
35
41
  def configure_oauth(consumer = nil, token = nil, options = {})
36
- @oauth_options = { consumer: consumer,
37
- token: token,
38
- scheme: "header",
39
- signature_method: nil,
40
- nonce: nil,
41
- timestamp: nil }.merge(options)
42
+ @oauth_options = {
43
+ consumer: consumer,
44
+ token: token,
45
+ scheme: "header",
46
+ signature_method: nil,
47
+ nonce: nil,
48
+ timestamp: nil,
49
+ }.merge(options)
42
50
  end
43
51
 
44
52
  def apply_oauth!
45
53
  return unless ActionController::TestRequest.use_oauth? && @oauth_options
46
54
 
47
- @oauth_helper = OAuth::Client::Helper.new(self, @oauth_options.merge(request_uri: (respond_to?(:fullpath) ? fullpath : request_uri)))
55
+ @oauth_helper = OAuth::Client::Helper.new(
56
+ self,
57
+ @oauth_options.merge(request_uri: (respond_to?(:fullpath) ? fullpath : request_uri)),
58
+ )
48
59
  @oauth_helper.amend_user_agent_header(env)
49
60
 
50
61
  send("set_oauth_#{@oauth_options[:scheme]}")
@@ -59,6 +70,7 @@ module ActionController
59
70
  @query_parameters.merge!(oauth_signature: @oauth_helper.signature)
60
71
  end
61
72
 
62
- def set_oauth_query_string; end
73
+ def set_oauth_query_string
74
+ end
63
75
  end
64
76
  end
@@ -1,119 +1,126 @@
1
- require "em-http"
1
+ # frozen_string_literal: true
2
+
2
3
  require "oauth/helper"
3
- require "oauth/request_proxy/em_http_request"
4
+ require "oauth/optional"
4
5
 
5
- # Extensions for em-http so that we can use consumer.sign! with an EventMachine::HttpClient
6
- # instance. This is purely syntactic sugar.
7
- module EventMachine
8
- class HttpClient
9
- attr_reader :oauth_helper
6
+ if OAuth::Optional.em_http_available?
7
+ require "oauth/request_proxy/em_http_request"
10
8
 
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)
9
+ # Extensions for em-http so that we can use consumer.sign! with an EventMachine::HttpClient
10
+ # instance. This is purely syntactic sugar.
11
+ module EventMachine
12
+ class HttpClient
13
+ attr_reader :oauth_helper
33
14
 
34
- @oauth_helper = OAuth::Client::Helper.new(self, options)
35
- __send__(:"set_oauth_#{options[:scheme]}")
36
- end
15
+ # Add the OAuth information to an HTTP request. Depending on the <tt>options[:scheme]</tt> setting
16
+ # this may add a header, additional query string parameters, or additional POST body parameters.
17
+ # The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
18
+ # header.
19
+ #
20
+ # * http - Configured Net::HTTP instance, ignored in this scenario except for getting host.
21
+ # * consumer - OAuth::Consumer instance
22
+ # * token - OAuth::Token instance
23
+ # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
24
+ # +signature_method+, +nonce+, +timestamp+)
25
+ #
26
+ # This method also modifies the <tt>User-Agent</tt> header to add the OAuth gem version.
27
+ #
28
+ # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1]
29
+ def oauth!(http, consumer = nil, token = nil, options = {})
30
+ options = {
31
+ request_uri: normalized_oauth_uri(http),
32
+ consumer: consumer,
33
+ token: token,
34
+ scheme: "header",
35
+ signature_method: nil,
36
+ nonce: nil,
37
+ timestamp: nil,
38
+ }.merge(options)
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
+ @oauth_helper = OAuth::Client::Helper.new(self, options)
41
+ __send__(:"set_oauth_#{options[:scheme]}")
42
+ end
59
43
 
60
- OAuth::Client::Helper.new(self, options).signature_base_string
61
- end
44
+ # Create a string suitable for signing for an HTTP request. This process involves parameter
45
+ # normalization as specified in the OAuth specification. The exact normalization also depends
46
+ # on the <tt>options[:scheme]</tt> being used so this must match what will be used for the request
47
+ # itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+
48
+ # header.
49
+ #
50
+ # * http - Configured Net::HTTP instance
51
+ # * consumer - OAuth::Consumer instance
52
+ # * token - OAuth::Token instance
53
+ # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
54
+ # +signature_method+, +nonce+, +timestamp+)
55
+ #
56
+ # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1]
57
+ def signature_base_string(http, consumer = nil, token = nil, options = {})
58
+ options = {
59
+ request_uri: normalized_oauth_uri(http),
60
+ consumer: consumer,
61
+ token: token,
62
+ scheme: "header",
63
+ signature_method: nil,
64
+ nonce: nil,
65
+ timestamp: nil,
66
+ }.merge(options)
62
67
 
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 = @conn.dup
69
- encoded_query = encode_query(@conn, @req[:query])
70
- path, query = encoded_query.split("?", 2)
71
- uri.query = query unless encoded_query.empty?
72
- uri.path = path
73
- uri
68
+ OAuth::Client::Helper.new(self, options).signature_base_string
74
69
  end
75
- end
76
-
77
- protected
78
70
 
79
- def combine_query(path, query, uri_query)
80
- combined_query = if query.is_a?(Hash)
81
- query.map { |k, v| encode_param(k, v) }.join("&")
82
- else
83
- query.to_s
71
+ # This code was lifted from the em-http-request because it was removed from
72
+ # the gem June 19, 2010
73
+ # see: http://github.com/igrigorik/em-http-request/commit/d536fc17d56dbe55c487eab01e2ff9382a62598b
74
+ def normalize_uri
75
+ @normalized_uri ||= begin
76
+ uri = @conn.dup
77
+ encoded_query = encode_query(@conn, @req[:query])
78
+ path, query = encoded_query.split("?", 2)
79
+ uri.query = query unless encoded_query.empty?
80
+ uri.path = path
81
+ uri
82
+ end
84
83
  end
85
- unless uri_query.to_s.empty?
86
- combined_query = [combined_query, uri_query].reject(&:empty?).join("&")
84
+
85
+ protected
86
+
87
+ def combine_query(path, query, uri_query)
88
+ combined_query = if query.is_a?(Hash)
89
+ query.map { |k, v| encode_param(k, v) }.join("&")
90
+ else
91
+ query.to_s
92
+ end
93
+ combined_query = [combined_query, uri_query].reject(&:empty?).join("&") unless uri_query.to_s.empty?
94
+ combined_query.to_s.empty? ? path : "#{path}?#{combined_query}"
87
95
  end
88
- combined_query.to_s.empty? ? path : "#{path}?#{combined_query}"
89
- end
90
96
 
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
+ # Since we expect to get the host etc details from the http instance (...),
98
+ # we create a fake url here. Surely this is a horrible, horrible idea?
99
+ def normalized_oauth_uri(http)
100
+ uri = URI.parse(normalize_uri.path)
101
+ uri.host = http.address
102
+ uri.port = http.port
97
103
 
98
- uri.scheme = if http.respond_to?(:use_ssl?) && http.use_ssl?
99
- "https"
100
- else
101
- "http"
102
- end
103
- uri.to_s
104
- end
104
+ uri.scheme = if http.respond_to?(:use_ssl?) && http.use_ssl?
105
+ "https"
106
+ else
107
+ "http"
108
+ end
109
+ uri.to_s
110
+ end
105
111
 
106
- def set_oauth_header
107
- req[:head] ||= {}
108
- req[:head].merge!("Authorization" => @oauth_helper.header)
109
- end
112
+ def set_oauth_header
113
+ req[:head] ||= {}
114
+ req[:head].merge!("Authorization" => @oauth_helper.header)
115
+ end
110
116
 
111
- def set_oauth_body
112
- raise NotImplementedError, "please use the set_oauth_header method instead"
113
- end
117
+ def set_oauth_body
118
+ raise NotImplementedError, "please use the set_oauth_header method instead"
119
+ end
114
120
 
115
- def set_oauth_query_string
116
- raise NotImplementedError, "please use the set_oauth_header method instead"
121
+ def set_oauth_query_string
122
+ raise NotImplementedError, "please use the set_oauth_header method instead"
123
+ end
117
124
  end
118
125
  end
119
126
  end
@@ -1,98 +1,106 @@
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, {
53
+ uri: options[:request_uri],
54
+ consumer: options[:consumer],
55
+ token: options[:token],
56
+ unsigned_parameters: options[:unsigned_parameters],
57
+ }.merge(extra_options))
58
+ end
54
59
 
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
60
+ def signature_base_string(extra_options = {})
61
+ OAuth::Signature.signature_base_string(@request, {
62
+ uri: options[:request_uri],
63
+ consumer: options[:consumer],
64
+ token: options[:token],
65
+ parameters: oauth_parameters,
66
+ }.merge(extra_options))
67
+ end
61
68
 
62
- def token_request?
63
- @options[:token_request].eql?(true)
64
- end
69
+ def token_request?
70
+ @options[:token_request].eql?(true)
71
+ end
65
72
 
66
- def hash_body
67
- @options[:body_hash] = OAuth::Signature.body_hash(@request, parameters: oauth_parameters)
68
- end
73
+ def hash_body
74
+ @options[:body_hash] = OAuth::Signature.body_hash(@request, parameters: oauth_parameters)
75
+ end
69
76
 
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
77
+ def amend_user_agent_header(headers)
78
+ @oauth_ua_string ||= "OAuth gem v#{OAuth::Version::VERSION}"
79
+ # Net::HTTP in 1.9 appends Ruby
80
+ if headers["User-Agent"] && headers["User-Agent"] != "Ruby"
81
+ headers["User-Agent"] += " (#{@oauth_ua_string})"
82
+ else
83
+ headers["User-Agent"] = @oauth_ua_string
84
+ end
77
85
  end
78
- end
79
86
 
80
- def header
81
- parameters = oauth_parameters
82
- parameters["oauth_signature"] = signature(options.merge(parameters: parameters))
87
+ def header
88
+ parameters = oauth_parameters
89
+ parameters["oauth_signature"] = signature(options.merge(parameters: parameters))
83
90
 
84
- header_params_str = parameters.sort.map { |k, v| "#{k}=\"#{escape(v)}\"" }.join(", ")
91
+ header_params_str = parameters.sort.map { |k, v| "#{k}=\"#{escape(v)}\"" }.join(", ")
85
92
 
86
- realm = "realm=\"#{options[:realm]}\", " if options[:realm]
87
- "OAuth #{realm}#{header_params_str}"
88
- end
93
+ realm = "realm=\"#{options[:realm]}\", " if options[:realm]
94
+ "OAuth #{realm}#{header_params_str}"
95
+ end
89
96
 
90
- def parameters
91
- OAuth::RequestProxy.proxy(@request).parameters
92
- end
97
+ def parameters
98
+ OAuth::RequestProxy.proxy(@request).parameters
99
+ end
93
100
 
94
- def parameters_with_oauth
95
- oauth_parameters.merge(parameters)
101
+ def parameters_with_oauth
102
+ oauth_parameters.merge(parameters)
103
+ end
96
104
  end
97
105
  end
98
106
  end