symmetric-encryption 0.3.1 → 0.4.0
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/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: []
|