symmetric-encryption 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/symmetric-encryption.rb +6 -0
- data/lib/symmetric/extensions/active_record/base.rb +12 -8
- data/lib/symmetric/extensions/mongoid/fields.rb +115 -0
- data/lib/symmetric/version.rb +1 -1
- data/symmetric-encryption-0.3.1.gem +0 -0
- data/test/attr_encrypted_test.rb +129 -102
- data/test/cipher_test.rb +3 -0
- data/test/config/mongoid.yml +6 -0
- data/test/field_encrypted_test.rb +136 -0
- metadata +8 -4
data/lib/symmetric-encryption.rb
CHANGED
@@ -4,7 +4,13 @@ require 'symmetric/encryption'
|
|
4
4
|
if defined?(Rails)
|
5
5
|
require 'symmetric/railtie'
|
6
6
|
end
|
7
|
+
# attr_encrypted and Encrypted validator
|
7
8
|
if defined?(ActiveRecord::Base)
|
8
9
|
require 'symmetric/extensions/active_record/base'
|
9
10
|
require 'symmetric/railties/symmetric_encrypted_validator'
|
10
11
|
end
|
12
|
+
|
13
|
+
# field encryption for Mongoid
|
14
|
+
if defined?(Mongoid)
|
15
|
+
require 'symmetric/extensions/mongoid/fields'
|
16
|
+
end
|
@@ -25,21 +25,25 @@ module ActiveRecord #:nodoc:
|
|
25
25
|
|
26
26
|
params.each do |attribute|
|
27
27
|
# Generate unencrypted attribute with getter and setter
|
28
|
-
class_eval
|
28
|
+
class_eval(<<-UNENCRYPTED, __FILE__, __LINE__ + 1)
|
29
|
+
# Returns the decrypted value for the encrypted attribute
|
30
|
+
# The decrypted value is cached and is only decrypted if the encrypted value has changed
|
31
|
+
# If this method is not called, then the encrypted value is never decrypted
|
29
32
|
def #{attribute}
|
30
|
-
|
33
|
+
if @stored_encrypted_#{attribute} != self.encrypted_#{attribute}
|
34
|
+
@#{attribute} = ::Symmetric::Encryption.decrypt(self.encrypted_#{attribute})
|
35
|
+
@stored_encrypted_#{attribute} = self.encrypted_#{attribute}
|
36
|
+
end
|
31
37
|
@#{attribute}
|
32
38
|
end
|
33
|
-
UNENCRYPTED_GETTER
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
class_eval <<-UNENCRYPTED_SETTER
|
40
|
+
# Set the un-encrypted attribute
|
41
|
+
# Also updates the encrypted field with the encrypted value
|
38
42
|
def #{attribute}=(value)
|
39
|
-
self.encrypted_#{attribute} = ::Symmetric::Encryption.encrypt(value#{".to_yaml" if options[:marshal]})
|
43
|
+
self.encrypted_#{attribute} = @stored_encrypted_#{attribute} = ::Symmetric::Encryption.encrypt(value#{".to_yaml" if options[:marshal]})
|
40
44
|
@#{attribute} = value
|
41
45
|
end
|
42
|
-
|
46
|
+
UNENCRYPTED
|
43
47
|
|
44
48
|
encrypted_attributes[attribute.to_sym] = "encrypted_#{attribute}".to_sym
|
45
49
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Extensions to the mongoid Document model to support field encryption
|
2
|
+
# per the attr_encrypted model
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# #TODO initialize, create
|
6
|
+
#
|
7
|
+
module Mongoid
|
8
|
+
module Fields
|
9
|
+
module ClassMethods
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# class Person
|
13
|
+
# include Mongoid::Document
|
14
|
+
# include Symmetric::Encryption::Mongoid
|
15
|
+
#
|
16
|
+
# field :name, :type => String
|
17
|
+
# field :encrypted_social_security_number, :type => String, :encrypted => true, :decrypt_as => :social_security_number
|
18
|
+
# field :age, :type => Integer
|
19
|
+
#
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# The above document results in the following document in the Mongo collection 'persons':
|
23
|
+
# {
|
24
|
+
# "name" : "Joe",
|
25
|
+
# "encrypted_social_security_number" : "...",
|
26
|
+
# "age" : 21
|
27
|
+
# }
|
28
|
+
#
|
29
|
+
# Symmetric Encryption creates the getters and setters to be able to work with the field
|
30
|
+
# in it's unencrypted form. For example
|
31
|
+
#
|
32
|
+
# Example:
|
33
|
+
# person = Person.where(:encrypted_social_security_number => '...').first
|
34
|
+
#
|
35
|
+
# puts "Decrypted Social Security Number is: #{person.social_security_number}"
|
36
|
+
#
|
37
|
+
# # Or is the same as
|
38
|
+
# puts "Decrypted Social Security Number is: #{Symmetric::Encryption.decrypt(person.encrypted_social_security_number)}"
|
39
|
+
#
|
40
|
+
# # Sets the encrypted_social_security_number to encrypted version
|
41
|
+
# person.social_security_number = "123456789"
|
42
|
+
#
|
43
|
+
# # Or, is equivalent to:
|
44
|
+
# person.social_security_number = Symmetric::Encryption.encrypt("123456789")
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# Note: Unlike attr_encrypted finders must use the encrypted field name
|
48
|
+
# For Example this is NOT valid:
|
49
|
+
# person = Person.where(:social_security_number => '123456789').first
|
50
|
+
#
|
51
|
+
# Defines all the fields that are accessible on the Document
|
52
|
+
# For each field that is defined, a getter and setter will be
|
53
|
+
# added as an instance method to the Document.
|
54
|
+
#
|
55
|
+
# @example Define a field.
|
56
|
+
# field :score, :type => Integer, :default => 0
|
57
|
+
#
|
58
|
+
# @param [ Symbol ] name The name of the field.
|
59
|
+
# @param [ Hash ] options The options to pass to the field.
|
60
|
+
#
|
61
|
+
# @option options [ Class ] :type The type of the field.
|
62
|
+
# @option options [ String ] :label The label for the field.
|
63
|
+
# @option options [ Boolean ] :encryption If the field contains encrypted data.
|
64
|
+
# @option options [ Symbol ] :decrypt_as Name of the getters and setters to generate to access the decrypted value of this field.
|
65
|
+
# @option options [ Object, Proc ] :default The field's default
|
66
|
+
#
|
67
|
+
# @return [ Field ] The generated field
|
68
|
+
def field_with_symmetric_encryption(field_name, options={})
|
69
|
+
if options.delete(:encrypted) == true
|
70
|
+
decrypt_as = options.delete(:decrypt_as)
|
71
|
+
unless decrypt_as
|
72
|
+
raise "Symmetric::Encryption for Mongoid. When encryption is enabled for a field it must either start with 'encrypted_' or the option :decrypt must be supplied" unless field_name.to_s.start_with?('encrypted_')
|
73
|
+
decrypt_as = field_name.to_s['encrypted_'.length..-1]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Store Intended data type for this field, but we store it as a String
|
77
|
+
underlying_type = options[:type]
|
78
|
+
options[:type] = String
|
79
|
+
|
80
|
+
raise "Symmetric::Encryption for Mongoid currently only supports :type => String" unless underlying_type == String
|
81
|
+
|
82
|
+
# #TODO Need to do type conversions. Currently only support String
|
83
|
+
|
84
|
+
# Generate getter and setter methods
|
85
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
86
|
+
# Set the un-encrypted bank account number
|
87
|
+
# Also updates the encrypted field with the encrypted value
|
88
|
+
def #{decrypt_as}=(value)
|
89
|
+
@stored_#{field_name} = Symmetric::Encryption.encrypt(value)
|
90
|
+
self.#{field_name} = @stored_#{field_name}
|
91
|
+
@#{decrypt_as} = value
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns the decrypted value for the encrypted field
|
95
|
+
# The decrypted value is cached and is only decrypted if the encrypted value has changed
|
96
|
+
# If this method is not called, then the encrypted value is never decrypted
|
97
|
+
def #{decrypt_as}
|
98
|
+
if @stored_#{field_name} != self.#{field_name}
|
99
|
+
@#{decrypt_as} = Symmetric::Encryption.decrypt(self.#{field_name})
|
100
|
+
@stored_#{field_name} = self.#{field_name}
|
101
|
+
end
|
102
|
+
@#{decrypt_as}
|
103
|
+
end
|
104
|
+
EOS
|
105
|
+
end
|
106
|
+
|
107
|
+
# Pass on to the regular Mongoid field method
|
108
|
+
field_without_symmetric_encryption(field_name, options)
|
109
|
+
end
|
110
|
+
alias_method_chain :field, :symmetric_encryption
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
data/lib/symmetric/version.rb
CHANGED
Binary file
|
data/test/attr_encrypted_test.rb
CHANGED
@@ -6,7 +6,9 @@ require 'logger'
|
|
6
6
|
require 'erb'
|
7
7
|
require 'test/unit'
|
8
8
|
require 'shoulda'
|
9
|
+
# Since we want both the AR and Mongoid extensions loaded we need to require them first
|
9
10
|
require 'active_record'
|
11
|
+
require 'mongoid'
|
10
12
|
require 'symmetric-encryption'
|
11
13
|
|
12
14
|
ActiveRecord::Base.logger = Logger.new($stderr)
|
@@ -17,6 +19,7 @@ ActiveRecord::Schema.define :version => 0 do
|
|
17
19
|
create_table :users, :force => true do |t|
|
18
20
|
t.string :encrypted_bank_account_number
|
19
21
|
t.string :encrypted_social_security_number
|
22
|
+
t.string :name
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
@@ -28,117 +31,141 @@ class User < ActiveRecord::Base
|
|
28
31
|
validates :encrypted_social_security_number, :symmetric_encrypted => true
|
29
32
|
end
|
30
33
|
|
34
|
+
# Load Symmetric Encryption keys
|
35
|
+
Symmetric::Encryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
36
|
+
|
37
|
+
# Initialize the database connection
|
38
|
+
config_file = File.join(File.dirname(__FILE__), 'config', 'database.yml')
|
39
|
+
raise "database config not found. Create a config file at: test/config/database.yml" unless File.exists? config_file
|
40
|
+
|
41
|
+
cfg = YAML.load(ERB.new(File.new(config_file).read).result)['test']
|
42
|
+
raise("Environment 'test' not defined in test/config/database.yml") unless cfg
|
43
|
+
|
44
|
+
User.establish_connection(cfg)
|
45
|
+
|
31
46
|
#
|
32
47
|
# Unit Test for attr_encrypted and validation aspects of Symmetric::Encryption
|
33
48
|
#
|
34
|
-
|
35
49
|
class AttrEncryptedTest < Test::Unit::TestCase
|
36
|
-
context '
|
50
|
+
context 'the Symmetric::Encryption Library' do
|
37
51
|
|
38
52
|
setup do
|
39
|
-
|
53
|
+
@bank_account_number = "1234567890"
|
54
|
+
@bank_account_number_encrypted = "L94ArJeFlJrZp6SYsvoOGA==\n"
|
55
|
+
|
56
|
+
@social_security_number = "987654321"
|
57
|
+
@social_security_number_encrypted = "S+8X1NRrqdfEIQyFHVPuVA==\n"
|
58
|
+
|
59
|
+
@user = User.new(
|
60
|
+
# Encrypted Attribute
|
61
|
+
:bank_account_number => @bank_account_number,
|
62
|
+
# Encrypted Attribute
|
63
|
+
:social_security_number => @social_security_number
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
should "have encrypted methods" do
|
68
|
+
assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
|
69
|
+
assert_equal true, @user.respond_to?(:bank_account_number)
|
70
|
+
assert_equal true, @user.respond_to?(:encrypted_social_security_number)
|
71
|
+
assert_equal true, @user.respond_to?(:social_security_number)
|
72
|
+
assert_equal false, @user.respond_to?(:encrypted_name)
|
73
|
+
end
|
74
|
+
|
75
|
+
should "have unencrypted values" do
|
76
|
+
assert_equal @bank_account_number, @user.bank_account_number
|
77
|
+
assert_equal @social_security_number, @user.social_security_number
|
40
78
|
end
|
41
79
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
should "have encrypted methods" do
|
71
|
-
assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
|
72
|
-
assert_equal true, @user.respond_to?(:bank_account_number)
|
73
|
-
assert_equal true, @user.respond_to?(:encrypted_social_security_number)
|
74
|
-
assert_equal true, @user.respond_to?(:social_security_number)
|
75
|
-
assert_equal false, @user.respond_to?(:encrypted_name)
|
76
|
-
end
|
77
|
-
|
78
|
-
should "have unencrypted values" do
|
79
|
-
assert_equal @bank_account_number, @user.bank_account_number
|
80
|
-
assert_equal @social_security_number, @user.social_security_number
|
81
|
-
end
|
82
|
-
|
83
|
-
should "have encrypted values" do
|
84
|
-
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
85
|
-
assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
|
86
|
-
end
|
87
|
-
|
88
|
-
should "encrypt" do
|
89
|
-
user = User.new
|
90
|
-
user.bank_account_number = @bank_account_number
|
91
|
-
assert_equal @bank_account_number, user.bank_account_number
|
92
|
-
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
93
|
-
end
|
94
|
-
|
95
|
-
should "allow lookups using unencrypted or encrypted column name" do
|
96
|
-
@user.save!
|
97
|
-
|
98
|
-
inq = User.find_by_bank_account_number(@bank_account_number)
|
99
|
-
assert_equal @bank_account_number, inq.bank_account_number
|
100
|
-
assert_equal @bank_account_number_encrypted, inq.encrypted_bank_account_number
|
101
|
-
|
102
|
-
@user.delete
|
103
|
-
end
|
104
|
-
|
105
|
-
should "return encrypted attributes for the class" do
|
106
|
-
expect = {:social_security_number=>:encrypted_social_security_number, :bank_account_number=>:encrypted_bank_account_number}
|
107
|
-
result = User.encrypted_attributes
|
108
|
-
expect.each_pair {|k,v| assert_equal expect[k], result[k]}
|
109
|
-
end
|
110
|
-
|
111
|
-
should "return encrypted keys for the class" do
|
112
|
-
expect = [:social_security_number, :bank_account_number]
|
113
|
-
result = User.encrypted_keys
|
114
|
-
expect.each {|val| assert_equal true, result.include?(val)}
|
115
|
-
|
116
|
-
# Also check encrypted_attribute?
|
117
|
-
expect.each {|val| assert_equal true, User.encrypted_attribute?(val)}
|
118
|
-
end
|
119
|
-
|
120
|
-
should "return encrypted columns for the class" do
|
121
|
-
expect = [:encrypted_social_security_number, :encrypted_bank_account_number]
|
122
|
-
result = User.encrypted_columns
|
123
|
-
expect.each {|val| assert_equal true, result.include?(val)}
|
124
|
-
|
125
|
-
# Also check encrypted_column?
|
126
|
-
expect.each {|val| assert_equal true, User.encrypted_column?(val)}
|
127
|
-
end
|
128
|
-
|
129
|
-
should "validate encrypted data" do
|
130
|
-
assert_equal true, @user.valid?
|
131
|
-
@user.encrypted_bank_account_number = '123'
|
132
|
-
assert_equal false, @user.valid?
|
133
|
-
assert_equal ["must be a value encrypted using Symmetric::Encryption.encrypt"], @user.errors[:encrypted_bank_account_number]
|
134
|
-
@user.encrypted_bank_account_number = Symmetric::Encryption.encrypt('123')
|
135
|
-
assert_equal true, @user.valid?
|
136
|
-
@user.bank_account_number = '123'
|
137
|
-
assert_equal true, @user.valid?
|
138
|
-
end
|
139
|
-
|
140
|
-
end
|
80
|
+
should "have encrypted values" do
|
81
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
82
|
+
assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
|
83
|
+
end
|
84
|
+
|
85
|
+
should "encrypt" do
|
86
|
+
user = User.new
|
87
|
+
user.bank_account_number = @bank_account_number
|
88
|
+
assert_equal @bank_account_number, user.bank_account_number
|
89
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
90
|
+
end
|
91
|
+
|
92
|
+
should "allow lookups using unencrypted or encrypted column name" do
|
93
|
+
@user.save!
|
94
|
+
|
95
|
+
inq = User.find_by_bank_account_number(@bank_account_number)
|
96
|
+
assert_equal @bank_account_number, inq.bank_account_number
|
97
|
+
assert_equal @bank_account_number_encrypted, inq.encrypted_bank_account_number
|
98
|
+
|
99
|
+
@user.delete
|
100
|
+
end
|
101
|
+
|
102
|
+
should "all paths should lead to the same result" do
|
103
|
+
assert_equal @bank_account_number_encrypted, (@user.encrypted_social_security_number = @bank_account_number_encrypted)
|
104
|
+
assert_equal @bank_account_number, @user.social_security_number
|
105
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
|
106
|
+
end
|
141
107
|
|
108
|
+
should "all paths should lead to the same result 2" do
|
109
|
+
assert_equal @bank_account_number, (@user.social_security_number = @bank_account_number)
|
110
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
|
111
|
+
assert_equal @bank_account_number, @user.social_security_number
|
142
112
|
end
|
113
|
+
|
114
|
+
should "all paths should lead to the same result, check uninitialized" do
|
115
|
+
user = User.new
|
116
|
+
assert_equal nil, user.social_security_number
|
117
|
+
assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
|
118
|
+
assert_equal @bank_account_number, user.social_security_number
|
119
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_social_security_number
|
120
|
+
|
121
|
+
assert_equal nil, (user.social_security_number = nil)
|
122
|
+
assert_equal nil, user.social_security_number
|
123
|
+
assert_equal nil, user.encrypted_social_security_number
|
124
|
+
end
|
125
|
+
|
126
|
+
should "allow unencrypted values to be passed to the constructor" do
|
127
|
+
user = User.new(:bank_account_number => @bank_account_number, :social_security_number => @social_security_number)
|
128
|
+
assert_equal @bank_account_number, user.bank_account_number
|
129
|
+
assert_equal @social_security_number, user.social_security_number
|
130
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
131
|
+
assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
|
132
|
+
end
|
133
|
+
|
134
|
+
should "return encrypted attributes for the class" do
|
135
|
+
expect = {:social_security_number=>:encrypted_social_security_number, :bank_account_number=>:encrypted_bank_account_number}
|
136
|
+
result = User.encrypted_attributes
|
137
|
+
expect.each_pair {|k,v| assert_equal expect[k], result[k]}
|
138
|
+
end
|
139
|
+
|
140
|
+
should "return encrypted keys for the class" do
|
141
|
+
expect = [:social_security_number, :bank_account_number]
|
142
|
+
result = User.encrypted_keys
|
143
|
+
expect.each {|val| assert_equal true, result.include?(val)}
|
144
|
+
|
145
|
+
# Also check encrypted_attribute?
|
146
|
+
expect.each {|val| assert_equal true, User.encrypted_attribute?(val)}
|
147
|
+
end
|
148
|
+
|
149
|
+
should "return encrypted columns for the class" do
|
150
|
+
expect = [:encrypted_social_security_number, :encrypted_bank_account_number]
|
151
|
+
result = User.encrypted_columns
|
152
|
+
expect.each {|val| assert_equal true, result.include?(val)}
|
153
|
+
|
154
|
+
# Also check encrypted_column?
|
155
|
+
expect.each {|val| assert_equal true, User.encrypted_column?(val)}
|
156
|
+
end
|
157
|
+
|
158
|
+
should "validate encrypted data" do
|
159
|
+
assert_equal true, @user.valid?
|
160
|
+
@user.encrypted_bank_account_number = '123'
|
161
|
+
assert_equal false, @user.valid?
|
162
|
+
assert_equal ["must be a value encrypted using Symmetric::Encryption.encrypt"], @user.errors[:encrypted_bank_account_number]
|
163
|
+
@user.encrypted_bank_account_number = Symmetric::Encryption.encrypt('123')
|
164
|
+
assert_equal true, @user.valid?
|
165
|
+
@user.bank_account_number = '123'
|
166
|
+
assert_equal true, @user.valid?
|
167
|
+
end
|
168
|
+
|
143
169
|
end
|
170
|
+
|
144
171
|
end
|
data/test/cipher_test.rb
CHANGED
@@ -48,6 +48,9 @@ class CipherTest < Test::Unit::TestCase
|
|
48
48
|
)
|
49
49
|
@social_security_number = "987654321"
|
50
50
|
@social_security_number_encrypted = "Qd0qzN6oVuATJQBTf8X6tg==\n"
|
51
|
+
@sample_data = [
|
52
|
+
{ :text => '555052345', :encrypted => ''}
|
53
|
+
]
|
51
54
|
end
|
52
55
|
|
53
56
|
should "default to 'aes-256-cbc'" do
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# Allow examples to be run in-place without requiring a gem install
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'logger'
|
6
|
+
require 'erb'
|
7
|
+
require 'test/unit'
|
8
|
+
require 'shoulda'
|
9
|
+
# Since we want both the AR and Mongoid extensions loaded we need to require them first
|
10
|
+
require 'active_record'
|
11
|
+
require 'mongoid'
|
12
|
+
require 'symmetric-encryption'
|
13
|
+
|
14
|
+
Mongoid.logger = Logger.new($stdout)
|
15
|
+
Mongoid.load!("test/config/mongoid.yml")
|
16
|
+
|
17
|
+
class MongoidUser
|
18
|
+
include Mongoid::Document
|
19
|
+
|
20
|
+
field :name, :type => String
|
21
|
+
field :encrypted_bank_account_number, :type => String, :encrypted => true
|
22
|
+
field :encrypted_social_security_number, :type => String, :encrypted => true
|
23
|
+
# field :encrypted_integer, :type => Integer, :encrypted => true
|
24
|
+
# field :encrypted_float, :type => Float, :encrypted => true
|
25
|
+
# field :encrypted_date, :type => Date, :encrypted => true
|
26
|
+
# etc...
|
27
|
+
|
28
|
+
# validates :encrypted_bank_account_number, :symmetric_encrypted => true
|
29
|
+
# validates :encrypted_social_security_number, :symmetric_encrypted => true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Load Symmetric Encryption keys
|
33
|
+
Symmetric::Encryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
34
|
+
|
35
|
+
#
|
36
|
+
# Unit Tests for field encrypted and validation aspects of Symmetric::Encryption
|
37
|
+
#
|
38
|
+
class FieldEncryptedTest < Test::Unit::TestCase
|
39
|
+
context 'the Symmetric::Encryption Library' do
|
40
|
+
setup do
|
41
|
+
@bank_account_number = "1234567890"
|
42
|
+
@bank_account_number_encrypted = "L94ArJeFlJrZp6SYsvoOGA==\n"
|
43
|
+
|
44
|
+
@social_security_number = "987654321"
|
45
|
+
@social_security_number_encrypted = "S+8X1NRrqdfEIQyFHVPuVA==\n"
|
46
|
+
|
47
|
+
@integer = 32768
|
48
|
+
@integer_encrypted = "FA3smFQEKqB/ITv+A0xACg==\n"
|
49
|
+
|
50
|
+
@float = 0.9867
|
51
|
+
@float_encrypted = "z7Pwt2JDp74d+u0IXFAdrQ==\n"
|
52
|
+
|
53
|
+
@date = Date.parse('20120320')
|
54
|
+
@date_encrypted = "WTkSPHo5ApSSHBJMxxWt2A==\n"
|
55
|
+
|
56
|
+
# #TODO Intercept passing in attributes to create etc.
|
57
|
+
@user = MongoidUser.new(
|
58
|
+
:encrypted_bank_account_number => @bank_account_number_encrypted,
|
59
|
+
:encrypted_social_security_number => @social_security_number_encrypted,
|
60
|
+
:encrypted_integer => @integer_encrypted,
|
61
|
+
:encrypted_float => @float_encrypted,
|
62
|
+
:encrypted_date => @date_encrypted,
|
63
|
+
:name => "Joe Bloggs"
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
should "have encrypted methods" do
|
68
|
+
assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
|
69
|
+
assert_equal true, @user.respond_to?(:bank_account_number)
|
70
|
+
assert_equal true, @user.respond_to?(:encrypted_social_security_number)
|
71
|
+
assert_equal true, @user.respond_to?(:social_security_number)
|
72
|
+
assert_equal false, @user.respond_to?(:encrypted_name)
|
73
|
+
end
|
74
|
+
|
75
|
+
should "have unencrypted values" do
|
76
|
+
assert_equal @bank_account_number, @user.bank_account_number
|
77
|
+
assert_equal @social_security_number, @user.social_security_number
|
78
|
+
end
|
79
|
+
|
80
|
+
should "have encrypted values" do
|
81
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
82
|
+
assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
|
83
|
+
end
|
84
|
+
|
85
|
+
should "encrypt" do
|
86
|
+
user = MongoidUser.new
|
87
|
+
user.bank_account_number = @bank_account_number
|
88
|
+
assert_equal @bank_account_number, user.bank_account_number
|
89
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
90
|
+
end
|
91
|
+
|
92
|
+
should "all paths should lead to the same result" do
|
93
|
+
assert_equal @bank_account_number_encrypted, (@user.encrypted_social_security_number = @bank_account_number_encrypted)
|
94
|
+
assert_equal @bank_account_number, @user.social_security_number
|
95
|
+
end
|
96
|
+
|
97
|
+
should "all paths should lead to the same result 2" do
|
98
|
+
assert_equal @bank_account_number, (@user.social_security_number = @bank_account_number)
|
99
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
|
100
|
+
end
|
101
|
+
|
102
|
+
should "all paths should lead to the same result, check uninitialized" do
|
103
|
+
user = MongoidUser.new
|
104
|
+
assert_equal nil, user.social_security_number
|
105
|
+
assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
|
106
|
+
assert_equal @bank_account_number, user.social_security_number
|
107
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_social_security_number
|
108
|
+
|
109
|
+
assert_equal nil, (user.social_security_number = nil)
|
110
|
+
assert_equal nil, user.social_security_number
|
111
|
+
assert_equal nil, user.encrypted_social_security_number
|
112
|
+
end
|
113
|
+
|
114
|
+
should "allow unencrypted values to be passed to the constructor" do
|
115
|
+
user = MongoidUser.new(:bank_account_number => @bank_account_number, :social_security_number => @social_security_number)
|
116
|
+
assert_equal @bank_account_number, user.bank_account_number
|
117
|
+
assert_equal @social_security_number, user.social_security_number
|
118
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
119
|
+
assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
|
120
|
+
end
|
121
|
+
|
122
|
+
should "allow both encrypted and unencrypted values to be passed to the constructor" do
|
123
|
+
user = MongoidUser.new(:encrypted_bank_account_number => @bank_account_number_encrypted, :social_security_number => @social_security_number)
|
124
|
+
assert_equal @bank_account_number, user.bank_account_number
|
125
|
+
assert_equal @social_security_number, user.social_security_number
|
126
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
127
|
+
assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
|
128
|
+
end
|
129
|
+
|
130
|
+
# should "support different data types" do
|
131
|
+
# assert_equal @integer, @user.integer
|
132
|
+
# assert_equal @integer_encrypted, @user.encrypted_integer
|
133
|
+
# end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Reid Morrison
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-03-
|
17
|
+
date: 2012-03-20 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- lib/symmetric/cipher.rb
|
33
33
|
- lib/symmetric/encryption.rb
|
34
34
|
- lib/symmetric/extensions/active_record/base.rb
|
35
|
+
- lib/symmetric/extensions/mongoid/fields.rb
|
35
36
|
- lib/symmetric/railtie.rb
|
36
37
|
- lib/symmetric/railties/symmetric_encrypted_validator.rb
|
37
38
|
- lib/symmetric/railties/symmetric_encryption.rake
|
@@ -47,15 +48,18 @@ files:
|
|
47
48
|
- Rakefile
|
48
49
|
- README.md
|
49
50
|
- symmetric-encryption-0.3.0.gem
|
51
|
+
- symmetric-encryption-0.3.1.gem
|
50
52
|
- test/attr_encrypted_test.rb
|
51
53
|
- test/cipher_test.rb
|
52
54
|
- test/config/database.yml
|
55
|
+
- test/config/mongoid.yml
|
53
56
|
- test/config/symmetric-encryption.yml
|
54
57
|
- test/config/test_new.iv
|
55
58
|
- test/config/test_new.key
|
56
59
|
- test/config/test_secondary_1.iv
|
57
60
|
- test/config/test_secondary_1.key
|
58
61
|
- test/encryption_test.rb
|
62
|
+
- test/field_encrypted_test.rb
|
59
63
|
has_rdoc: true
|
60
64
|
homepage: https://github.com/ClarityServices/symmetric-encryption
|
61
65
|
licenses: []
|