Module: Vidibus::Secure

Defined in:
lib/vidibus/secure.rb,
lib/vidibus/secure/mongoid.rb,
lib/vidibus/secure/version.rb,
lib/vidibus/secure/extensions/controller.rb

Defined Under Namespace

Modules: Extensions, Mongoid Classes: Error, InputError, KeyError

Constant Summary collapse

VERSION =
'0.3.1'

Class Method Summary collapse

Class Method Details

.decrypt(data, key, options = {}) ⇒ Object

Decrypts given data with given key.

Raises:



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/vidibus/secure.rb', line 57

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)
  decrypted_data = crypt(:decrypt, decoded_data, key, options)
  return data unless decrypted_data
  begin
    JSON.parse(decrypted_data)
  rescue JSON::ParserError
    decrypted_data
  end
end

.encrypt(data, key, options = {}) ⇒ Object

Encrypts given data with given key.

Raises:



46
47
48
49
50
51
52
53
54
# File 'lib/vidibus/secure.rb', line 46

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

.random(options = {}) ⇒ Object

Returns a truly random string. Now it is not much more than an interface for Ruby’s SecureRandom, but that might change over time.

Options:

:length     Length of string to generate
:encoding   Encoding of string; hex or base64

Keep in mind that a hexadecimal string is less secure than a base64 encoded string with the same length!



30
31
32
33
34
# File 'lib/vidibus/secure.rb', line 30

def random(options = {})
  options = settings[:random].merge(options)
  length = options[:length]
  SecureRandom.send(options[:encoding], length)[0,length]
end

.settingsObject

Define default settings for random, sign, and crypt.



11
12
13
14
15
16
17
# File 'lib/vidibus/secure.rb', line 11

def settings
  @settings ||= {
    :random => { :length => 50, :encoding => :base64 },
    :sign => { :algorithm => "SHA256", :encoding => :hex },
    :crypt => { :algorithm => "AES-256-CBC", :encoding => :base64 }
  }
end

.sign(data, key, options = {}) ⇒ Object

Returns signature of given data with given key.

Raises:



37
38
39
40
41
42
43
# File 'lib/vidibus/secure.rb', line 37

def sign(data, key, options = {})
  raise KeyError.new("Please provide a secret key to sign data with.") unless key
  options = settings[:sign].merge(options)
  digest = OpenSSL::Digest.new(options[:algorithm])
  signature = OpenSSL::HMAC.digest(digest, key, data)
  encode(signature, options)
end

.sign_request(verb, path, params, key, signature_param = nil) ⇒ Object

Signs request.

Raises:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/vidibus/secure.rb', line 71

def sign_request(verb, path, params, key, signature_param = nil)
  default_signature_param = :sign
  params_given = !!params
  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_nested_query(uri.query)
  uri.query = nil

  _verb = verb.to_s.downcase
  _params = (params.merge(path_params)).except(signature_param.to_s, signature_param.to_s.to_sym)

  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(/\?/) ? "&" : "?"
      path << "#{glue}#{signature_param}=#{signature}"
    end
  end
  [path, params]
end

.verify_request(verb, path, params, key, signature_param = nil) ⇒ Object

Verifies that given request is valid.



105
106
107
108
109
110
111
# File 'lib/vidibus/secure.rb', line 105

def verify_request(verb, path, params, key, signature_param = nil)
  params ||= {}
  _path = path.dup
  _params = params.dup
  sign_request(verb, _path, _params, key, signature_param)
  return (path == _path and params == _params)
end