Module: OAuth::Helper — Documentation by YARD 0.9.45

# Module: OAuth::Helper

Included in:
  Net::HTTPGenericRequest, Client::Helper, RequestProxy::Base, Server, Signature::Base, Token

Defined in:
  lib/oauth/helper.rb

## Class Method Summary collapse

- ._escape(string) ⇒ Object
- .escape(value) ⇒ Object

  Escape +value+ by URL encoding all non-reserved character.

- .generate_key(size = 32) ⇒ Object (also: generate_nonce)

  Generate a random key of up to +size+ bytes.

- .generate_timestamp ⇒ Object

  :nodoc:.

- .normalize(params) ⇒ Object

  Normalize a +Hash+ of parameter values.

- .normalize_nested_query(value, prefix = nil) ⇒ Object

  Returns a string representation of the Hash like in URL query string build_nested_query(=> {:level_2 => [‘value_1’,’value_2’]}, ‘prefix’)) #=> [“prefix%5Blevel_1%5D%5Blevel_2%5D%5B%5D=value_1”, “prefix%5Blevel_1%5D%5Blevel_2%5D%5B%5D=value_2”].

- .parse_header(header) ⇒ Object

  Parse an Authorization / WWW-Authenticate header into a hash.

- .stringify_keys(hash) ⇒ Object
- .unescape(value) ⇒ Object

## Class Method Details

### ._escape(string) ⇒ `Object`

    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    # File 'lib/oauth/helper.rb', line 20

    def _escape(string)
      # Percent-encode per RFC 3986 (unreserved: A-Z a-z 0-9 - . _ ~)
      # Encode by byte to ensure stable behavior across Ruby versions and encodings.
      bytes = string.to_s.b.bytes
      bytes.map do |b|
        ch = b.chr
        if ch =~ OAuth::RESERVED_CHARACTERS
          "%%%02X" % b
        else
          ch
        end
      end.join
    end

### .escape(value) ⇒ `Object`

Escape +value+ by URL encoding all non-reserved character.

See Also: core spec version 1.0, section 5.1[http://oauth.net/core/1.0#rfc.section.5.1]

    14
    15
    16
    17
    18
    # File 'lib/oauth/helper.rb', line 14

    def escape(value)
      _escape(value.to_s.to_str)
    rescue ArgumentError
      _escape(value.to_s.to_str.force_encoding(Encoding::UTF_8))
    end

### .generate_key(size = 32) ⇒ `Object` Also known as: generate_nonce

Generate a random key of up to +size+ bytes. The value returned is Base64 encoded with non-word
characters removed.

    52
    53
    54
    # File 'lib/oauth/helper.rb', line 52

    def generate_key(size = 32)
      Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/, "")
    end

### .generate_timestamp ⇒ `Object`

:nodoc:

    58
    59
    60
    # File 'lib/oauth/helper.rb', line 58

    def generate_timestamp # :nodoc:
      Time.now.to_i.to_s
    end

### .normalize(params) ⇒ `Object`

Normalize a +Hash+ of parameter values. Parameters are sorted by name, using lexicographical
byte value ordering. If two or more parameters share the same name, they are sorted by their value.
Parameters are concatenated in their sorted order into a single string. For each parameter, the name
is separated from the corresponding value by an “=” character, even if the value is empty. Each
name-value pair is separated by an “&” character.

See Also: core spec version 1.0, section 9.1.1[http://oauth.net/core/1.0#rfc.section.9.1.1]

    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    # File 'lib/oauth/helper.rb', line 69

    def normalize(params)
      params.sort.map do |k, values|
        case values
        when Array
          # make sure the array has an element so we don't lose the key
          values << nil if values.empty?
          # multiple values were provided for a single key
          if values[0].is_a?(Hash)
            normalize_nested_query(values, k)
          else
            values.sort.collect do |v|
              [escape(k), escape(v)].join("=")
            end
          end
        when Hash
          normalize_nested_query(values, k)
        else
          [escape(k), escape(values)].join("=")
        end
      end * "&"
    end

### .normalize_nested_query(value, prefix = nil) ⇒ `Object`

Returns a string representation of the Hash like in URL query string
build_nested_query(=> {:level_2 => [‘value_1’,’value_2’]}, ‘prefix’))
#=> [“prefix%5Blevel_1%5D%5Blevel_2%5D%5B%5D=value_1”, “prefix%5Blevel_1%5D%5Blevel_2%5D%5B%5D=value_2”]

    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    # File 'lib/oauth/helper.rb', line 94

    def normalize_nested_query(value, prefix = nil)
      case value
      when Array
        value.map do |v|
          normalize_nested_query(v, "#{prefix}[]")
        end.flatten.sort
      when Hash
        value.map do |k, v|
          normalize_nested_query(v, prefix ? "#{prefix}[#{k}]" : k)
        end.flatten.sort
      else
        [escape(prefix), escape(value)].join("=")
      end
    end

### .parse_header(header) ⇒ `Object`

Parse an Authorization / WWW-Authenticate header into a hash. Takes care of unescaping and
removing surrounding quotes. Raises a OAuth::Problem if the header is not parsable into a
valid hash. Does not validate the keys or values.

hash = parse_header(headers[‘Authorization’] || headers[‘WWW-Authenticate’])
hash[‘oauth_timestamp’]
#=>”1234567890”

Raises:

- (`OAuth::Problem`)

    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    # File 'lib/oauth/helper.rb', line 117

    def parse_header(header)
      # decompose
      params = header[6, header.length].split(/[,=&]/)

      # odd number of arguments - must be a malformed header.
      raise OAuth::Problem, "Invalid authorization header" if params.size.odd?

      params.map! do |v|
        # strip and unescape
        val = unescape(v.strip)
        # strip quotes
        val.sub(/^"(.*)"$/, '\1')
      end

      # convert into a Hash
      Hash[*params.flatten]
    end

### .stringify_keys(hash) ⇒ `Object`

    135
    136
    137
    138
    139
    140
    141
    # File 'lib/oauth/helper.rb', line 135

    def stringify_keys(hash)
      new_h = {}
      hash.each do |k, v|
        new_h[k.to_s] = v.is_a?(Hash) ? stringify_keys(v) : v
      end
      new_h
    end

### .unescape(value) ⇒ `Object`

    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    # File 'lib/oauth/helper.rb', line 34

    def unescape(value)
      # Do NOT treat "+" as space; OAuth treats '+' as a literal plus unless percent-encoded.
      str = value.to_s.gsub("+", "%2B")
      # Decode %HH sequences; leave malformed sequences intact.
      decoded = str.gsub(/%([0-9A-Fa-f]{2})/) { Regexp.last_match(1).to_i(16).chr }
      # Prefer UTF-8 when the decoded bytes form valid UTF-8; otherwise, return as binary.
      begin
        utf8 = decoded.dup
        utf8.force_encoding(Encoding::UTF_8)
        decoded = utf8 if utf8.valid_encoding?
      rescue NameError
        # Older Rubies without Encoding constants: keep original encoding.
      end
      decoded
    end