Module: GoCardless::Utils

Extended by:
Utils
Included in:
Utils
Defined in:
lib/gocardless/utils.rb

Instance Method Summary collapse

Instance Method Details

#camelize(str) ⇒ Object

String Helpers



8
9
10
# File 'lib/gocardless/utils.rb', line 8

def camelize(str)
  str.split('_').map(&:capitalize).join
end

#flatten_params(obj, ns = nil) ⇒ Array

Flatten a hash containing nested hashes and arrays to a non-nested array of key-value pairs.

Examples:

flatten_params(a: 'b')
# => [['a', 'b']]

flatten_params(a: ['b', 'c'])
# => [['a[]', 'b'], ['a[]', 'c']]

flatten_params(a: {b: 'c'})
# => [['a[b]', 'c']]

Parameters:

  • obj (Hash) —

    the hash to flatten

Returns:

  • (Array) —

    an array of key-value pairs (arrays of two strings)



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/gocardless/utils.rb', line 58

def flatten_params(obj, ns=nil)
  case obj
  when Hash
    pairs = obj.map { |k,v| flatten_params(v, ns ? "#{ns}[#{k}]" : k) }
    pairs.empty? ? [] : pairs.inject(&:+)
  when Array
    obj.map { |v| flatten_params(v, "#{ns}[]") }.inject(&:+)
  when Time
    [[ns.to_s, iso_format_time(obj)]]
  else
    [[ns.to_s, obj.to_s]]
  end
end

#iso_format_time(time) ⇒ String

Format a Time object according to ISO 8601, and convert to UTC.

Parameters:

  • time (Time) —

    the time object to format

Returns:

  • (String) —

    the ISO-formatted time



101
102
103
104
105
106
# File 'lib/gocardless/utils.rb', line 101

def iso_format_time(time)
  return time unless time.is_a? Time or time.is_a? Date
  time = time.getutc if time.is_a? Time
  time = time.new_offset(0) if time.is_a? DateTime
  time.strftime('%Y-%m-%dT%H:%M:%SZ')
end

#normalize_params(params) ⇒ Object

Generate a percent-encoded query string from an object. The object may have nested arrays and objects as values. Ordinary top-level key-value pairs will be of the form "name=Bob", arrays will result in "cars=BMW&cars=Fiat", and nested objects will look like "user=Bob&user=50". All keys and values will be percent-encoded according to RFC5849 §3.6 and parameters will be normalised according to RFC5849 §3.4.1.3.2.



79
80
81
82
83
# File 'lib/gocardless/utils.rb', line 79

def normalize_params(params)
  flatten_params(params).sort.map do |pair|
    pair.map { |item| percent_encode(item) } * '='
  end * '&'
end

#percent_encode(str) ⇒ String

Percent encode a string according to RFC 5849 (section 3.6)

Parameters:

  • str (String) —

    the string to encode

Returns:

  • (String) —

    str the encoded string



38
39
40
# File 'lib/gocardless/utils.rb', line 38

def percent_encode(str)
  URI.encode(str, /[^a-zA-Z0-9\-\.\_\~]/)
end

#sign_params(params, key) ⇒ String

Given a Hash of parameters, normalize then (flatten and convert to a string), then generate the HMAC-SHA-256 signature using the provided key.

Parameters:

  • params (Hash) —

    the parameters to sign

  • key (String) —

    the key to sign the params with

Returns:

  • (String) —

    the resulting signature



91
92
93
94
95
# File 'lib/gocardless/utils.rb', line 91

def sign_params(params, key)
  msg = Utils.normalize_params(params)
  digest = OpenSSL::Digest::Digest.new('sha256')
  OpenSSL::HMAC.hexdigest(digest, key, msg)
end

#singularize(str) ⇒ Object



16
17
18
19
# File 'lib/gocardless/utils.rb', line 16

def singularize(str)
  # This should probably be a bit more robust
  str.sub(/s$/, '').sub(/i$/, 'us')
end

#stringify_times(obj) ⇒ Hash

Recursively ISO format all time and date values.

Parameters:

  • obj (Hash) —

    the object containing date or time objects

Returns:

  • (Hash) —

    the object with ISO-formatted time stings



112
113
114
115
116
117
118
119
120
121
# File 'lib/gocardless/utils.rb', line 112

def stringify_times(obj)
  case obj
  when Hash
    Hash[obj.map { |k,v| [k, stringify_times(v)] }]
  when Array
    obj.map { |v| stringify_times(v) }
  else
    iso_format_time(obj)
  end
end

#symbolize_keys(hash) ⇒ Object

Hash Helpers



22
23
24
# File 'lib/gocardless/utils.rb', line 22

def symbolize_keys(hash)
  symbolize_keys! hash.dup
end

#symbolize_keys!(hash) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/gocardless/utils.rb', line 26

def symbolize_keys!(hash)
  hash.keys.each do |key|
    sym_key = key.to_s.to_sym rescue key
    hash[sym_key] = hash.delete(key) unless hash.key?(sym_key)
  end
  hash
end

#underscore(str) ⇒ Object



12
13
14
# File 'lib/gocardless/utils.rb', line 12

def underscore(str)
  str.gsub(/(.)([A-Z])/) { "#{$1}_#{$2.downcase}" }.downcase
end