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