signet 0.11.0 → 0.14.1
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 +51 -15
- data/Gemfile +5 -4
- data/README.md +4 -6
- data/Rakefile +107 -37
- data/lib/signet.rb +17 -14
- data/lib/signet/errors.rb +4 -4
- data/lib/signet/oauth_1.rb +129 -154
- data/lib/signet/oauth_1/client.rb +309 -343
- data/lib/signet/oauth_1/credential.rb +40 -37
- data/lib/signet/oauth_1/server.rb +197 -203
- data/lib/signet/oauth_1/signature_methods/hmac_sha1.rb +11 -10
- data/lib/signet/oauth_1/signature_methods/plaintext.rb +8 -7
- data/lib/signet/oauth_1/signature_methods/rsa_sha1.rb +11 -11
- data/lib/signet/oauth_2.rb +41 -43
- data/lib/signet/oauth_2/client.rb +328 -313
- data/lib/signet/version.rb +2 -73
- data/signet.gemspec +37 -39
- data/spec/signet/oauth_1/client_spec.rb +313 -315
- data/spec/signet/oauth_1/credential_spec.rb +64 -56
- data/spec/signet/oauth_1/server_spec.rb +362 -362
- data/spec/signet/oauth_1/signature_methods/hmac_sha1_spec.rb +26 -26
- data/spec/signet/oauth_1/signature_methods/plaintext_spec.rb +28 -28
- data/spec/signet/oauth_1/signature_methods/rsa_sha1_spec.rb +34 -35
- data/spec/signet/oauth_1_spec.rb +553 -524
- data/spec/signet/oauth_2/client_spec.rb +652 -576
- data/spec/signet/oauth_2_spec.rb +88 -89
- data/spec/signet_spec.rb +41 -41
- data/spec/spec_helper.rb +7 -7
- data/spec/spec_helper_spec.rb +8 -8
- metadata +64 -52
- data/tasks/clobber.rake +0 -2
- data/tasks/gem.rake +0 -34
- data/tasks/git.rake +0 -40
- data/tasks/metrics.rake +0 -41
- data/tasks/spec.rake +0 -34
- data/tasks/wiki.rake +0 -38
- data/tasks/yard.rake +0 -21
| @@ -15,6 +15,11 @@ | |
| 15 15 | 
             
            module Signet #:nodoc:
         | 
| 16 16 | 
             
              module OAuth1
         | 
| 17 17 | 
             
                class Credential
         | 
| 18 | 
            +
                  # rubocop:disable Metrics/AbcSize
         | 
| 19 | 
            +
                  # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 20 | 
            +
                  # rubocop:disable Metrics/MethodLength
         | 
| 21 | 
            +
                  # rubocop:disable Metrics/PerceivedComplexity
         | 
| 22 | 
            +
             | 
| 18 23 | 
             
                  ##
         | 
| 19 24 | 
             
                  # Creates a token object from a key and secret.
         | 
| 20 25 | 
             
                  #
         | 
| @@ -34,7 +39,7 @@ module Signet #:nodoc: | |
| 34 39 | 
             
                  #   Signet::OAuth1::Credential.new(
         | 
| 35 40 | 
             
                  #     "dpf43f3p2l4k3l03", "kd94hf93k423kf44"
         | 
| 36 41 | 
             
                  #   )
         | 
| 37 | 
            -
                  def initialize | 
| 42 | 
            +
                  def initialize *args
         | 
| 38 43 | 
             
                    # We want to be particularly flexible in how we initialize a token
         | 
| 39 44 | 
             
                    # object for maximum interoperability.  However, this flexibility
         | 
| 40 45 | 
             
                    # means we need to be careful about returning an unexpected value for
         | 
| @@ -45,73 +50,71 @@ module Signet #:nodoc: | |
| 45 50 | 
             
                    # indifferent access.  Also uglier.
         | 
| 46 51 | 
             
                    key_from_hash = lambda do |parameters|
         | 
| 47 52 | 
             
                      parameters["oauth_token"] ||
         | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 53 | 
            +
                        parameters[:oauth_token] ||
         | 
| 54 | 
            +
                        parameters["key"] ||
         | 
| 55 | 
            +
                        parameters[:key]
         | 
| 51 56 | 
             
                    end
         | 
| 52 57 | 
             
                    secret_from_hash = lambda do |parameters|
         | 
| 53 58 | 
             
                      parameters["oauth_token_secret"] ||
         | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 59 | 
            +
                        parameters[:oauth_token_secret] ||
         | 
| 60 | 
            +
                        parameters["secret"] ||
         | 
| 61 | 
            +
                        parameters[:secret]
         | 
| 57 62 | 
             
                    end
         | 
| 58 | 
            -
                    if args.first.respond_to? | 
| 63 | 
            +
                    if args.first.respond_to? :to_hash
         | 
| 59 64 | 
             
                      parameters = args.first.to_hash
         | 
| 60 | 
            -
                      @key = key_from_hash.call | 
| 61 | 
            -
                      @secret = secret_from_hash.call | 
| 65 | 
            +
                      @key = key_from_hash.call parameters
         | 
| 66 | 
            +
                      @secret = secret_from_hash.call parameters
         | 
| 62 67 | 
             
                      unless @key && @secret
         | 
| 63 68 | 
             
                        raise ArgumentError,
         | 
| 64 | 
            -
             | 
| 69 | 
            +
                              "Could not find both key and secret in #{hash.inspect}."
         | 
| 65 70 | 
             
                      end
         | 
| 66 71 | 
             
                    else
         | 
| 67 72 | 
             
                      # Normalize to an Array
         | 
| 68 | 
            -
                      if !args.first. | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 73 | 
            +
                      if !args.first.is_a?(String) &&
         | 
| 74 | 
            +
                         !args.first.respond_to?(:to_str) &&
         | 
| 75 | 
            +
                         args.first.is_a?(Enumerable)
         | 
| 71 76 | 
             
                        # We need to special-case strings since they're technically
         | 
| 72 77 | 
             
                        # Enumerable objects.
         | 
| 73 78 | 
             
                        args = args.first.to_a
         | 
| 74 | 
            -
                      elsif args.first.respond_to? | 
| 79 | 
            +
                      elsif args.first.respond_to? :to_ary
         | 
| 75 80 | 
             
                        args = args.first.to_ary
         | 
| 76 81 | 
             
                      end
         | 
| 77 | 
            -
                      if args.all? { |value| value. | 
| 78 | 
            -
                        parameters = args. | 
| 79 | 
            -
                        @key = key_from_hash.call | 
| 80 | 
            -
                        @secret = secret_from_hash.call | 
| 82 | 
            +
                      if args.all? { |value| value.is_a? Array }
         | 
| 83 | 
            +
                        parameters = args.each_with_object({}) { |(k, v), h| h[k] = v; }
         | 
| 84 | 
            +
                        @key = key_from_hash.call parameters
         | 
| 85 | 
            +
                        @secret = secret_from_hash.call parameters
         | 
| 81 86 | 
             
                      elsif args.size == 2
         | 
| 82 87 | 
             
                        @key, @secret = args
         | 
| 83 88 | 
             
                      else
         | 
| 84 89 | 
             
                        raise ArgumentError,
         | 
| 85 | 
            -
             | 
| 90 | 
            +
                              "wrong number of arguments (#{args.size} for 2)"
         | 
| 86 91 | 
             
                      end
         | 
| 87 92 | 
             
                    end
         | 
| 88 | 
            -
                     | 
| 89 | 
            -
             | 
| 90 | 
            -
                     | 
| 91 | 
            -
             | 
| 92 | 
            -
                    end
         | 
| 93 | 
            -
                    if @secret.respond_to?(:to_str)
         | 
| 94 | 
            -
                      @secret = @secret.to_str
         | 
| 95 | 
            -
                    else
         | 
| 96 | 
            -
                      raise TypeError, "Expected String, got #{@secret.class}."
         | 
| 97 | 
            -
                    end
         | 
| 93 | 
            +
                    raise TypeError, "Expected String, got #{@key.class}." unless @key.respond_to? :to_str
         | 
| 94 | 
            +
                    @key = @key.to_str
         | 
| 95 | 
            +
                    raise TypeError, "Expected String, got #{@secret.class}." unless @secret.respond_to? :to_str
         | 
| 96 | 
            +
                    @secret = @secret.to_str
         | 
| 98 97 | 
             
                  end
         | 
| 98 | 
            +
                  # rubocop:enable Metrics/AbcSize
         | 
| 99 | 
            +
                  # rubocop:enable Metrics/CyclomaticComplexity
         | 
| 100 | 
            +
                  # rubocop:enable Metrics/MethodLength
         | 
| 101 | 
            +
                  # rubocop:enable Metrics/PerceivedComplexity
         | 
| 99 102 |  | 
| 100 103 | 
             
                  attr_accessor :key, :secret
         | 
| 101 104 |  | 
| 102 105 | 
             
                  def to_hash
         | 
| 103 | 
            -
                     | 
| 104 | 
            -
                      "oauth_token" | 
| 105 | 
            -
                      "oauth_token_secret" =>  | 
| 106 | 
            +
                    {
         | 
| 107 | 
            +
                      "oauth_token"        => key,
         | 
| 108 | 
            +
                      "oauth_token_secret" => secret
         | 
| 106 109 | 
             
                    }
         | 
| 107 110 | 
             
                  end
         | 
| 108 | 
            -
                   | 
| 111 | 
            +
                  alias to_h to_hash
         | 
| 109 112 |  | 
| 110 | 
            -
                  def == | 
| 113 | 
            +
                  def == other
         | 
| 111 114 | 
             
                    if other.respond_to?(:key) && other.respond_to?(:secret)
         | 
| 112 | 
            -
                       | 
| 115 | 
            +
                      key == other.key && secret == other.secret
         | 
| 113 116 | 
             
                    else
         | 
| 114 | 
            -
                       | 
| 117 | 
            +
                      false
         | 
| 115 118 | 
             
                    end
         | 
| 116 119 | 
             
                  end
         | 
| 117 120 | 
             
                end
         | 
| @@ -12,18 +12,17 @@ | |
| 12 12 | 
             
            #    See the License for the specific language governing permissions and
         | 
| 13 13 | 
             
            #    limitations under the License.
         | 
| 14 14 | 
             
            #
         | 
| 15 | 
            -
            require  | 
| 16 | 
            -
            require  | 
| 17 | 
            -
            require  | 
| 18 | 
            -
            require  | 
| 19 | 
            -
            require  | 
| 20 | 
            -
            require  | 
| 21 | 
            -
            require  | 
| 15 | 
            +
            require "faraday"
         | 
| 16 | 
            +
            require "stringio"
         | 
| 17 | 
            +
            require "addressable/uri"
         | 
| 18 | 
            +
            require "signet"
         | 
| 19 | 
            +
            require "signet/errors"
         | 
| 20 | 
            +
            require "signet/oauth_1"
         | 
| 21 | 
            +
            require "signet/oauth_1/credential"
         | 
| 22 22 |  | 
| 23 23 | 
             
            module Signet
         | 
| 24 24 | 
             
              module OAuth1
         | 
| 25 25 | 
             
                class Server
         | 
| 26 | 
            -
             | 
| 27 26 | 
             
                  # @return [Proc] lookup the value from this Proc.
         | 
| 28 27 | 
             
                  attr_accessor :nonce_timestamp, :client_credential, :token_credential,
         | 
| 29 28 | 
             
                                :temporary_credential, :verifier
         | 
| @@ -50,19 +49,21 @@ module Signet | |
| 50 49 | 
             
                  #     :verifier =>
         | 
| 51 50 | 
             
                  #       lambda {|verifier| Verifier.find_by_verifier(verifier).active? }
         | 
| 52 51 | 
             
                  #   )
         | 
| 53 | 
            -
                  def initialize | 
| 52 | 
            +
                  def initialize options = {}
         | 
| 54 53 | 
             
                    [:nonce_timestamp, :client_credential, :token_credential,
         | 
| 55 54 | 
             
                     :temporary_credential, :verifier].each do |attr|
         | 
| 56 | 
            -
             | 
| 55 | 
            +
                      instance_variable_set "@#{attr}", options[attr]
         | 
| 57 56 | 
             
                    end
         | 
| 58 57 | 
             
                  end
         | 
| 59 | 
            -
             
         | 
| 58 | 
            +
                  # rubocop:disable Naming/UncommunicativeMethodParamName
         | 
| 59 | 
            +
             | 
| 60 60 | 
             
                  # Constant time string comparison.
         | 
| 61 | 
            -
                  def safe_equals? | 
| 61 | 
            +
                  def safe_equals? a, b
         | 
| 62 62 | 
             
                    check = a.bytesize ^ b.bytesize
         | 
| 63 63 | 
             
                    a.bytes.zip(b.bytes) { |x, y| check |= x ^ y.to_i }
         | 
| 64 | 
            -
                    check | 
| 64 | 
            +
                    check.zero?
         | 
| 65 65 | 
             
                  end
         | 
| 66 | 
            +
                  # rubocop:enable Naming/UncommunicativeMethodParamName
         | 
| 66 67 |  | 
| 67 68 | 
             
                  ##
         | 
| 68 69 | 
             
                  # Determine if the supplied nonce/timestamp pair is valid by calling
         | 
| @@ -71,10 +72,11 @@ module Signet | |
| 71 72 | 
             
                  # @param [String, #to_str] nonce value from the request
         | 
| 72 73 | 
             
                  # @param [String, #to_str] timestamp value from the request
         | 
| 73 74 | 
             
                  # @return [Boolean] if the nonce/timestamp pair is valid.
         | 
| 74 | 
            -
                  def validate_nonce_timestamp | 
| 75 | 
            -
                     | 
| 76 | 
            -
                       | 
| 77 | 
            -
                        @nonce_timestamp. | 
| 75 | 
            +
                  def validate_nonce_timestamp nonce, timestamp
         | 
| 76 | 
            +
                    if @nonce_timestamp.respond_to? :call
         | 
| 77 | 
            +
                      nonce =
         | 
| 78 | 
            +
                        @nonce_timestamp.call nonce, timestamp
         | 
| 79 | 
            +
                    end
         | 
| 78 80 | 
             
                    nonce ? true : false
         | 
| 79 81 | 
             
                  end
         | 
| 80 82 |  | 
| @@ -84,8 +86,8 @@ module Signet | |
| 84 86 | 
             
                  #
         | 
| 85 87 | 
             
                  # @param [String] key provided to the {#client_credential} Proc.
         | 
| 86 88 | 
             
                  # @return [Signet::OAuth1::Credential] The client credential.
         | 
| 87 | 
            -
                  def find_client_credential | 
| 88 | 
            -
                    call_credential_lookup | 
| 89 | 
            +
                  def find_client_credential key
         | 
| 90 | 
            +
                    call_credential_lookup @client_credential, key
         | 
| 89 91 | 
             
                  end
         | 
| 90 92 |  | 
| 91 93 | 
             
                  ##
         | 
| @@ -94,8 +96,8 @@ module Signet | |
| 94 96 | 
             
                  #
         | 
| 95 97 | 
             
                  # @param [String] key provided to the {#token_credential} Proc.
         | 
| 96 98 | 
             
                  # @return [Signet::OAuth1::Credential] if the credential is found.
         | 
| 97 | 
            -
                  def find_token_credential | 
| 98 | 
            -
                    call_credential_lookup | 
| 99 | 
            +
                  def find_token_credential key
         | 
| 100 | 
            +
                    call_credential_lookup @token_credential, key
         | 
| 99 101 | 
             
                  end
         | 
| 100 102 |  | 
| 101 103 | 
             
                  ##
         | 
| @@ -104,8 +106,8 @@ module Signet | |
| 104 106 | 
             
                  #
         | 
| 105 107 | 
             
                  # @param [String] key provided to the {#temporary_credential} Proc.
         | 
| 106 108 | 
             
                  # @return [Signet::OAuth1::Credential] if the credential is found.
         | 
| 107 | 
            -
                  def find_temporary_credential | 
| 108 | 
            -
                    call_credential_lookup | 
| 109 | 
            +
                  def find_temporary_credential key
         | 
| 110 | 
            +
                    call_credential_lookup @temporary_credential, key
         | 
| 109 111 | 
             
                  end
         | 
| 110 112 |  | 
| 111 113 | 
             
                  ##
         | 
| @@ -115,17 +117,17 @@ module Signet | |
| 115 117 | 
             
                  # @param [String] key provided to the Proc in <code>credential</code>
         | 
| 116 118 | 
             
                  # @return [Signet::OAuth1::Credential] credential provided by
         | 
| 117 119 | 
             
                  #   <code>credential</code> (if any).
         | 
| 118 | 
            -
                  def call_credential_lookup | 
| 119 | 
            -
                    cred = credential.call | 
| 120 | 
            -
                            credential.respond_to? | 
| 120 | 
            +
                  def call_credential_lookup credential, key
         | 
| 121 | 
            +
                    cred = credential.call key if
         | 
| 122 | 
            +
                            credential.respond_to? :call
         | 
| 121 123 | 
             
                    return nil if cred.nil?
         | 
| 122 | 
            -
                    return nil unless  | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
                    if | 
| 124 | 
            +
                    return nil unless cred.respond_to?(:to_str) ||
         | 
| 125 | 
            +
                                      cred.respond_to?(:to_ary) ||
         | 
| 126 | 
            +
                                      cred.respond_to?(:to_hash)
         | 
| 127 | 
            +
                    if cred.instance_of? ::Signet::OAuth1::Credential
         | 
| 126 128 | 
             
                      cred
         | 
| 127 129 | 
             
                    else
         | 
| 128 | 
            -
                      ::Signet::OAuth1::Credential.new | 
| 130 | 
            +
                      ::Signet::OAuth1::Credential.new cred
         | 
| 129 131 | 
             
                    end
         | 
| 130 132 | 
             
                  end
         | 
| 131 133 |  | 
| @@ -135,11 +137,12 @@ module Signet | |
| 135 137 | 
             
                  # @param [String] verifier Key provided to the {#verifier} Proc.
         | 
| 136 138 | 
             
                  # @return [Boolean] if the verifier Proc returns anything other than
         | 
| 137 139 | 
             
                  #   <code>nil</code> or <code>false</code>.
         | 
| 138 | 
            -
                  def find_verifier | 
| 139 | 
            -
                    verified = @verifier.call | 
| 140 | 
            +
                  def find_verifier verifier
         | 
| 141 | 
            +
                    verified = @verifier.call verifier if @verifier.respond_to? :call
         | 
| 140 142 | 
             
                    verified ? true : false
         | 
| 141 143 | 
             
                  end
         | 
| 142 | 
            -
             | 
| 144 | 
            +
                  # rubocop:disable Metrics/MethodLength
         | 
| 145 | 
            +
                  # rubocop:disable Metrics/PerceivedComplexity
         | 
| 143 146 |  | 
| 144 147 | 
             
                  ##
         | 
| 145 148 | 
             
                  # Validate and normalize the components from an HTTP request.
         | 
| @@ -151,12 +154,12 @@ module Signet | |
| 151 154 | 
             
                  #   @param [StringIO, String] body The HTTP body.
         | 
| 152 155 | 
             
                  #   @param [HTTPAdapter] adapter The HTTP adapter(optional).
         | 
| 153 156 | 
             
                  # @return [Hash] normalized request components
         | 
| 154 | 
            -
                  def verify_request_components | 
| 157 | 
            +
                  def verify_request_components options = {}
         | 
| 155 158 | 
             
                    if options[:request]
         | 
| 156 | 
            -
                      if options[:request]. | 
| 159 | 
            +
                      if options[:request].is_a?(Faraday::Request) || options[:request].is_a?(Array)
         | 
| 157 160 | 
             
                        request = options[:request]
         | 
| 158 161 | 
             
                      elsif options[:adapter]
         | 
| 159 | 
            -
                        request = options[:adapter].adapt_request | 
| 162 | 
            +
                        request = options[:adapter].adapt_request options[:request]
         | 
| 160 163 | 
             
                      end
         | 
| 161 164 | 
             
                      method = request.method
         | 
| 162 165 | 
             
                      uri = request.path
         | 
| @@ -166,45 +169,43 @@ module Signet | |
| 166 169 | 
             
                      method = options[:method] || :get
         | 
| 167 170 | 
             
                      uri = options[:uri]
         | 
| 168 171 | 
             
                      headers = options[:headers] || []
         | 
| 169 | 
            -
                      body = options[:body] ||  | 
| 172 | 
            +
                      body = options[:body] || ""
         | 
| 170 173 | 
             
                    end
         | 
| 171 174 |  | 
| 172 | 
            -
                    headers = headers.to_a if headers. | 
| 175 | 
            +
                    headers = headers.to_a if headers.is_a? Hash
         | 
| 173 176 | 
             
                    method = method.to_s.upcase
         | 
| 174 177 |  | 
| 175 178 | 
             
                    request_components = {
         | 
| 176 | 
            -
                      :method | 
| 177 | 
            -
                      :uri | 
| 178 | 
            -
                      : | 
| 179 | 
            +
                      method:  method,
         | 
| 180 | 
            +
                      uri:     uri,
         | 
| 181 | 
            +
                      headers: headers
         | 
| 179 182 | 
             
                    }
         | 
| 180 183 |  | 
| 181 184 | 
             
                    # Verify that we have all the pieces required to validate the HTTP request
         | 
| 182 185 | 
             
                    request_components.each do |(key, value)|
         | 
| 183 | 
            -
                      unless value
         | 
| 184 | 
            -
                        raise ArgumentError, "Missing :#{key} parameter."
         | 
| 185 | 
            -
                      end
         | 
| 186 | 
            +
                      raise ArgumentError, "Missing :#{key} parameter." unless value
         | 
| 186 187 | 
             
                    end
         | 
| 187 188 | 
             
                    request_components[:body] = body
         | 
| 188 189 | 
             
                    request_components
         | 
| 189 190 | 
             
                  end
         | 
| 191 | 
            +
                  # rubocop:enable Metrics/MethodLength
         | 
| 192 | 
            +
                  # rubocop:enable Metrics/PerceivedComplexity
         | 
| 190 193 |  | 
| 191 194 | 
             
                  ##
         | 
| 192 195 | 
             
                  # Validate and normalize the HTTP Authorization header.
         | 
| 193 196 | 
             
                  #
         | 
| 194 197 | 
             
                  # @param [Array] headers from HTTP request.
         | 
| 195 198 | 
             
                  # @return [Hash] Hash of Authorization header.
         | 
| 196 | 
            -
                  def verify_auth_header_components | 
| 197 | 
            -
                    auth_header = headers.find{|x| x[0] ==  | 
| 198 | 
            -
                    if | 
| 199 | 
            -
                      raise MalformedAuthorizationError.new('Authorization header is missing')
         | 
| 200 | 
            -
                    end
         | 
| 199 | 
            +
                  def verify_auth_header_components headers
         | 
| 200 | 
            +
                    auth_header = headers.find { |x| x[0] == "Authorization" }
         | 
| 201 | 
            +
                    raise MalformedAuthorizationError, "Authorization header is missing" if auth_header.nil? || auth_header[1] == ""
         | 
| 201 202 | 
             
                    auth_hash = ::Signet::OAuth1.parse_authorization_header(
         | 
| 202 | 
            -
                      auth_header[1] | 
| 203 | 
            +
                      auth_header[1]
         | 
| 204 | 
            +
                    ).each_with_object({}) { |(key, val), acc| acc[key.downcase] = val; }
         | 
| 203 205 |  | 
| 204 206 | 
             
                    auth_hash
         | 
| 205 207 | 
             
                  end
         | 
| 206 208 |  | 
| 207 | 
            -
             | 
| 208 209 | 
             
                  ##
         | 
| 209 210 | 
             
                  # @overload request_realm(options)
         | 
| 210 211 | 
             
                  #   @param [Hash] request A pre-constructed request to verify.
         | 
| @@ -214,27 +215,31 @@ module Signet | |
| 214 215 | 
             
                  #   @param [StringIO, String] body The HTTP body.
         | 
| 215 216 | 
             
                  #   @param [HTTPAdapter] adapter The HTTP adapter(optional).
         | 
| 216 217 | 
             
                  # @return [String] The Authorization realm(see RFC 2617) of the request.
         | 
| 217 | 
            -
                  def request_realm | 
| 218 | 
            -
                    if | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 226 | 
            -
             | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 229 | 
            -
             | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            -
                     | 
| 218 | 
            +
                  def request_realm options = {}
         | 
| 219 | 
            +
                    request_components = if options[:request]
         | 
| 220 | 
            +
                                           verify_request_components(
         | 
| 221 | 
            +
                                             request: options[:request],
         | 
| 222 | 
            +
                                             adapter: options[:adapter]
         | 
| 223 | 
            +
                                           )
         | 
| 224 | 
            +
                                         else
         | 
| 225 | 
            +
                                           verify_request_components(
         | 
| 226 | 
            +
                                             method:  options[:method],
         | 
| 227 | 
            +
                                             uri:     options[:uri],
         | 
| 228 | 
            +
                                             headers: options[:headers],
         | 
| 229 | 
            +
                                             body:    options[:body]
         | 
| 230 | 
            +
                                           )
         | 
| 231 | 
            +
                                         end
         | 
| 232 | 
            +
             | 
| 233 | 
            +
                    auth_header = request_components[:headers].find { |x| x[0] == "Authorization" }
         | 
| 234 | 
            +
                    raise MalformedAuthorizationError, "Authorization header is missing" if auth_header.nil? || auth_header[1] == ""
         | 
| 234 235 | 
             
                    auth_hash = ::Signet::OAuth1.parse_authorization_header(
         | 
| 235 | 
            -
                      auth_header[1] | 
| 236 | 
            -
                     | 
| 236 | 
            +
                      auth_header[1]
         | 
| 237 | 
            +
                    ).each_with_object({}) { |(key, val), acc| acc[key.downcase] = val; }
         | 
| 238 | 
            +
                    auth_hash["realm"]
         | 
| 237 239 | 
             
                  end
         | 
| 240 | 
            +
                  # rubocop:disable Metrics/AbcSize
         | 
| 241 | 
            +
                  # rubocop:disable Metrics/MethodLength
         | 
| 242 | 
            +
                  # rubocop:disable Metrics/PerceivedComplexity
         | 
| 238 243 |  | 
| 239 244 | 
             
                  ##
         | 
| 240 245 | 
             
                  # Authenticates a temporary credential request. If no oauth_callback is
         | 
| @@ -248,60 +253,62 @@ module Signet | |
| 248 253 | 
             
                  #   @param [StringIO, String] body The HTTP body.
         | 
| 249 254 | 
             
                  #   @param [HTTPAdapter] adapter The HTTP adapter(optional).
         | 
| 250 255 | 
             
                  # @return [String] The oauth_callback value, or <code>false</code> if not valid.
         | 
| 251 | 
            -
                  def authenticate_temporary_credential_request | 
| 256 | 
            +
                  def authenticate_temporary_credential_request options = {}
         | 
| 252 257 | 
             
                    verifications = {
         | 
| 253 | 
            -
                      : | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
                        }
         | 
| 258 | 
            +
                      client_credential: lambda { |_x|
         | 
| 259 | 
            +
                                           ::Signet::OAuth1::Credential.new("Client credential key",
         | 
| 260 | 
            +
                                                                            "Client credential secret")
         | 
| 261 | 
            +
                                         }
         | 
| 258 262 | 
             
                    }
         | 
| 259 263 | 
             
                    verifications.each do |(key, _value)|
         | 
| 260 | 
            -
                      raise ArgumentError, "#{key} was not set." unless  | 
| 264 | 
            +
                      raise ArgumentError, "#{key} was not set." unless send key
         | 
| 261 265 | 
             
                    end
         | 
| 262 266 |  | 
| 263 | 
            -
                    if | 
| 264 | 
            -
             | 
| 265 | 
            -
             | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
             | 
| 271 | 
            -
             | 
| 272 | 
            -
             | 
| 267 | 
            +
                    request_components = if options[:request]
         | 
| 268 | 
            +
                                           verify_request_components(
         | 
| 269 | 
            +
                                             request: options[:request],
         | 
| 270 | 
            +
                                             adapter: options[:adapter]
         | 
| 271 | 
            +
                                           )
         | 
| 272 | 
            +
                                         else
         | 
| 273 | 
            +
                                           verify_request_components(
         | 
| 274 | 
            +
                                             method:  options[:method],
         | 
| 275 | 
            +
                                             uri:     options[:uri],
         | 
| 276 | 
            +
                                             headers: options[:headers]
         | 
| 277 | 
            +
                                           )
         | 
| 278 | 
            +
                                         end
         | 
| 273 279 | 
             
                    # body should be blank; we don't care in any case.
         | 
| 274 280 | 
             
                    method = request_components[:method]
         | 
| 275 281 | 
             
                    uri = request_components[:uri]
         | 
| 276 282 | 
             
                    headers = request_components[:headers]
         | 
| 277 283 |  | 
| 278 | 
            -
                    auth_hash = verify_auth_header_components | 
| 279 | 
            -
                    return false unless(client_credential = find_client_credential(
         | 
| 280 | 
            -
             | 
| 284 | 
            +
                    auth_hash = verify_auth_header_components headers
         | 
| 285 | 
            +
                    return false unless (client_credential = find_client_credential(
         | 
| 286 | 
            +
                      auth_hash["oauth_consumer_key"]
         | 
| 287 | 
            +
                    ))
         | 
| 281 288 |  | 
| 282 | 
            -
                    return false unless validate_nonce_timestamp(auth_hash[ | 
| 283 | 
            -
                                                                 auth_hash[ | 
| 289 | 
            +
                    return false unless validate_nonce_timestamp(auth_hash["oauth_nonce"],
         | 
| 290 | 
            +
                                                                 auth_hash["oauth_timestamp"])
         | 
| 284 291 | 
             
                    client_credential_secret = client_credential.secret if client_credential
         | 
| 285 292 |  | 
| 286 293 | 
             
                    computed_signature = ::Signet::OAuth1.sign_parameters(
         | 
| 287 294 | 
             
                      method,
         | 
| 288 295 | 
             
                      uri,
         | 
| 289 296 | 
             
                      # Realm isn't used, and will throw the signature off.
         | 
| 290 | 
            -
                      auth_hash.reject{|k, | 
| 297 | 
            +
                      auth_hash.reject { |k, _v| k == "realm" }.to_a,
         | 
| 291 298 | 
             
                      client_credential_secret,
         | 
| 292 299 | 
             
                      nil
         | 
| 293 300 | 
             
                    )
         | 
| 294 | 
            -
                    if safe_equals? | 
| 295 | 
            -
                      if | 
| 296 | 
            -
                         | 
| 301 | 
            +
                    if safe_equals? computed_signature, auth_hash["oauth_signature"]
         | 
| 302 | 
            +
                      if auth_hash.fetch("oauth_callback", "oob").empty?
         | 
| 303 | 
            +
                        "oob"
         | 
| 297 304 | 
             
                      else
         | 
| 298 | 
            -
                        auth_hash.fetch | 
| 305 | 
            +
                        auth_hash.fetch "oauth_callback"
         | 
| 299 306 | 
             
                      end
         | 
| 300 307 | 
             
                    else
         | 
| 301 308 | 
             
                      false
         | 
| 302 309 | 
             
                    end
         | 
| 303 310 | 
             
                  end
         | 
| 304 | 
            -
             | 
| 311 | 
            +
                  # rubocop:enable Metrics/PerceivedComplexity
         | 
| 305 312 |  | 
| 306 313 | 
             
                  ##
         | 
| 307 314 | 
             
                  # Authenticates a token credential request.
         | 
| @@ -314,70 +321,66 @@ module Signet | |
| 314 321 | 
             
                  #   @param [HTTPAdapter] adapter The HTTP adapter(optional).
         | 
| 315 322 | 
             
                  # @return [Hash] A hash of credentials and realm for a valid request,
         | 
| 316 323 | 
             
                  #   or <code>nil</code> if not valid.
         | 
| 317 | 
            -
                  def authenticate_token_credential_request | 
| 324 | 
            +
                  def authenticate_token_credential_request options = {}
         | 
| 318 325 | 
             
                    verifications = {
         | 
| 319 | 
            -
                      : | 
| 320 | 
            -
             | 
| 321 | 
            -
             | 
| 322 | 
            -
             | 
| 323 | 
            -
                      : | 
| 324 | 
            -
             | 
| 325 | 
            -
             | 
| 326 | 
            -
             | 
| 327 | 
            -
                      : | 
| 328 | 
            -
                        lambda {|x| 'Verifier' }
         | 
| 326 | 
            +
                      client_credential:    lambda { |_x|
         | 
| 327 | 
            +
                                              ::Signet::OAuth1::Credential.new("Client credential key",
         | 
| 328 | 
            +
                                                                               "Client credential secret")
         | 
| 329 | 
            +
                                            },
         | 
| 330 | 
            +
                      temporary_credential: lambda { |_x|
         | 
| 331 | 
            +
                                              ::Signet::OAuth1::Credential.new("Temporary credential key",
         | 
| 332 | 
            +
                                                                               "Temporary credential secret")
         | 
| 333 | 
            +
                                            },
         | 
| 334 | 
            +
                      verifier:             ->(_x) { "Verifier" }
         | 
| 329 335 | 
             
                    }
         | 
| 330 336 | 
             
                    verifications.each do |(key, _value)|
         | 
| 331 | 
            -
                      unless  | 
| 332 | 
            -
                        raise ArgumentError, "#{key} was not set."
         | 
| 333 | 
            -
                      end
         | 
| 334 | 
            -
                    end
         | 
| 335 | 
            -
                    if(options[:request])
         | 
| 336 | 
            -
                      request_components = verify_request_components(
         | 
| 337 | 
            -
                        :request=>options[:request],
         | 
| 338 | 
            -
                        :adapter=>options[:adapter]
         | 
| 339 | 
            -
                      )
         | 
| 340 | 
            -
                    else
         | 
| 341 | 
            -
                      request_components = verify_request_components(
         | 
| 342 | 
            -
                        :method=>options[:method],
         | 
| 343 | 
            -
                        :uri=>options[:uri],
         | 
| 344 | 
            -
                        :headers=>options[:headers],
         | 
| 345 | 
            -
                        :body=>options[:body]
         | 
| 346 | 
            -
                      )
         | 
| 337 | 
            +
                      raise ArgumentError, "#{key} was not set." unless send key
         | 
| 347 338 | 
             
                    end
         | 
| 339 | 
            +
                    request_components = if options[:request]
         | 
| 340 | 
            +
                                           verify_request_components(
         | 
| 341 | 
            +
                                             request: options[:request],
         | 
| 342 | 
            +
                                             adapter: options[:adapter]
         | 
| 343 | 
            +
                                           )
         | 
| 344 | 
            +
                                         else
         | 
| 345 | 
            +
                                           verify_request_components(
         | 
| 346 | 
            +
                                             method:  options[:method],
         | 
| 347 | 
            +
                                             uri:     options[:uri],
         | 
| 348 | 
            +
                                             headers: options[:headers],
         | 
| 349 | 
            +
                                             body:    options[:body]
         | 
| 350 | 
            +
                                           )
         | 
| 351 | 
            +
                                         end
         | 
| 348 352 | 
             
                    # body should be blank; we don't care in any case.
         | 
| 349 353 | 
             
                    method = request_components[:method]
         | 
| 350 354 | 
             
                    uri = request_components[:uri]
         | 
| 351 355 | 
             
                    headers = request_components[:headers]
         | 
| 352 356 |  | 
| 353 | 
            -
                    auth_hash = verify_auth_header_components | 
| 354 | 
            -
                    return false unless(
         | 
| 355 | 
            -
                      client_credential = find_client_credential | 
| 357 | 
            +
                    auth_hash = verify_auth_header_components headers
         | 
| 358 | 
            +
                    return false unless (
         | 
| 359 | 
            +
                      client_credential = find_client_credential auth_hash["oauth_consumer_key"]
         | 
| 356 360 | 
             
                    )
         | 
| 357 | 
            -
                    return false unless(
         | 
| 358 | 
            -
                      temporary_credential = find_temporary_credential | 
| 361 | 
            +
                    return false unless (
         | 
| 362 | 
            +
                      temporary_credential = find_temporary_credential auth_hash["oauth_token"]
         | 
| 359 363 | 
             
                    )
         | 
| 360 364 | 
             
                    return false unless validate_nonce_timestamp(
         | 
| 361 | 
            -
                      auth_hash[ | 
| 365 | 
            +
                      auth_hash["oauth_nonce"], auth_hash["oauth_timestamp"]
         | 
| 366 | 
            +
                    )
         | 
| 362 367 |  | 
| 363 368 | 
             
                    computed_signature = ::Signet::OAuth1.sign_parameters(
         | 
| 364 369 | 
             
                      method,
         | 
| 365 370 | 
             
                      uri,
         | 
| 366 371 | 
             
                      # Realm isn't used, and will throw the signature off.
         | 
| 367 | 
            -
                      auth_hash.reject{|k, | 
| 372 | 
            +
                      auth_hash.reject { |k, _v| k == "realm" }.to_a,
         | 
| 368 373 | 
             
                      client_credential.secret,
         | 
| 369 374 | 
             
                      temporary_credential.secret
         | 
| 370 375 | 
             
                    )
         | 
| 371 376 |  | 
| 372 | 
            -
                     | 
| 373 | 
            -
             | 
| 374 | 
            -
             | 
| 375 | 
            -
             | 
| 376 | 
            -
                      }
         | 
| 377 | 
            -
                    else
         | 
| 378 | 
            -
                      nil
         | 
| 379 | 
            -
                    end
         | 
| 377 | 
            +
                    return nil unless safe_equals? computed_signature, auth_hash["oauth_signature"]
         | 
| 378 | 
            +
                    { client_credential:    client_credential,
         | 
| 379 | 
            +
                      temporary_credential: temporary_credential,
         | 
| 380 | 
            +
                      realm:                auth_hash["realm"] }
         | 
| 380 381 | 
             
                  end
         | 
| 382 | 
            +
                  # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 383 | 
            +
                  # rubocop:disable Metrics/PerceivedComplexity
         | 
| 381 384 |  | 
| 382 385 | 
             
                  ##
         | 
| 383 386 | 
             
                  # Authenticates a request for a protected resource.
         | 
| @@ -392,96 +395,88 @@ module Signet | |
| 392 395 | 
             
                  #
         | 
| 393 396 | 
             
                  # @return [Hash] A hash of the credentials and realm for a valid request,
         | 
| 394 397 | 
             
                  #   or <code>nil</code> if not valid.
         | 
| 395 | 
            -
                  def authenticate_resource_request | 
| 398 | 
            +
                  def authenticate_resource_request options = {}
         | 
| 396 399 | 
             
                    verifications = {
         | 
| 397 | 
            -
                      : | 
| 398 | 
            -
             | 
| 399 | 
            -
             | 
| 400 | 
            -
             | 
| 401 | 
            -
                        end
         | 
| 400 | 
            +
                      client_credential: lambda do |_x|
         | 
| 401 | 
            +
                                           ::Signet::OAuth1::Credential.new("Client credential key",
         | 
| 402 | 
            +
                                                                            "Client credential secret")
         | 
| 403 | 
            +
                                         end
         | 
| 402 404 | 
             
                    }
         | 
| 403 405 |  | 
| 404 | 
            -
                    unless | 
| 406 | 
            +
                    unless options[:two_legged] == true
         | 
| 405 407 | 
             
                      verifications.update(
         | 
| 406 | 
            -
                        : | 
| 407 | 
            -
             | 
| 408 | 
            -
             | 
| 409 | 
            -
             | 
| 410 | 
            -
                          end
         | 
| 408 | 
            +
                        token_credential: lambda do |_x|
         | 
| 409 | 
            +
                                            ::Signet::OAuth1::Credential.new("Token credential key",
         | 
| 410 | 
            +
                                                                             "Token credential secret")
         | 
| 411 | 
            +
                                          end
         | 
| 411 412 | 
             
                      )
         | 
| 412 413 | 
             
                    end
         | 
| 413 414 | 
             
                    # Make sure all required state is set
         | 
| 414 415 | 
             
                    verifications.each do |(key, _value)|
         | 
| 415 | 
            -
                      unless  | 
| 416 | 
            -
                        raise ArgumentError, "#{key} was not set."
         | 
| 417 | 
            -
                      end
         | 
| 416 | 
            +
                      raise ArgumentError, "#{key} was not set." unless send key
         | 
| 418 417 | 
             
                    end
         | 
| 419 418 |  | 
| 420 | 
            -
                    if | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
             | 
| 425 | 
            -
             | 
| 426 | 
            -
             | 
| 427 | 
            -
             | 
| 428 | 
            -
             | 
| 429 | 
            -
             | 
| 430 | 
            -
             | 
| 419 | 
            +
                    request_components = if options[:request]
         | 
| 420 | 
            +
                                           verify_request_components(
         | 
| 421 | 
            +
                                             request: options[:request],
         | 
| 422 | 
            +
                                             adapter: options[:adapter]
         | 
| 423 | 
            +
                                           )
         | 
| 424 | 
            +
                                         else
         | 
| 425 | 
            +
                                           verify_request_components(
         | 
| 426 | 
            +
                                             method:  options[:method],
         | 
| 427 | 
            +
                                             uri:     options[:uri],
         | 
| 428 | 
            +
                                             headers: options[:headers],
         | 
| 429 | 
            +
                                             body:    options[:body]
         | 
| 430 | 
            +
                                           )
         | 
| 431 | 
            +
                                         end
         | 
| 431 432 | 
             
                    method = request_components[:method]
         | 
| 432 433 | 
             
                    uri = request_components[:uri]
         | 
| 433 434 | 
             
                    headers = request_components[:headers]
         | 
| 434 435 | 
             
                    body = request_components[:body]
         | 
| 435 436 |  | 
| 436 437 |  | 
| 437 | 
            -
                    if !body. | 
| 438 | 
            +
                    if !body.is_a?(String) && body.respond_to?(:each)
         | 
| 438 439 | 
             
                      # Just in case we get a chunked body
         | 
| 439 440 | 
             
                      merged_body = StringIO.new
         | 
| 440 441 | 
             
                      body.each do |chunk|
         | 
| 441 | 
            -
                        merged_body.write | 
| 442 | 
            +
                        merged_body.write chunk
         | 
| 442 443 | 
             
                      end
         | 
| 443 444 | 
             
                      body = merged_body.string
         | 
| 444 445 | 
             
                    end
         | 
| 445 | 
            -
                     | 
| 446 | 
            -
                      raise TypeError, "Expected String, got #{body.class}."
         | 
| 447 | 
            -
                    end
         | 
| 446 | 
            +
                    raise TypeError, "Expected String, got #{body.class}." unless body.is_a? String
         | 
| 448 447 |  | 
| 449 448 | 
             
                    media_type = nil
         | 
| 450 449 | 
             
                    headers.each do |(header, value)|
         | 
| 451 | 
            -
                      if header. | 
| 452 | 
            -
                        media_type = value.gsub(/^([^;]+)(;.*?)?$/, '\1')
         | 
| 453 | 
            -
                      end
         | 
| 450 | 
            +
                      media_type = value.gsub(/^([^;]+)(;.*?)?$/, '\1') if header.casecmp("Content-Type").zero?
         | 
| 454 451 | 
             
                    end
         | 
| 455 452 |  | 
| 456 | 
            -
                    auth_hash = verify_auth_header_components | 
| 453 | 
            +
                    auth_hash = verify_auth_header_components headers
         | 
| 457 454 |  | 
| 458 | 
            -
                    auth_token = auth_hash[ | 
| 455 | 
            +
                    auth_token = auth_hash["oauth_token"]
         | 
| 459 456 |  | 
| 460 457 |  | 
| 461 | 
            -
                    unless | 
| 462 | 
            -
                      return nil if | 
| 463 | 
            -
                      return nil unless(token_credential = find_token_credential | 
| 458 | 
            +
                    unless options[:two_legged]
         | 
| 459 | 
            +
                      return nil if auth_token.nil?
         | 
| 460 | 
            +
                      return nil unless (token_credential = find_token_credential auth_token)
         | 
| 464 461 | 
             
                      token_credential_secret = token_credential.secret if token_credential
         | 
| 465 462 | 
             
                    end
         | 
| 466 463 |  | 
| 467 | 
            -
                    return nil unless(client_credential =
         | 
| 468 | 
            -
             | 
| 464 | 
            +
                    return nil unless (client_credential =
         | 
| 465 | 
            +
                                         find_client_credential auth_hash["oauth_consumer_key"])
         | 
| 469 466 |  | 
| 470 | 
            -
                    return nil unless validate_nonce_timestamp(auth_hash[ | 
| 471 | 
            -
             | 
| 467 | 
            +
                    return nil unless validate_nonce_timestamp(auth_hash["oauth_nonce"],
         | 
| 468 | 
            +
                                                               auth_hash["oauth_timestamp"])
         | 
| 472 469 |  | 
| 473 | 
            -
                    if | 
| 474 | 
            -
                       media_type ==  | 
| 470 | 
            +
                    if method == ("POST" || "PUT") &&
         | 
| 471 | 
            +
                       media_type == "application/x-www-form-urlencoded"
         | 
| 475 472 | 
             
                      request_components[:body] = body
         | 
| 476 | 
            -
                      post_parameters = Addressable::URI.form_unencode | 
| 477 | 
            -
                      post_parameters.each {|param| param[1] = "" if param[1].nil?}
         | 
| 473 | 
            +
                      post_parameters = Addressable::URI.form_unencode body
         | 
| 474 | 
            +
                      post_parameters.each { |param| param[1] = "" if param[1].nil? }
         | 
| 478 475 | 
             
                      # If the auth header doesn't have the same params as the body, it
         | 
| 479 476 | 
             
                      # can't have been signed correctly(5849#3.4.1.3)
         | 
| 480 | 
            -
                      unless | 
| 481 | 
            -
                        raise MalformedAuthorizationError | 
| 482 | 
            -
                           | 
| 483 | 
            -
                          'but Authentication header did not include form values'
         | 
| 484 | 
            -
                                                             )
         | 
| 477 | 
            +
                      unless post_parameters.sort == auth_hash.reject { |k, _v| k.index "oauth_" }.to_a.sort
         | 
| 478 | 
            +
                        raise MalformedAuthorizationError, "Request is of type application/x-www-form-urlencoded " \
         | 
| 479 | 
            +
                          "but Authentication header did not include form values"
         | 
| 485 480 | 
             
                      end
         | 
| 486 481 | 
             
                    end
         | 
| 487 482 |  | 
| @@ -491,21 +486,20 @@ module Signet | |
| 491 486 | 
             
                      method,
         | 
| 492 487 | 
             
                      uri,
         | 
| 493 488 | 
             
                      # Realm isn't used, and will throw the signature off.
         | 
| 494 | 
            -
                      auth_hash.reject{|k, | 
| 489 | 
            +
                      auth_hash.reject { |k, _v| k == "realm" }.to_a,
         | 
| 495 490 | 
             
                      client_credential_secret,
         | 
| 496 491 | 
             
                      token_credential_secret
         | 
| 497 492 | 
             
                    )
         | 
| 498 493 |  | 
| 499 | 
            -
                     | 
| 500 | 
            -
             | 
| 501 | 
            -
             | 
| 502 | 
            -
             | 
| 503 | 
            -
                      }
         | 
| 504 | 
            -
                    else
         | 
| 505 | 
            -
                      nil
         | 
| 506 | 
            -
                    end
         | 
| 494 | 
            +
                    return nil unless safe_equals? computed_signature, auth_hash["oauth_signature"]
         | 
| 495 | 
            +
                    { client_credential: client_credential,
         | 
| 496 | 
            +
                      token_credential:  token_credential,
         | 
| 497 | 
            +
                      realm:             auth_hash["realm"] }
         | 
| 507 498 | 
             
                  end
         | 
| 508 | 
            -
             | 
| 499 | 
            +
                  # rubocop:enable Metrics/AbcSize
         | 
| 500 | 
            +
                  # rubocop:enable Metrics/CyclomaticComplexity
         | 
| 501 | 
            +
                  # rubocop:enable Metrics/MethodLength
         | 
| 502 | 
            +
                  # rubocop:enable Metrics/PerceivedComplexity
         | 
| 509 503 | 
             
                end
         | 
| 510 504 | 
             
              end
         | 
| 511 505 | 
             
            end
         |