lib/vidibus/secure.rb in vidibus-secure-0.0.4 vs lib/vidibus/secure.rb in vidibus-secure-0.1.0

- old
+ new

@@ -1,14 +1,11 @@ -require "openssl" -require "active_support/secure_random" -require "rack" -require "uri" - module Vidibus module Secure - class KeyError < StandardError; end + class Error < StandardError; end + class KeyError < Error; end + class InputError < Error; end class << self # Define default settings for random, sign, and crypt. def settings @@ -47,41 +44,53 @@ # Encrypts given data with given key. def encrypt(data, key, options = {}) raise KeyError.new("Please provide a secret key to encrypt data with.") unless key options = settings[:crypt].merge(options) + unless data.is_a?(String) + data = JSON.generate(data) + end encrypted_data = crypt(:encrypt, data, key, options) encode(encrypted_data, options) end # Decrypts given data with given key. def decrypt(data, key, options = {}) raise KeyError.new("Please provide a secret key to decrypt data with.") unless key options = settings[:crypt].merge(options) decoded_data = decode(data, options) - crypt(:decrypt, decoded_data, key, options) + decrypted_data = crypt(:decrypt, decoded_data, key, options) + begin + JSON.parse(decrypted_data) + rescue JSON::ParserError + decrypted_data + end end # Signs request. def sign_request(verb, path, params, key, signature_param = nil) default_signature_param = :sign params_given = !!params - raise ArgumentError.new("Given params is not a Hash.") if params_given and !params.is_a?(Hash) + raise InputError.new("Given params is not a Hash.") if params_given and !params.is_a?(Hash) params = {} unless params_given signature_param ||= (params_given and params.keys.first.is_a?(String)) ? default_signature_param.to_s : default_signature_param uri = URI.parse(path) path_params = Rack::Utils.parse_query(uri.query) uri.query = nil _verb = verb.to_s.downcase - _uri = uri.to_s.gsub(/\/+$/, "") _params = (params.merge(path_params)).except(signature_param.to_s, signature_param.to_s.to_sym) - _params = _params.any? ? _params.to_a_rec.flatten.sort{|a,b| a.to_s <=> b.to_s}.join("|") : "" - signature = sign("#{_verb}|#{_uri}|#{_params}", key) + signature_string = [ + _verb, + uri.to_s.gsub(/\/+$/, ""), + _params.any? ? params_identifier(_params) : "" + ].join("|") + signature = sign(signature_string, key) + if %w[post put].include?(_verb) or (params_given and path_params.empty?) params[signature_param] = signature else unless path.gsub!(/(#{signature_param}=)[^&]+/, "\\1#{signature}") glue = path.match(/\?/) ? "&" : "?" @@ -123,9 +132,26 @@ if options[:encoding] == :hex [data].pack("H*") elsif options[:encoding] == :base64 data.unpack("m*").to_s end + end + + # Returns an identifier string from given params input. + # + # Example: + # {:some=>{:nested=>{:really=>["serious", "stuff"]}, :are=>"params"}} + # # => 1:some:2:are:params|2:nested:3:really:4:serious:|4:stuff: + # + def params_identifier(params, level = 1) + array = [] + for key, value in params + if [Array, Hash].include?(value.class) + value = params_identifier(value, level + 1) + end + array << "#{level}:#{key}:#{value}" + end + array.sort.join("|") end end end end