encrypted_search_attributes 1.0.1 → 1.1.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.
- checksums.yaml +5 -13
- data/README.md +37 -7
- data/lib/encrypted_search_attributes/extensions/active_record/base.rb +28 -7
- data/lib/encrypted_search_attributes/version.rb +1 -1
- data/spec/acceptance/attr_encrypted_search_spec.rb +9 -0
- data/spec/acceptance/custom_method_normalizer_spec.rb +91 -0
- data/spec/acceptance/custom_proc_normalizer_spec.rb +85 -0
- metadata +22 -18
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YWQ3YzYzMzc5ZjQ0Y2I5MmU0ZWE1NjRhMjM1MzY5NWE4MDM4NTEzNg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 71c31041e7631bfc6e189c0b2b88fff33ed376f6
|
4
|
+
data.tar.gz: af0c66f1efec431a32218112b929fd57661b2ba7
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZDBhZTMwMzZmNzMwN2FlZTNhYzkwYzE3Y2FiMTdiZjA2Mzg3NGY5MzA3NTYz
|
11
|
-
NDhhYjJkMDAxMzVkMGU5ZTViMTM3MGMyM2E1NGU5NGNmNjYyYTU=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MmJmMTUzOTMzYjI2Y2U2ZTFhNDM2ZGVhZjdjYTE5M2EzNGRhYmUwM2I5MTEw
|
14
|
-
OTAxMGMwNWM3OWUwYWM5MTFjODJiMDkyMTQxM2YwZDEwMTZiNGQyMjk5M2Q3
|
15
|
-
ZWI2NGI0M2ZlZjdlMzYyMjQ3MzY0OTViYzkyNGJmNzc0ZDE2NmE=
|
6
|
+
metadata.gz: 64acc8baadd3c6bf1976ec71455b8db26a3d7d35b69ae56c0e75b63902e9fc636a482b16e442194e352df83c42bafca0a1eded48800be4c5cb93251f39953f28
|
7
|
+
data.tar.gz: d1ba0cde85f8fcf68f9e9d8d19dd55eb631a1d03e5fbf9238b28a380633b71def5d58da66d8ee88830f559767638691d36eeec8b4a9384dfc5bdef123557b6f7
|
data/README.md
CHANGED
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
Auto populates encrypted fields that are designed for searching
|
4
4
|
|
5
|
-
Encrypting a field makes it very difficult to perform a case insensitive search for the columns data. This gem normalizes the text before encrypted it and storing it in a search column. The
|
5
|
+
Encrypting a field makes it very difficult to perform a case insensitive search for the columns data. This gem normalizes the text before encrypted it and storing it in a search column. The default normalization method is to convert the text to all lowercase, but you can specify your own normalization method.
|
6
6
|
|
7
7
|
This gem is intended to be used with the symmetric-encryption gem. It assumes that a `encrypted_search_attribute` column exists for the encrypted attribute.
|
8
8
|
|
9
|
-
##
|
9
|
+
## Examples
|
10
|
+
|
11
|
+
### Using the default normalization method
|
10
12
|
|
11
13
|
Let's assume we have the following ActiveRecord model defined.
|
12
14
|
|
@@ -26,6 +28,38 @@ This would require the database schema to look something like this.
|
|
26
28
|
end
|
27
29
|
```
|
28
30
|
|
31
|
+
### Specifying a custom normalization method
|
32
|
+
|
33
|
+
You can specify custom normalizations in a couple of different ways
|
34
|
+
|
35
|
+
#### Procs
|
36
|
+
|
37
|
+
You can specify a proc that gets called to perform the normalization. This works well if you only have one field that you need to override the normalization for.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
class Widget < ActiveRecord::Base
|
41
|
+
attr_encrypted :name
|
42
|
+
attr_encrypted_search :name,
|
43
|
+
normalize: ->(unencrypted_value) { enencrypted_value.to_s.downcase.gsub('.', '') }
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
#### Symbol referencing a method
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
class Widget < ActiveRecord::Base
|
51
|
+
attr_encrypted :name
|
52
|
+
attr_encrypted_search :name,
|
53
|
+
normalize: :normalize_search_value
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def normalize_search_value(unencypted_value)
|
58
|
+
enencrypted_value.to_s.downcase.gsub('.', '')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
29
63
|
## Installation
|
30
64
|
|
31
65
|
Add this line to your application's Gemfile:
|
@@ -40,13 +74,9 @@ Or install it yourself as:
|
|
40
74
|
|
41
75
|
$ gem install encrypted_search_attributes
|
42
76
|
|
43
|
-
## Usage
|
44
|
-
|
45
|
-
TODO: Write usage instructions here
|
46
|
-
|
47
77
|
## Contributing
|
48
78
|
|
49
|
-
1. Fork it ( http://github.com/
|
79
|
+
1. Fork it ( http://github.com/corgibytes/encrypted_search_attributes/fork )
|
50
80
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
81
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
52
82
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -4,9 +4,10 @@ module ActiveRecord
|
|
4
4
|
def attr_encrypted_search(*params)
|
5
5
|
define_attribute_methods rescue nil
|
6
6
|
|
7
|
-
options
|
8
|
-
compress
|
9
|
-
type
|
7
|
+
options = params.last.is_a?(Hash) ? params.pop.dup : {}
|
8
|
+
compress = options.delete(:compress) || false
|
9
|
+
type = options.delete(:type) || :string
|
10
|
+
normalize = options.delete(:normalize)
|
10
11
|
|
11
12
|
raise "Invalid type: #{type.inspect}. Valid types: #{SymmetricEncryption::COERCION_TYPES.inspect}" unless SymmetricEncryption::COERCION_TYPES.include?(type)
|
12
13
|
|
@@ -20,14 +21,34 @@ module ActiveRecord
|
|
20
21
|
end
|
21
22
|
|
22
23
|
params.each do |attribute|
|
23
|
-
mod.module_eval
|
24
|
-
|
24
|
+
mod.module_eval do
|
25
|
+
define_method("#{attribute}=") do |value|
|
25
26
|
if value
|
26
|
-
|
27
|
+
send(
|
28
|
+
"encrypted_search_#{attribute}=",
|
29
|
+
::SymmetricEncryption.encrypt(
|
30
|
+
send("normalize_#{attribute}", value),
|
31
|
+
false,
|
32
|
+
compress,
|
33
|
+
type
|
34
|
+
)
|
35
|
+
)
|
27
36
|
end
|
28
37
|
super(value)
|
29
38
|
end
|
30
|
-
|
39
|
+
|
40
|
+
define_method("normalize_#{attribute}") do |value|
|
41
|
+
if normalize
|
42
|
+
if normalize.respond_to?(:call)
|
43
|
+
normalize.call(value)
|
44
|
+
else
|
45
|
+
send(normalize, value)
|
46
|
+
end
|
47
|
+
else
|
48
|
+
value.downcase
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
31
52
|
end
|
32
53
|
|
33
54
|
end
|
@@ -49,6 +49,15 @@ describe 'attr_encrypted_search' do
|
|
49
49
|
expect(widget.encrypted_search_name).to eq(search_value)
|
50
50
|
end
|
51
51
|
|
52
|
+
it 'correctly handles nil values' do
|
53
|
+
widget = Widget.create!(name: nil)
|
54
|
+
|
55
|
+
expect(widget.encrypted_search_name).to eq(nil)
|
56
|
+
|
57
|
+
widget.reload
|
58
|
+
expect(widget.encrypted_search_name).to eq(nil)
|
59
|
+
end
|
60
|
+
|
52
61
|
it 'sets encrypted search field on assignment' do
|
53
62
|
widget = Widget.create!
|
54
63
|
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
db_config_file = File.expand_path('../../config/database.yml', __FILE__)
|
4
|
+
encryption_config_file = File.expand_path('../../config/symmetric-encryption.yml', __FILE__)
|
5
|
+
|
6
|
+
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(db_config_file)).result)
|
7
|
+
ActiveRecord::Base.establish_connection('test')
|
8
|
+
|
9
|
+
ActiveRecord::Schema.define(version: 0) do
|
10
|
+
create_table :widget_with_custom_methods, force: true do |t|
|
11
|
+
t.string :encrypted_name
|
12
|
+
t.string :encrypted_search_name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class WidgetWithCustomMethod < ActiveRecord::Base
|
17
|
+
attr_encrypted :name
|
18
|
+
attr_encrypted_search :name,
|
19
|
+
normalize: :downcase_no_spaces
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def downcase_no_spaces(value)
|
24
|
+
value.downcase.gsub(' ', '')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
SymmetricEncryption.load!(encryption_config_file, 'test')
|
29
|
+
|
30
|
+
# Initialize the database connection
|
31
|
+
config = YAML.load(ERB.new(File.new(db_config_file).read).result)['test']
|
32
|
+
|
33
|
+
WidgetWithCustomMethod.establish_connection(config)
|
34
|
+
|
35
|
+
describe 'custom method attr_encrypted_search' do
|
36
|
+
it 'sets encrypted search field on initialization' do
|
37
|
+
widget = WidgetWithCustomMethod.new(name: 'Test Value')
|
38
|
+
|
39
|
+
search_value = ::SymmetricEncryption.encrypt('testvalue')
|
40
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
41
|
+
|
42
|
+
widget.save!
|
43
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
44
|
+
|
45
|
+
widget.reload
|
46
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'sets the encrypted search field on creation' do
|
50
|
+
widget = WidgetWithCustomMethod.create!(name: 'Another Test')
|
51
|
+
|
52
|
+
search_value = ::SymmetricEncryption.encrypt('anothertest')
|
53
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
54
|
+
|
55
|
+
widget.reload
|
56
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'correctly handles nil values' do
|
60
|
+
widget = WidgetWithCustomMethod.create!(name: nil)
|
61
|
+
|
62
|
+
expect(widget.encrypted_search_name).to eq(nil)
|
63
|
+
|
64
|
+
widget.reload
|
65
|
+
expect(widget.encrypted_search_name).to eq(nil)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'sets encrypted search field on assignment' do
|
69
|
+
widget = WidgetWithCustomMethod.create!
|
70
|
+
|
71
|
+
widget.name = 'Something Else'
|
72
|
+
|
73
|
+
search_value = ::SymmetricEncryption.encrypt('somethingelse')
|
74
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
75
|
+
|
76
|
+
widget.save!
|
77
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
78
|
+
|
79
|
+
widget.reload
|
80
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'preserves attr_encrypted functionality' do
|
84
|
+
widget = WidgetWithCustomMethod.create!(name: 'Anything')
|
85
|
+
expect(widget.name).to eq('Anything')
|
86
|
+
expect(widget.encrypted_name).to eq(::SymmetricEncryption.encrypt('Anything'))
|
87
|
+
|
88
|
+
widget.reload
|
89
|
+
expect(widget.encrypted_name).to eq(::SymmetricEncryption.encrypt('Anything'))
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
db_config_file = File.expand_path('../../config/database.yml', __FILE__)
|
4
|
+
encryption_config_file = File.expand_path('../../config/symmetric-encryption.yml', __FILE__)
|
5
|
+
|
6
|
+
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(db_config_file)).result)
|
7
|
+
ActiveRecord::Base.establish_connection('test')
|
8
|
+
|
9
|
+
ActiveRecord::Schema.define(version: 0) do
|
10
|
+
create_table :widget_with_custom_procs, force: true do |t|
|
11
|
+
t.string :encrypted_name
|
12
|
+
t.string :encrypted_search_name
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class WidgetWithCustomProc < ActiveRecord::Base
|
17
|
+
attr_encrypted :name
|
18
|
+
attr_encrypted_search :name,
|
19
|
+
normalize: ->(value) { value.downcase.gsub(' ', '') }
|
20
|
+
end
|
21
|
+
|
22
|
+
SymmetricEncryption.load!(encryption_config_file, 'test')
|
23
|
+
|
24
|
+
# Initialize the database connection
|
25
|
+
config = YAML.load(ERB.new(File.new(db_config_file).read).result)['test']
|
26
|
+
|
27
|
+
WidgetWithCustomProc.establish_connection(config)
|
28
|
+
|
29
|
+
describe 'custom proc attr_encrypted_search' do
|
30
|
+
it 'sets encrypted search field on initialization' do
|
31
|
+
widget = WidgetWithCustomProc.new(name: 'Test Value')
|
32
|
+
|
33
|
+
search_value = ::SymmetricEncryption.encrypt('testvalue')
|
34
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
35
|
+
|
36
|
+
widget.save!
|
37
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
38
|
+
|
39
|
+
widget.reload
|
40
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'sets the encrypted search field on creation' do
|
44
|
+
widget = WidgetWithCustomProc.create!(name: 'Another Test')
|
45
|
+
|
46
|
+
search_value = ::SymmetricEncryption.encrypt('anothertest')
|
47
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
48
|
+
|
49
|
+
widget.reload
|
50
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'correctly handles nil values' do
|
54
|
+
widget = WidgetWithCustomProc.create!(name: nil)
|
55
|
+
|
56
|
+
expect(widget.encrypted_search_name).to eq(nil)
|
57
|
+
|
58
|
+
widget.reload
|
59
|
+
expect(widget.encrypted_search_name).to eq(nil)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'sets encrypted search field on assignment' do
|
63
|
+
widget = WidgetWithCustomProc.create!
|
64
|
+
|
65
|
+
widget.name = 'Something Else'
|
66
|
+
|
67
|
+
search_value = ::SymmetricEncryption.encrypt('somethingelse')
|
68
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
69
|
+
|
70
|
+
widget.save!
|
71
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
72
|
+
|
73
|
+
widget.reload
|
74
|
+
expect(widget.encrypted_search_name).to eq(search_value)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'preserves attr_encrypted functionality' do
|
78
|
+
widget = WidgetWithCustomProc.create!(name: 'Anything')
|
79
|
+
expect(widget.name).to eq('Anything')
|
80
|
+
expect(widget.encrypted_name).to eq(::SymmetricEncryption.encrypt('Anything'))
|
81
|
+
|
82
|
+
widget.reload
|
83
|
+
expect(widget.encrypted_name).to eq(::SymmetricEncryption.encrypt('Anything'))
|
84
|
+
end
|
85
|
+
end
|
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encrypted_search_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- M. Scott Ford
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: symmetric-encryption
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 3.2.13
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.2.13
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.5'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '10.1'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '10.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 2.14.1
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 2.14.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: sqlite3
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 1.3.8
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 1.3.8
|
97
97
|
description: Encrypting a field makes it very difficult to perform a case insensitive
|
@@ -104,7 +104,7 @@ executables: []
|
|
104
104
|
extensions: []
|
105
105
|
extra_rdoc_files: []
|
106
106
|
files:
|
107
|
-
- .gitignore
|
107
|
+
- ".gitignore"
|
108
108
|
- Gemfile
|
109
109
|
- LICENSE.txt
|
110
110
|
- README.md
|
@@ -114,6 +114,8 @@ files:
|
|
114
114
|
- lib/encrypted_search_attributes/extensions/active_record/base.rb
|
115
115
|
- lib/encrypted_search_attributes/version.rb
|
116
116
|
- spec/acceptance/attr_encrypted_search_spec.rb
|
117
|
+
- spec/acceptance/custom_method_normalizer_spec.rb
|
118
|
+
- spec/acceptance/custom_proc_normalizer_spec.rb
|
117
119
|
- spec/config/database.yml
|
118
120
|
- spec/config/symmetric-encryption.yml
|
119
121
|
- spec/config/test_new.iv
|
@@ -131,22 +133,24 @@ require_paths:
|
|
131
133
|
- lib
|
132
134
|
required_ruby_version: !ruby/object:Gem::Requirement
|
133
135
|
requirements:
|
134
|
-
- -
|
136
|
+
- - ">="
|
135
137
|
- !ruby/object:Gem::Version
|
136
138
|
version: '0'
|
137
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
140
|
requirements:
|
139
|
-
- -
|
141
|
+
- - ">="
|
140
142
|
- !ruby/object:Gem::Version
|
141
143
|
version: '0'
|
142
144
|
requirements: []
|
143
145
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.
|
146
|
+
rubygems_version: 2.4.5
|
145
147
|
signing_key:
|
146
148
|
specification_version: 4
|
147
149
|
summary: Auto populates encrypted fields that are designed for searching
|
148
150
|
test_files:
|
149
151
|
- spec/acceptance/attr_encrypted_search_spec.rb
|
152
|
+
- spec/acceptance/custom_method_normalizer_spec.rb
|
153
|
+
- spec/acceptance/custom_proc_normalizer_spec.rb
|
150
154
|
- spec/config/database.yml
|
151
155
|
- spec/config/symmetric-encryption.yml
|
152
156
|
- spec/config/test_new.iv
|