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

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: OAuth core spec version 1.0, 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_timestampObject

: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: OAuth core spec version 1.0, 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:



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