vidibus-secure 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.bundle/config +2 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +100 -0
- data/LICENSE +20 -0
- data/README.rdoc +38 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/lib/generators/vidibus_secure_key/vidibus_secure_key_generator.rb +11 -0
- data/lib/vidibus/secure/extensions/controller.rb +34 -0
- data/lib/vidibus/secure/extensions.rb +5 -0
- data/lib/vidibus/secure/mongoid.rb +35 -0
- data/lib/vidibus/secure.rb +131 -0
- data/lib/vidibus-secure.rb +6 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/vidibus/secure/extensions/controller_spec.rb +75 -0
- data/spec/vidibus/secure/mongoid_spec.rb +89 -0
- data/spec/vidibus/secure_spec.rb +345 -0
- data/vidibus-secure.gemspec +75 -0
- metadata +151 -0
data/.bundle/config
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "mongoid", "~> 2.0.0.beta.20"
|
|
4
|
+
gem "activesupport", "~> 3.0.0"
|
|
5
|
+
gem "rack"
|
|
6
|
+
gem "vidibus-core_extensions"
|
|
7
|
+
|
|
8
|
+
# Development dependencies
|
|
9
|
+
gem "rails", "~> 3.0.0"
|
|
10
|
+
gem "rspec", "~> 2.0.0.beta.20"
|
|
11
|
+
gem "rr"
|
|
12
|
+
gem "relevance-rcov"
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
abstract (1.0.0)
|
|
5
|
+
actionmailer (3.0.0)
|
|
6
|
+
actionpack (= 3.0.0)
|
|
7
|
+
mail (~> 2.2.5)
|
|
8
|
+
actionpack (3.0.0)
|
|
9
|
+
activemodel (= 3.0.0)
|
|
10
|
+
activesupport (= 3.0.0)
|
|
11
|
+
builder (~> 2.1.2)
|
|
12
|
+
erubis (~> 2.6.6)
|
|
13
|
+
i18n (~> 0.4.1)
|
|
14
|
+
rack (~> 1.2.1)
|
|
15
|
+
rack-mount (~> 0.6.12)
|
|
16
|
+
rack-test (~> 0.5.4)
|
|
17
|
+
tzinfo (~> 0.3.23)
|
|
18
|
+
activemodel (3.0.0)
|
|
19
|
+
activesupport (= 3.0.0)
|
|
20
|
+
builder (~> 2.1.2)
|
|
21
|
+
i18n (~> 0.4.1)
|
|
22
|
+
activerecord (3.0.0)
|
|
23
|
+
activemodel (= 3.0.0)
|
|
24
|
+
activesupport (= 3.0.0)
|
|
25
|
+
arel (~> 1.0.0)
|
|
26
|
+
tzinfo (~> 0.3.23)
|
|
27
|
+
activeresource (3.0.0)
|
|
28
|
+
activemodel (= 3.0.0)
|
|
29
|
+
activesupport (= 3.0.0)
|
|
30
|
+
activesupport (3.0.0)
|
|
31
|
+
arel (1.0.1)
|
|
32
|
+
activesupport (~> 3.0.0)
|
|
33
|
+
bson (1.0.4)
|
|
34
|
+
builder (2.1.2)
|
|
35
|
+
diff-lcs (1.1.2)
|
|
36
|
+
erubis (2.6.6)
|
|
37
|
+
abstract (>= 1.0.0)
|
|
38
|
+
i18n (0.4.1)
|
|
39
|
+
mail (2.2.5)
|
|
40
|
+
activesupport (>= 2.3.6)
|
|
41
|
+
mime-types
|
|
42
|
+
treetop (>= 1.4.5)
|
|
43
|
+
mime-types (1.16)
|
|
44
|
+
mongo (1.0.7)
|
|
45
|
+
bson (>= 1.0.4)
|
|
46
|
+
mongoid (2.0.0.beta.17)
|
|
47
|
+
activemodel (~> 3.0.0)
|
|
48
|
+
bson (= 1.0.4)
|
|
49
|
+
mongo (= 1.0.7)
|
|
50
|
+
tzinfo (~> 0.3.22)
|
|
51
|
+
will_paginate (~> 3.0.pre)
|
|
52
|
+
polyglot (0.3.1)
|
|
53
|
+
rack (1.2.1)
|
|
54
|
+
rack-mount (0.6.13)
|
|
55
|
+
rack (>= 1.0.0)
|
|
56
|
+
rack-test (0.5.4)
|
|
57
|
+
rack (>= 1.0)
|
|
58
|
+
rails (3.0.0)
|
|
59
|
+
actionmailer (= 3.0.0)
|
|
60
|
+
actionpack (= 3.0.0)
|
|
61
|
+
activerecord (= 3.0.0)
|
|
62
|
+
activeresource (= 3.0.0)
|
|
63
|
+
activesupport (= 3.0.0)
|
|
64
|
+
bundler (~> 1.0.0)
|
|
65
|
+
railties (= 3.0.0)
|
|
66
|
+
railties (3.0.0)
|
|
67
|
+
actionpack (= 3.0.0)
|
|
68
|
+
activesupport (= 3.0.0)
|
|
69
|
+
rake (>= 0.8.4)
|
|
70
|
+
thor (~> 0.14.0)
|
|
71
|
+
rake (0.8.7)
|
|
72
|
+
relevance-rcov (0.9.2.1)
|
|
73
|
+
rr (1.0.0)
|
|
74
|
+
rspec (2.0.0.beta.20)
|
|
75
|
+
rspec-core (= 2.0.0.beta.20)
|
|
76
|
+
rspec-expectations (= 2.0.0.beta.20)
|
|
77
|
+
rspec-mocks (= 2.0.0.beta.20)
|
|
78
|
+
rspec-core (2.0.0.beta.20)
|
|
79
|
+
rspec-expectations (2.0.0.beta.20)
|
|
80
|
+
diff-lcs (>= 1.1.2)
|
|
81
|
+
rspec-mocks (2.0.0.beta.20)
|
|
82
|
+
thor (0.14.0)
|
|
83
|
+
treetop (1.4.8)
|
|
84
|
+
polyglot (>= 0.3.1)
|
|
85
|
+
tzinfo (0.3.23)
|
|
86
|
+
vidibus-core_extensions (0.3.5)
|
|
87
|
+
will_paginate (3.0.pre2)
|
|
88
|
+
|
|
89
|
+
PLATFORMS
|
|
90
|
+
ruby
|
|
91
|
+
|
|
92
|
+
DEPENDENCIES
|
|
93
|
+
activesupport (~> 3.0.0)
|
|
94
|
+
mongoid (~> 2.0.0.beta.20)
|
|
95
|
+
rack
|
|
96
|
+
rails (~> 3.0.0)
|
|
97
|
+
relevance-rcov
|
|
98
|
+
rr
|
|
99
|
+
rspec (~> 2.0.0.beta.20)
|
|
100
|
+
vidibus-core_extensions
|
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2010 Andre Pankratz
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
= vidibus-secure
|
|
2
|
+
|
|
3
|
+
This gem is part of the open source SOA framework Vidibus: http://www.vidibus.org
|
|
4
|
+
|
|
5
|
+
TODO: Describe
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
== Installation
|
|
9
|
+
|
|
10
|
+
Add the dependency to the Gemfile of your application:
|
|
11
|
+
|
|
12
|
+
gem "vidibus-secure"
|
|
13
|
+
|
|
14
|
+
Then call `bundle install` on your console.
|
|
15
|
+
|
|
16
|
+
If you want to use Vidibus::Secure::Mongoid in your models, you should generate an initializer to set an unique encryption key:
|
|
17
|
+
|
|
18
|
+
rails generate vidibus_secure_key
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
== Usage
|
|
22
|
+
|
|
23
|
+
TODO: Describe
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
=== Usage in Mongoid model
|
|
27
|
+
|
|
28
|
+
TODO: Describe
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
== TODO
|
|
32
|
+
|
|
33
|
+
* Documentation
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
== Copyright
|
|
37
|
+
|
|
38
|
+
Copyright (c) 2010 Andre Pankratz. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require "rubygems"
|
|
2
|
+
require "rake"
|
|
3
|
+
require "rake/rdoctask"
|
|
4
|
+
require "rspec"
|
|
5
|
+
require "rspec/core/rake_task"
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
require "jeweler"
|
|
9
|
+
Jeweler::Tasks.new do |gem|
|
|
10
|
+
gem.name = "vidibus-secure"
|
|
11
|
+
gem.summary = %Q{Security tools for Vidibus applications}
|
|
12
|
+
gem.description = %Q{Description...}
|
|
13
|
+
gem.email = "andre@vidibus.com"
|
|
14
|
+
gem.homepage = "http://github.com/vidibus/vidibus-secure"
|
|
15
|
+
gem.authors = ["Andre Pankratz"]
|
|
16
|
+
gem.add_dependency "mongoid", "~> 2.0.0.beta.20"
|
|
17
|
+
gem.add_dependency "activesupport", "~> 3.0.0"
|
|
18
|
+
gem.add_dependency "rack"
|
|
19
|
+
gem.add_dependency "vidibus-core_extensions"
|
|
20
|
+
end
|
|
21
|
+
Jeweler::GemcutterTasks.new
|
|
22
|
+
rescue LoadError
|
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Rspec::Core::RakeTask.new(:rcov) do |t|
|
|
27
|
+
t.pattern = "spec/**/*_spec.rb"
|
|
28
|
+
t.rcov = true
|
|
29
|
+
t.rcov_opts = ["--exclude", "^spec,/gems/"]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Rake::RDocTask.new do |rdoc|
|
|
33
|
+
version = File.exist?("VERSION") ? File.read("VERSION") : ""
|
|
34
|
+
rdoc.rdoc_dir = "rdoc"
|
|
35
|
+
rdoc.title = "vidibus-secure #{version}"
|
|
36
|
+
rdoc.rdoc_files.include("README*")
|
|
37
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
38
|
+
rdoc.options << "--charset=utf-8"
|
|
39
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.1
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class VidibusSecureKeyGenerator < Rails::Generators::Base
|
|
2
|
+
desc 'Generates an initializer that sets ENV["VIDIBUS_SECURE_KEY"]'
|
|
3
|
+
|
|
4
|
+
def create_initializer
|
|
5
|
+
create_file "config/initializers/vidibus_secure_key.rb" do
|
|
6
|
+
%(# This is a secret key for encrypting values of field defined by attr_encrypted.\n) +
|
|
7
|
+
%(# Do not change this encryption key! Otherwise you will not be able to decrypt data already stored in your database.\n) +
|
|
8
|
+
%(ENV["VIDIBUS_SECURE_KEY"] = "#{Vidibus::Secure.random(:encoding => :base64, :length => 100)}")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Vidibus
|
|
2
|
+
module Secure
|
|
3
|
+
module Extensions
|
|
4
|
+
|
|
5
|
+
# Contains extensions of ApplicationController.
|
|
6
|
+
module Controller
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
helper_method :valid_request?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Generates a signature of a request path.
|
|
14
|
+
# Will use the current request.fullpath unless an URI is given.
|
|
15
|
+
#
|
|
16
|
+
# The given URI will be decomposed into path and request params.
|
|
17
|
+
# A given +signature_param+ will be removed, all remaining params
|
|
18
|
+
# will be ordered alphabetically.
|
|
19
|
+
#
|
|
20
|
+
# Usage:
|
|
21
|
+
#
|
|
22
|
+
# valid_request?("mysecret")
|
|
23
|
+
# valid_request?("mysecret", :uri => "http://...", :method => "get", :params => {})
|
|
24
|
+
#
|
|
25
|
+
def valid_request?(secret, options = {})
|
|
26
|
+
method = options.delete(:method) || request.method
|
|
27
|
+
uri = options.delete(:uri) || request.protocol + request.host_with_port + request.fullpath
|
|
28
|
+
params = options.delete(:params) || request.params.except(:action, "action", :controller, "controller", :id, "id")
|
|
29
|
+
Vidibus::Secure.verify_request(method, uri, params, secret)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Vidibus
|
|
2
|
+
module Secure
|
|
3
|
+
module Mongoid
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
module ClassMethods
|
|
6
|
+
|
|
7
|
+
# Sets encrypted attributes.
|
|
8
|
+
def attr_encrypted(*args)
|
|
9
|
+
key = ENV["VIDIBUS_SECURE_KEY"]
|
|
10
|
+
options = args.extract_options!
|
|
11
|
+
for field in args
|
|
12
|
+
|
|
13
|
+
# Define Mongoid field
|
|
14
|
+
encrypted_field = "#{field}_encrypted"
|
|
15
|
+
self.send(:field, encrypted_field, :type => Binary)
|
|
16
|
+
|
|
17
|
+
# Define setter
|
|
18
|
+
class_eval <<-EOV
|
|
19
|
+
def #{field}=(value)
|
|
20
|
+
self.#{encrypted_field} = value ? Vidibus::Secure.encrypt(value, "#{key}") : nil
|
|
21
|
+
end
|
|
22
|
+
EOV
|
|
23
|
+
|
|
24
|
+
# Define getter
|
|
25
|
+
class_eval <<-EOV
|
|
26
|
+
def #{field}
|
|
27
|
+
Vidibus::Secure.decrypt(#{encrypted_field}, "#{key}") if #{encrypted_field}
|
|
28
|
+
end
|
|
29
|
+
EOV
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
require "openssl"
|
|
2
|
+
require "active_support/secure_random"
|
|
3
|
+
require "rack"
|
|
4
|
+
require "uri"
|
|
5
|
+
|
|
6
|
+
module Vidibus
|
|
7
|
+
module Secure
|
|
8
|
+
|
|
9
|
+
class KeyError < StandardError; end
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
|
|
13
|
+
# Define default settings for random, sign, and crypt.
|
|
14
|
+
def settings
|
|
15
|
+
@settings ||= {
|
|
16
|
+
:random => { :length => 50, :encoding => :base64 },
|
|
17
|
+
:sign => { :algorithm => "SHA256", :encoding => :hex },
|
|
18
|
+
:crypt => { :algorithm => "AES-256-CBC", :encoding => :base64 }
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns a truly random string.
|
|
23
|
+
# Now it is not much more than an interface for ActiveSupport::SecureRandom,
|
|
24
|
+
# but that might change over time.
|
|
25
|
+
#
|
|
26
|
+
# Options:
|
|
27
|
+
# :length Length of string to generate
|
|
28
|
+
# :encoding Encoding of string; hex or base64
|
|
29
|
+
#
|
|
30
|
+
# Keep in mind that a hexadecimal string is less secure
|
|
31
|
+
# than a base64 encoded string with the same length!
|
|
32
|
+
#
|
|
33
|
+
def random(options = {})
|
|
34
|
+
options = settings[:random].merge(options)
|
|
35
|
+
length = options[:length]
|
|
36
|
+
ActiveSupport::SecureRandom.send(options[:encoding], length)[0,length]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns signature of given data with given key.
|
|
40
|
+
def sign(data, key, options = {})
|
|
41
|
+
raise KeyError.new("Please provide a secret key to sign data with.") unless key
|
|
42
|
+
options = settings[:sign].merge(options)
|
|
43
|
+
digest = OpenSSL::Digest::Digest.new(options[:algorithm])
|
|
44
|
+
signature = OpenSSL::HMAC.digest(digest, key, data)
|
|
45
|
+
encode(signature, options)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Encrypts given data with given key.
|
|
49
|
+
def encrypt(data, key, options = {})
|
|
50
|
+
raise KeyError.new("Please provide a secret key to encrypt data with.") unless key
|
|
51
|
+
options = settings[:crypt].merge(options)
|
|
52
|
+
encrypted_data = crypt(:encrypt, data, key, options)
|
|
53
|
+
encode(encrypted_data, options)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Decrypts given data with given key.
|
|
57
|
+
def decrypt(data, key, options = {})
|
|
58
|
+
raise KeyError.new("Please provide a secret key to decrypt data with.") unless key
|
|
59
|
+
options = settings[:crypt].merge(options)
|
|
60
|
+
decoded_data = decode(data, options)
|
|
61
|
+
crypt(:decrypt, decoded_data, key, options)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Signs request.
|
|
65
|
+
def sign_request(verb, path, params, key, signature_param = nil)
|
|
66
|
+
default_signature_param = :sign
|
|
67
|
+
params_given = !!params
|
|
68
|
+
raise ArgumentError.new("Given params is not a Hash.") if params_given and !params.is_a?(Hash)
|
|
69
|
+
params = {} unless params_given
|
|
70
|
+
signature_param ||= (params_given and params.keys.first.is_a?(String)) ? default_signature_param.to_s : default_signature_param
|
|
71
|
+
|
|
72
|
+
uri = URI.parse(path)
|
|
73
|
+
path_params = Rack::Utils.parse_query(uri.query)
|
|
74
|
+
uri.query = nil
|
|
75
|
+
|
|
76
|
+
_verb = verb.to_s.downcase
|
|
77
|
+
_uri = uri.to_s.gsub(/\/+$/, "")
|
|
78
|
+
_params = (params.merge(path_params)).except(signature_param.to_s, signature_param.to_s.to_sym)
|
|
79
|
+
_params = _params.any? ? _params.to_a_rec.flatten.sort{|a,b| a.to_s <=> b.to_s}.join("|") : ""
|
|
80
|
+
|
|
81
|
+
signature = sign("#{_verb}|#{_uri}|#{_params}", key)
|
|
82
|
+
|
|
83
|
+
if %w[post put].include?(_verb) or (params_given and path_params.empty?)
|
|
84
|
+
params[signature_param] = signature
|
|
85
|
+
else
|
|
86
|
+
unless path.gsub!(/(#{signature_param}=)[^&]+/, "\\1#{signature}")
|
|
87
|
+
glue = path.match(/\?/) ? "&" : "?"
|
|
88
|
+
path << "#{glue}#{signature_param}=#{signature}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
[path, params]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Verifies that given request is valid.
|
|
95
|
+
def verify_request(verb, path, params, key, signature_param = nil)
|
|
96
|
+
params ||= {}
|
|
97
|
+
_path = path.dup
|
|
98
|
+
_params = params.dup
|
|
99
|
+
sign_request(verb, _path, _params, key, signature_param)
|
|
100
|
+
return (path == _path and params == _params)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
protected
|
|
104
|
+
|
|
105
|
+
def crypt(cipher_method, data, key, options = {})
|
|
106
|
+
cipher = OpenSSL::Cipher::Cipher.new(options[:algorithm])
|
|
107
|
+
digest = OpenSSL::Digest::SHA512.new(key).digest
|
|
108
|
+
cipher.send(cipher_method)
|
|
109
|
+
cipher.pkcs5_keyivgen(digest)
|
|
110
|
+
result = cipher.update(data)
|
|
111
|
+
result << cipher.final
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def encode(data, options = {})
|
|
115
|
+
if options[:encoding] == :hex
|
|
116
|
+
data.unpack("H*").to_s
|
|
117
|
+
elsif options[:encoding] == :base64
|
|
118
|
+
[data].pack("m*")
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def decode(data, options = {})
|
|
123
|
+
if options[:encoding] == :hex
|
|
124
|
+
[data].pack("H*")
|
|
125
|
+
elsif options[:encoding] == :base64
|
|
126
|
+
data.unpack("m*").to_s
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
3
|
+
|
|
4
|
+
require "rubygems"
|
|
5
|
+
require "mongoid"
|
|
6
|
+
require "rspec"
|
|
7
|
+
require "rr"
|
|
8
|
+
require "vidibus-secure"
|
|
9
|
+
|
|
10
|
+
Mongoid.configure do |config|
|
|
11
|
+
name = "vidibus-secure_test"
|
|
12
|
+
host = "localhost"
|
|
13
|
+
config.master = Mongo::Connection.new.db(name)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
RSpec.configure do |config|
|
|
17
|
+
config.mock_with :rr
|
|
18
|
+
config.after :suite do
|
|
19
|
+
Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "ostruct"
|
|
2
|
+
require "spec_helper"
|
|
3
|
+
require "action_controller"
|
|
4
|
+
|
|
5
|
+
class Controller < ActionController::Base; end
|
|
6
|
+
|
|
7
|
+
describe "Vidibus::Secure::Extensions::Controller" do
|
|
8
|
+
let(:controller) { Controller.new }
|
|
9
|
+
let(:secret) { "mysecret" }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
stub(controller).request do
|
|
13
|
+
@request ||= begin
|
|
14
|
+
Struct.new("Request", :protocol, :host_with_port, :fullpath, :method, :params) unless defined?(Struct::Request)
|
|
15
|
+
Struct::Request.new("http://", "vidibus.org", "/", "get", {})
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "#valid_request?" do
|
|
21
|
+
it "should available to controllers that stem from ActionController::Base" do
|
|
22
|
+
controller.should respond_to(:valid_request?)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should build URI from request object if no :uri is provided" do
|
|
26
|
+
mock(controller.request).protocol {"http://"}
|
|
27
|
+
mock(controller.request).host_with_port {"vidibus.org"}
|
|
28
|
+
mock(controller.request).fullpath {"/"}
|
|
29
|
+
controller.valid_request?(secret, :method => "get", :params => {})
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should use request.method if no :method is provided" do
|
|
33
|
+
mock(controller.request).method {"get"}
|
|
34
|
+
controller.valid_request?(secret, :uri => "something", :params => {})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should use request.params if no :params are provided" do
|
|
38
|
+
mock(controller.request).params {{}}
|
|
39
|
+
controller.valid_request?(secret, :uri => "something", :method => "get")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should use given params" do
|
|
43
|
+
dont_allow(controller).request
|
|
44
|
+
controller.valid_request?(secret, :method => "get", :uri => "something", :params => {})
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should return true for valid requests" do
|
|
48
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/", controller.request.params, secret)
|
|
49
|
+
controller.valid_request?(secret).should be_true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should omit :action, :controller, and :id from request.params" do
|
|
53
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/", controller.request.params, secret)
|
|
54
|
+
controller.request.params.merge(:action => "index", :controller => "application", :id => nil)
|
|
55
|
+
controller.valid_request?(secret).should be_true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should omit 'action', 'controller', and 'id' from request.params" do
|
|
59
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/", controller.request.params, secret)
|
|
60
|
+
controller.request.params.merge("action" => "index", "controller" => "application", "id" => nil)
|
|
61
|
+
controller.valid_request?(secret).should be_true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should keep :action, :controller, and :id in custom params" do
|
|
65
|
+
params = { :action => "index", :controller => "application", :id => "12" }
|
|
66
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/", params, secret)
|
|
67
|
+
controller.valid_request?(secret, :params => params).should be_true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should call Vidibus::Secure.verify_request" do
|
|
71
|
+
mock(Vidibus::Secure).verify_request("get", "http://vidibus.org/", {}, secret)
|
|
72
|
+
controller.valid_request?(secret)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
ENV["VIDIBUS_SECURE_KEY"] = "c4l60HC/lyerr2VEnrP7s2YAldyZGfIBePUzCl+tBsTs1EWJOc8dEJ7F2Vty7KPEeRuBWGxZHVAbku8pLo+UvXRpLcRiF7lxKiKl"
|
|
4
|
+
|
|
5
|
+
class Model
|
|
6
|
+
include Mongoid::Document
|
|
7
|
+
include Vidibus::Secure::Mongoid
|
|
8
|
+
attr_encrypted :my_secret, :another_secret
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "Vidibus::Secure::Mongoid" do
|
|
12
|
+
let(:model) { Model.new }
|
|
13
|
+
let(:secret) { "My name is Bond." }
|
|
14
|
+
let(:encrypted_secret) { "+PlBG1ChiqUAYMrHlJzDL4NwXHtGBIUm/KQ2ZWfwxjM=\n" }
|
|
15
|
+
|
|
16
|
+
it "should add a field :my_secret_encrypted" do
|
|
17
|
+
model.should respond_to(:my_secret_encrypted)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should add a setter for :my_secret" do
|
|
21
|
+
model.should respond_to(:my_secret=)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should add a getter for :my_secret" do
|
|
25
|
+
model.should respond_to(:my_secret)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should add a field :another_secret_encrypted" do
|
|
29
|
+
model.should respond_to(:another_secret_encrypted)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should add a setter for :another_secret" do
|
|
33
|
+
model.should respond_to(:another_secret=)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should add a getter for :another_secret" do
|
|
37
|
+
model.should respond_to(:another_secret)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "#my_secret=" do
|
|
41
|
+
it "should set :my_secret_encrypted" do
|
|
42
|
+
model.my_secret_encrypted.should be_nil
|
|
43
|
+
model.my_secret = "my_secret"
|
|
44
|
+
model.my_secret_encrypted.should_not be_nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should encrypt a given value" do
|
|
48
|
+
model.my_secret = secret
|
|
49
|
+
model.my_secret_encrypted.should eql(encrypted_secret)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should be persistent" do
|
|
53
|
+
model.my_secret = secret
|
|
54
|
+
model.save!
|
|
55
|
+
model.reload
|
|
56
|
+
model.my_secret_encrypted.should eql(encrypted_secret)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should not encrypt nil" do
|
|
60
|
+
model.my_secret = nil
|
|
61
|
+
model.my_secret_encrypted.should eql(nil)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "#my_secret" do
|
|
66
|
+
it "should get :my_secret_encrypted" do
|
|
67
|
+
model.my_secret.should be_nil
|
|
68
|
+
model.my_secret_encrypted = encrypted_secret
|
|
69
|
+
model.my_secret.should_not be_nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should decrypt value of :my_secret_encrypted" do
|
|
73
|
+
model.my_secret_encrypted = encrypted_secret
|
|
74
|
+
model.my_secret.should eql(secret)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should be persistent" do
|
|
78
|
+
model.my_secret_encrypted = encrypted_secret
|
|
79
|
+
model.save!
|
|
80
|
+
model.reload
|
|
81
|
+
model.my_secret.should eql(secret)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should not decrypt nil" do
|
|
85
|
+
model.my_secret_encrypted = nil
|
|
86
|
+
model.my_secret.should eql(nil)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe "Vidibus::Secure" do
|
|
4
|
+
let(:key) { "8KTbTanrBTQ5c8CjANpJQjPWcIstFxq/uFIUQBF3gRnztM565xIfe8MStVcLilbEhjYwfZiD4lFWINF22Aw8gVEbkSf2rLN0fnuO9YtNqFLQU6m/OldO5JbsBJPCwuzsPYmZ1w==" }
|
|
5
|
+
let(:data) { "My name is Bond. You know the rest." }
|
|
6
|
+
let(:encrypted_base64) { "hXUWa3gHRpYr/Fi2qm9xdTyZg7NSpYq8X2p1EL+/wffUg9IeIjVbSvyUYAvy\nTLbc\n" }
|
|
7
|
+
let(:encrypted_hex) { "8575166b780746962bfc58b6aa6f71753c9983b352a58abc5f6a7510bfbfc1f7d483d21e22355b4afc94600bf24cb6dc" }
|
|
8
|
+
let(:signature_base64) { "AhTlmymUI9q2bdrtJ0vLdyV8Y8eUf2U5xrzoK5PdWKQ=\n" }
|
|
9
|
+
let(:signature_hex) { "0214e59b299423dab66ddaed274bcb77257c63c7947f6539c6bce82b93dd58a4" }
|
|
10
|
+
let(:base64_format) { /([A-Z]|\+|\/)/ }
|
|
11
|
+
let(:hex_format) { /^[0-9a-f]+$/ }
|
|
12
|
+
|
|
13
|
+
describe ".settings" do
|
|
14
|
+
context "for :random" do
|
|
15
|
+
it "should default to a length of 50" do
|
|
16
|
+
Vidibus::Secure.settings[:random][:length].should eql(50)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should default to base64 encoding" do
|
|
20
|
+
Vidibus::Secure.settings[:random][:encoding].should eql(:base64)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "for :sign" do
|
|
25
|
+
it "should default to SHA256 algorithm" do
|
|
26
|
+
Vidibus::Secure.settings[:sign][:algorithm].should eql("SHA256")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should default to hex encoding" do
|
|
30
|
+
Vidibus::Secure.settings[:sign][:encoding].should eql(:hex)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "for :crypt" do
|
|
35
|
+
it "should default to AES-256-CBC algorithm" do
|
|
36
|
+
Vidibus::Secure.settings[:crypt][:algorithm].should eql("AES-256-CBC")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should default to base64 encoding" do
|
|
40
|
+
Vidibus::Secure.settings[:crypt][:encoding].should eql(:base64)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe ".random" do
|
|
46
|
+
it "should create a base64 random string with a length of 50 chars" do
|
|
47
|
+
random = Vidibus::Secure.random
|
|
48
|
+
random.length.should eql(50)
|
|
49
|
+
random.should match(base64_format)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should create a hexadecimal random string with a length of 50 chars if :encoding is provided" do
|
|
53
|
+
random = Vidibus::Secure.random(:encoding => :hex)
|
|
54
|
+
random.length.should eql(50)
|
|
55
|
+
random.should match(hex_format)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should create a random string with a length of 60 chars if :length is provided" do
|
|
59
|
+
Vidibus::Secure.random(:length => 60).length.should eql(60)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should create a hexadecimal random string if settings for :random are changed" do
|
|
63
|
+
Vidibus::Secure.settings[:random][:encoding] = :hex
|
|
64
|
+
Vidibus::Secure.random.should match(hex_format)
|
|
65
|
+
Vidibus::Secure.settings[:random][:encoding] = :base64
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe ".sign" do
|
|
70
|
+
it "should create a hexadecimal signature of given data by default" do
|
|
71
|
+
Vidibus::Secure.sign(data, key).should eql(signature_hex)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should create a base64 signature of given data if :encoding is provided" do
|
|
75
|
+
Vidibus::Secure.sign(data, key, :encoding => :base64).should eql(signature_base64)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should create a base64 signature of given data if settings for :sign are changed" do
|
|
79
|
+
Vidibus::Secure.settings[:sign][:encoding] = :base64
|
|
80
|
+
Vidibus::Secure.sign(data, key).should eql(signature_base64)
|
|
81
|
+
Vidibus::Secure.settings[:sign][:encoding] = :hex
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should raise an error if given secret key is nil" do
|
|
85
|
+
expect { Vidibus::Secure.sign(data, nil) }.to raise_error(Vidibus::Secure::KeyError)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe ".encrypt" do
|
|
90
|
+
it "should encrypt data as base64 string" do
|
|
91
|
+
Vidibus::Secure.encrypt(data, key).should eql(encrypted_base64)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should encrypt data as hexadecimal string if :encoding is provided" do
|
|
95
|
+
Vidibus::Secure.encrypt(data, key, :encoding => :hex).should eql(encrypted_hex)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should encrypt data as hexadecimal string if encoding settings for :crypt are set to hex" do
|
|
99
|
+
Vidibus::Secure.settings[:crypt][:encoding] = :hex
|
|
100
|
+
Vidibus::Secure.encrypt(data, key).should eql(encrypted_hex)
|
|
101
|
+
Vidibus::Secure.settings[:crypt][:encoding] = :base64
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should raise an error if given secret key is nil" do
|
|
105
|
+
expect { Vidibus::Secure.sign(data, nil) }.to raise_error(Vidibus::Secure::KeyError)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe ".decrypt" do
|
|
110
|
+
it "should decrypt a base64 string" do
|
|
111
|
+
Vidibus::Secure.decrypt(encrypted_base64, key).should eql(data)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should decrypt a hexadecimal string if :encoding is provided" do
|
|
115
|
+
Vidibus::Secure.decrypt(encrypted_hex, key, :encoding => :hex).should eql(data)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should decrypt a hexadecimal string if encoding settings for :crypt are set to hex" do
|
|
119
|
+
Vidibus::Secure.settings[:crypt][:encoding] = :hex
|
|
120
|
+
Vidibus::Secure.decrypt(encrypted_hex, key).should eql(data)
|
|
121
|
+
Vidibus::Secure.settings[:crypt][:encoding] = :base64
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should raise an error if given secret key is nil" do
|
|
125
|
+
expect { Vidibus::Secure.sign(data, nil) }.to raise_error(Vidibus::Secure::KeyError)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe ".sign_request" do
|
|
130
|
+
it "should not modifiy path for POST and PUT requests" do
|
|
131
|
+
for verb in %w[post put]
|
|
132
|
+
path, params = Vidibus::Secure.sign_request(verb, "/whazzup", {}, key)
|
|
133
|
+
path.should eql("/whazzup")
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should require that given params is a Hash" do
|
|
138
|
+
params = %w[1 2 3]
|
|
139
|
+
expect {
|
|
140
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
141
|
+
}.to raise_error(ArgumentError, "Given params is not a Hash.")
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context "for requests without body" do
|
|
145
|
+
it "should add signature to params, if no params are given in URI and params argument is a hash" do
|
|
146
|
+
path = "http://vidibus.org/status"
|
|
147
|
+
params = {}
|
|
148
|
+
Vidibus::Secure.sign_request(:get, path, params, key)
|
|
149
|
+
path.should eql("http://vidibus.org/status")
|
|
150
|
+
params.should eql(:sign => "09247a2534f14e57081193ef6834b08843352c796af264f77e76445472dae9ed")
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should add signature to URI, if no params are given in URI and params argument nil" do
|
|
154
|
+
path = "http://vidibus.org/status"
|
|
155
|
+
params = nil
|
|
156
|
+
Vidibus::Secure.sign_request(:get, path, params, key)
|
|
157
|
+
path.should eql("http://vidibus.org/status?sign=09247a2534f14e57081193ef6834b08843352c796af264f77e76445472dae9ed")
|
|
158
|
+
params.should be_nil
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "should add signature to URI, if params argument is a hash, but params are also given in URI" do
|
|
162
|
+
path = "http://vidibus.org/status?feel=good"
|
|
163
|
+
params = {}
|
|
164
|
+
Vidibus::Secure.sign_request(:get, path, params, key)
|
|
165
|
+
path.should eql("http://vidibus.org/status?feel=good&sign=528bbd5f791960570bd1a53ea5540d9970361b7abff72e8ecc02b12673330270")
|
|
166
|
+
params.should eql({})
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "should accept a custom name as signature param" do
|
|
170
|
+
path = "http://vidibus.org/status"
|
|
171
|
+
Vidibus::Secure.sign_request(:get, path, nil, key, "privado")
|
|
172
|
+
path.should eql("http://vidibus.org/status?privado=09247a2534f14e57081193ef6834b08843352c796af264f77e76445472dae9ed")
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should create a signature of a given URL" do
|
|
176
|
+
path = "http://vidibus.org/"
|
|
177
|
+
Vidibus::Secure.sign_request(:get, path, nil, key)
|
|
178
|
+
path.should eql("http://vidibus.org/?sign=0ff9ec7056fd6a2b8ea1d2a1f462458719e3cf0b65485c55035ac906fd3d3368")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should create identical signatures for URLs with and without trailing slash" do
|
|
182
|
+
signature = "0ff9ec7056fd6a2b8ea1d2a1f462458719e3cf0b65485c55035ac906fd3d3368"
|
|
183
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org", nil, key).first.should match(signature)
|
|
184
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/", nil, key).first.should match(signature)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should create a signature of a given URI" do
|
|
188
|
+
path = "http://vidibus.org/status"
|
|
189
|
+
Vidibus::Secure.sign_request(:get, path, nil, key)
|
|
190
|
+
path.should eql("http://vidibus.org/status?sign=09247a2534f14e57081193ef6834b08843352c796af264f77e76445472dae9ed")
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "should create identical signatures for URIs with and without trailing slash" do
|
|
194
|
+
signature = "09247a2534f14e57081193ef6834b08843352c796af264f77e76445472dae9ed"
|
|
195
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/status", nil, key).first.should match(signature)
|
|
196
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/status/", nil, key).first.should match(signature)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "should create a signature of URI with params" do
|
|
200
|
+
path = "http://vidibus.org/status?type=server"
|
|
201
|
+
Vidibus::Secure.sign_request(:get, path, {}, key)
|
|
202
|
+
path.should eql("http://vidibus.org/status?type=server&sign=afdc286310f98b36a4ad71e493a13ff35b5d841472328faadee270b6c62ca321")
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "should create identical signatures for URIs with params with and without trailing slash" do
|
|
206
|
+
signature = "afdc286310f98b36a4ad71e493a13ff35b5d841472328faadee270b6c62ca321"
|
|
207
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/status?type=server", {}, key).first.should match(signature)
|
|
208
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/status/?type=server", {}, key).first.should match(signature)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should replace signature in URI with params" do
|
|
212
|
+
path = "http://vidibus.org/status?interval=2&sign=something&type=server"
|
|
213
|
+
Vidibus::Secure.sign_request(:get, path, {}, key)
|
|
214
|
+
path.should eql("http://vidibus.org/status?interval=2&sign=647b0f8278ad6536b02886fa2e74ae31574941e74a7a1c1f3abe2c70b5c84625&type=server")
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "should replace signature in URI without other params" do
|
|
218
|
+
path = "http://vidibus.org/status?sign=something"
|
|
219
|
+
Vidibus::Secure.sign_request(:get, path, {}, key)
|
|
220
|
+
path.should eql("http://vidibus.org/status?sign=09247a2534f14e57081193ef6834b08843352c796af264f77e76445472dae9ed")
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "should create identical signatures for URIs with different params order" do
|
|
224
|
+
signature = "23a74d6a231961700e45b907b72fd3d47e10f7bc4618d74cb6e839d1de1b8fb7"
|
|
225
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/status?a=1&b=2", {}, key).first.should match(signature)
|
|
226
|
+
Vidibus::Secure.sign_request(:get, "http://vidibus.org/status/?b=2&a=1", {}, key).first.should match(signature)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
context "for request with body" do
|
|
231
|
+
it "should create a signature of path and params" do
|
|
232
|
+
params = {:some => "thing"}
|
|
233
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
234
|
+
params[:some].should eql("thing")
|
|
235
|
+
params[:sign].should eql("1c038202044005a8da96c780b79c691af849604dab9dabd283e65271c8012aae")
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should create a signature of path and nested params" do
|
|
239
|
+
params = {:some => {:nested => "params", :are => {:really => ["serious", "stuff"]}}}
|
|
240
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
241
|
+
params[:some].should eql({:nested => "params", :are => {:really => ["serious", "stuff"]}})
|
|
242
|
+
params[:sign].should eql("9419d44fc65b515b31923e2f3f4a166b384df107b61b323a1f7a3be1d7ad27f5")
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "should replace existing signature" do
|
|
246
|
+
params = {:some => "thing", :sign => "something"}
|
|
247
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
248
|
+
params[:some].should eql("thing")
|
|
249
|
+
params[:sign].should eql("1c038202044005a8da96c780b79c691af849604dab9dabd283e65271c8012aae")
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should add signature param as string if params are given as strings" do
|
|
253
|
+
params = {"some" => "thing"}
|
|
254
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
255
|
+
params["some"].should eql("thing")
|
|
256
|
+
params["sign"].should_not be_nil
|
|
257
|
+
params[:sign].should be_nil
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "should add signature param as symbol if params are given as symbols" do
|
|
261
|
+
params = {:some => "thing"}
|
|
262
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
263
|
+
params[:some].should eql("thing")
|
|
264
|
+
params[:sign].should_not be_nil
|
|
265
|
+
params["sign"].should be_nil
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "should add signature param as symbol if no params are given" do
|
|
269
|
+
params = {}
|
|
270
|
+
Vidibus::Secure.sign_request(:post, "/", params, key)
|
|
271
|
+
params[:sign].should_not be_nil
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
describe ".verify_request" do
|
|
277
|
+
it "should return true for a valid GET request" do
|
|
278
|
+
path = "http://vidibus.org/status?type=server&sign=afdc286310f98b36a4ad71e493a13ff35b5d841472328faadee270b6c62ca321"
|
|
279
|
+
Vidibus::Secure.verify_request(:get, path, {}, key).should be_true
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "should return true for a valid GET request even if verb is upcase" do
|
|
283
|
+
path = "http://vidibus.org/status?type=server&sign=afdc286310f98b36a4ad71e493a13ff35b5d841472328faadee270b6c62ca321"
|
|
284
|
+
Vidibus::Secure.verify_request("GET", path, {}, key).should be_true
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "should return true for a valid GET request if params are given as hash" do
|
|
288
|
+
path = "http://vidibus.org/status"
|
|
289
|
+
params = {:type => "server", :sign => "afdc286310f98b36a4ad71e493a13ff35b5d841472328faadee270b6c62ca321"}
|
|
290
|
+
Vidibus::Secure.verify_request("GET", path, params, key).should be_true
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "should return false if additional params are given" do
|
|
294
|
+
path = "http://vidibus.org/status?type=server&sign=83d49980a04004431602a35941d2f927bfa9a2440fa04ccd2abbbad96309aa07"
|
|
295
|
+
Vidibus::Secure.verify_request("GET", path, { :some => "thing" }, key).should be_false
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it "should return true for a valid POST request with params given as symbols" do
|
|
299
|
+
params = {:sign => "1c038202044005a8da96c780b79c691af849604dab9dabd283e65271c8012aae", :some => "thing"}
|
|
300
|
+
Vidibus::Secure.verify_request(:post, "/", params, key).should be_true
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "should return true for a valid POST request with nested params" do
|
|
304
|
+
params = {
|
|
305
|
+
:sign => "9419d44fc65b515b31923e2f3f4a166b384df107b61b323a1f7a3be1d7ad27f5",
|
|
306
|
+
:some => {:nested => "params", :are => {:really => ["serious", "stuff"]}}
|
|
307
|
+
}
|
|
308
|
+
Vidibus::Secure.verify_request(:post, "/", params, key).should be_true
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
it "should return true for a valid POST request with params given as string" do
|
|
312
|
+
params = {"sign"=>"1c038202044005a8da96c780b79c691af849604dab9dabd283e65271c8012aae", "some"=>"thing"}
|
|
313
|
+
Vidibus::Secure.verify_request(:post, "/", params, key).should be_true
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it "should return false if signature is invalid" do
|
|
317
|
+
path = "http://vidibus.org/status?type=server&sign=invalid"
|
|
318
|
+
Vidibus::Secure.verify_request(:get, path, {}, key).should be_false
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it "should return false if path does not match signature" do
|
|
322
|
+
path = "http://vidibus.org/invalid?type=server&sign=068dbf2695798e3cda2710ae34d74043653eae41d82cbbdf39edebd7e2ae9a50"
|
|
323
|
+
Vidibus::Secure.verify_request(:get, path, {}, key).should be_false
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it "should return false if request verb does not match signature" do
|
|
327
|
+
path = "http://vidibus.org/status?type=server&sign=068dbf2695798e3cda2710ae34d74043653eae41d82cbbdf39edebd7e2ae9a50"
|
|
328
|
+
Vidibus::Secure.verify_request(:delete, path, {}, key).should be_false
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it "should return false if params do not match signature" do
|
|
332
|
+
params = {"sign" => "90c71e477ea155e99b8a85b7f9ad0614e5445acfc33702cd3db614941f1a7df9", "some" => "invalid"}
|
|
333
|
+
Vidibus::Secure.verify_request(:post, "/", params, key).should be_false
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "should return false if signature does not match params" do
|
|
337
|
+
params = {"sign" => "invalid", "some" => "thing"}
|
|
338
|
+
Vidibus::Secure.verify_request(:post, "/", params, key).should be_false
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it "should accept nil params" do
|
|
342
|
+
expect { Vidibus::Secure.verify_request(:get, "", nil, key) }.to_not raise_error
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{vidibus-secure}
|
|
8
|
+
s.version = "0.0.1"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Andre Pankratz"]
|
|
12
|
+
s.date = %q{2010-09-23}
|
|
13
|
+
s.description = %q{Description...}
|
|
14
|
+
s.email = %q{andre@vidibus.com}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"README.rdoc"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
".bundle/config",
|
|
21
|
+
".gitignore",
|
|
22
|
+
".rspec",
|
|
23
|
+
"Gemfile",
|
|
24
|
+
"Gemfile.lock",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"README.rdoc",
|
|
27
|
+
"Rakefile",
|
|
28
|
+
"VERSION",
|
|
29
|
+
"lib/generators/vidibus_secure_key/vidibus_secure_key_generator.rb",
|
|
30
|
+
"lib/vidibus-secure.rb",
|
|
31
|
+
"lib/vidibus/secure.rb",
|
|
32
|
+
"lib/vidibus/secure/extensions.rb",
|
|
33
|
+
"lib/vidibus/secure/extensions/controller.rb",
|
|
34
|
+
"lib/vidibus/secure/mongoid.rb",
|
|
35
|
+
"spec/spec_helper.rb",
|
|
36
|
+
"spec/vidibus/secure/extensions/controller_spec.rb",
|
|
37
|
+
"spec/vidibus/secure/mongoid_spec.rb",
|
|
38
|
+
"spec/vidibus/secure_spec.rb",
|
|
39
|
+
"vidibus-secure.gemspec"
|
|
40
|
+
]
|
|
41
|
+
s.homepage = %q{http://github.com/vidibus/vidibus-secure}
|
|
42
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
43
|
+
s.require_paths = ["lib"]
|
|
44
|
+
s.rubygems_version = %q{1.3.7}
|
|
45
|
+
s.summary = %q{Security tools for Vidibus applications}
|
|
46
|
+
s.test_files = [
|
|
47
|
+
"spec/spec_helper.rb",
|
|
48
|
+
"spec/vidibus/secure/extensions/controller_spec.rb",
|
|
49
|
+
"spec/vidibus/secure/mongoid_spec.rb",
|
|
50
|
+
"spec/vidibus/secure_spec.rb"
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
if s.respond_to? :specification_version then
|
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
55
|
+
s.specification_version = 3
|
|
56
|
+
|
|
57
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
58
|
+
s.add_runtime_dependency(%q<mongoid>, ["~> 2.0.0.beta.20"])
|
|
59
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
|
|
60
|
+
s.add_runtime_dependency(%q<rack>, [">= 0"])
|
|
61
|
+
s.add_runtime_dependency(%q<vidibus-core_extensions>, [">= 0"])
|
|
62
|
+
else
|
|
63
|
+
s.add_dependency(%q<mongoid>, ["~> 2.0.0.beta.20"])
|
|
64
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
|
|
65
|
+
s.add_dependency(%q<rack>, [">= 0"])
|
|
66
|
+
s.add_dependency(%q<vidibus-core_extensions>, [">= 0"])
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
s.add_dependency(%q<mongoid>, ["~> 2.0.0.beta.20"])
|
|
70
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
|
|
71
|
+
s.add_dependency(%q<rack>, [">= 0"])
|
|
72
|
+
s.add_dependency(%q<vidibus-core_extensions>, [">= 0"])
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
metadata
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vidibus-secure
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 29
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Andre Pankratz
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2010-09-23 00:00:00 +02:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: mongoid
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 62196427
|
|
30
|
+
segments:
|
|
31
|
+
- 2
|
|
32
|
+
- 0
|
|
33
|
+
- 0
|
|
34
|
+
- beta
|
|
35
|
+
- 20
|
|
36
|
+
version: 2.0.0.beta.20
|
|
37
|
+
type: :runtime
|
|
38
|
+
version_requirements: *id001
|
|
39
|
+
- !ruby/object:Gem::Dependency
|
|
40
|
+
name: activesupport
|
|
41
|
+
prerelease: false
|
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
43
|
+
none: false
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
hash: 7
|
|
48
|
+
segments:
|
|
49
|
+
- 3
|
|
50
|
+
- 0
|
|
51
|
+
- 0
|
|
52
|
+
version: 3.0.0
|
|
53
|
+
type: :runtime
|
|
54
|
+
version_requirements: *id002
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rack
|
|
57
|
+
prerelease: false
|
|
58
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
59
|
+
none: false
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
hash: 3
|
|
64
|
+
segments:
|
|
65
|
+
- 0
|
|
66
|
+
version: "0"
|
|
67
|
+
type: :runtime
|
|
68
|
+
version_requirements: *id003
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: vidibus-core_extensions
|
|
71
|
+
prerelease: false
|
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
hash: 3
|
|
78
|
+
segments:
|
|
79
|
+
- 0
|
|
80
|
+
version: "0"
|
|
81
|
+
type: :runtime
|
|
82
|
+
version_requirements: *id004
|
|
83
|
+
description: Description...
|
|
84
|
+
email: andre@vidibus.com
|
|
85
|
+
executables: []
|
|
86
|
+
|
|
87
|
+
extensions: []
|
|
88
|
+
|
|
89
|
+
extra_rdoc_files:
|
|
90
|
+
- LICENSE
|
|
91
|
+
- README.rdoc
|
|
92
|
+
files:
|
|
93
|
+
- .bundle/config
|
|
94
|
+
- .gitignore
|
|
95
|
+
- .rspec
|
|
96
|
+
- Gemfile
|
|
97
|
+
- Gemfile.lock
|
|
98
|
+
- LICENSE
|
|
99
|
+
- README.rdoc
|
|
100
|
+
- Rakefile
|
|
101
|
+
- VERSION
|
|
102
|
+
- lib/generators/vidibus_secure_key/vidibus_secure_key_generator.rb
|
|
103
|
+
- lib/vidibus-secure.rb
|
|
104
|
+
- lib/vidibus/secure.rb
|
|
105
|
+
- lib/vidibus/secure/extensions.rb
|
|
106
|
+
- lib/vidibus/secure/extensions/controller.rb
|
|
107
|
+
- lib/vidibus/secure/mongoid.rb
|
|
108
|
+
- spec/spec_helper.rb
|
|
109
|
+
- spec/vidibus/secure/extensions/controller_spec.rb
|
|
110
|
+
- spec/vidibus/secure/mongoid_spec.rb
|
|
111
|
+
- spec/vidibus/secure_spec.rb
|
|
112
|
+
- vidibus-secure.gemspec
|
|
113
|
+
has_rdoc: true
|
|
114
|
+
homepage: http://github.com/vidibus/vidibus-secure
|
|
115
|
+
licenses: []
|
|
116
|
+
|
|
117
|
+
post_install_message:
|
|
118
|
+
rdoc_options:
|
|
119
|
+
- --charset=UTF-8
|
|
120
|
+
require_paths:
|
|
121
|
+
- lib
|
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
|
+
none: false
|
|
124
|
+
requirements:
|
|
125
|
+
- - ">="
|
|
126
|
+
- !ruby/object:Gem::Version
|
|
127
|
+
hash: 3
|
|
128
|
+
segments:
|
|
129
|
+
- 0
|
|
130
|
+
version: "0"
|
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
|
+
none: false
|
|
133
|
+
requirements:
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
hash: 3
|
|
137
|
+
segments:
|
|
138
|
+
- 0
|
|
139
|
+
version: "0"
|
|
140
|
+
requirements: []
|
|
141
|
+
|
|
142
|
+
rubyforge_project:
|
|
143
|
+
rubygems_version: 1.3.7
|
|
144
|
+
signing_key:
|
|
145
|
+
specification_version: 3
|
|
146
|
+
summary: Security tools for Vidibus applications
|
|
147
|
+
test_files:
|
|
148
|
+
- spec/spec_helper.rb
|
|
149
|
+
- spec/vidibus/secure/extensions/controller_spec.rb
|
|
150
|
+
- spec/vidibus/secure/mongoid_spec.rb
|
|
151
|
+
- spec/vidibus/secure_spec.rb
|