Module: Privy::Authorization::Canonicalization
- Defined in:
- lib/privy/authorization/canonicalization.rb
Class Method Summary collapse
- .canonicalize(value) ⇒ Object
- .coerce_keys(value) ⇒ Object
-
.format_number(value) ⇒ Object
TODO: port the ES6 ToString algorithm (ecma-262) for full RFC 8785 compliance on arbitrary floats.
- .serialize(value) ⇒ Object
Class Method Details
.canonicalize(value) ⇒ Object
10 11 12 |
# File 'lib/privy/authorization/canonicalization.rb', line 10 def canonicalize(value) serialize(coerce_keys(value)) end |
.coerce_keys(value) ⇒ Object
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/privy/authorization/canonicalization.rb', line 14 def coerce_keys(value) case value when Hash value.each_with_object({}) { |(k, v), h| h[k.to_s] = coerce_keys(v) } when Array value.map { |v| coerce_keys(v) } else value end end |
.format_number(value) ⇒ Object
TODO: port the ES6 ToString algorithm (ecma-262) for full RFC 8785 compliance on arbitrary floats. MVP payloads only contain integer and simple-decimal values, so the simplified form below is sufficient for now.
50 51 52 53 |
# File 'lib/privy/authorization/canonicalization.rb', line 50 def format_number(value) int = value.to_i value == int ? int.to_s : value.to_s end |
.serialize(value) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/privy/authorization/canonicalization.rb', line 25 def serialize(value) case value when Hash body = value.keys.sort_by { |k| k.encode("UTF-16BE").bytes } .map { |k| "#{JSON.generate(k)}:#{serialize(value[k])}" } .join(",") "{#{body}}" when Array "[#{value.map { |v| serialize(v) }.join(',')}]" when Float raise ArgumentError, "NaN/Infinity not permitted" unless value.finite? format_number(value) when Integer value.to_s when String, TrueClass, FalseClass, NilClass JSON.generate(value) else raise ArgumentError, "Cannot canonicalize #{value.class}" end end |