mongoid-encrypted-fields 1.2.2 → 1.3.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZmZkZTFkMzNjYzIwYTBkYWMxYzVmNzBlNjg2MjdiMWU4OGE2Njc0OA==
4
+ MmI2YWVkOGM2ZjlmOTY1NmQxMDJhNzNjMzhkNTdkZmVjNGY2NTA2Yw==
5
5
  data.tar.gz: !binary |-
6
- YmVjZTZmNGU4NDFiNzIwOTA4ZDdjZWE2M2I2Yjg0MThhMjYwOGU4Nw==
6
+ NmFkYzIzNjBlNWNjYTNmYTQ5NzI0ZjEwMzliODhkYjQ4NDUzYWI1ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- N2ViYzJlNGYzOTI1ZWY5NjQ5YjY3MWZjMTNmZjZhY2I3ZDIyMjMyYjJkMGJi
10
- MTgxNmEwNmNjOTE2MmZiOTU1NjU2NDkzNjE1MjFhMGE3YWYyN2I0NjZkZGVk
11
- ZjFkYmExNGY4NjM5MzVmNzJhMmU2YmIyZjc4MWI1OTNlZmM1MzQ=
9
+ MjI5MTUxMmY5NzEzMjRiYmZjZjZjM2Y1ZGVhOGI3MTUzYzhhYzlkNmJmOGJj
10
+ N2EzYzk0ZDM0NzQ4N2NlYzZjZTZiNjJjZmY2NWM4OWNlMThlNDhlNDZkMzlh
11
+ YWFmZDc5ODhlOTM4ZWQ4OTM2ZDcyZWQzNDlkM2JiOTExZDdkOGQ=
12
12
  data.tar.gz: !binary |-
13
- MjIyNDViMDdhYmY3OGE5NjNlMWIyZWQ1NjJiZWVkZmUxNWNkYmY0NzMwNmUw
14
- MzNkM2Y3ZTZlM2E2MmNjZmE2MzA2ODA4ZjZjMTk5M2RjMTUwYzIxMjgwYmE5
15
- Y2JmMDgzNDM2Njk2OTYxYWFmZDNjZTdlMTc1YmY5YTg1Njk5YzU=
13
+ NTVlOWZkNmNlZWI5OGU0NWE1NmNhMjZhNjFmODRiY2ZmMDBlMjYyZTFlZmI0
14
+ ZmRhNDY0NjY5YTc2YjZmNDVjNTI4OWIxYmU3MGRmMDQ3OTZjODMyOGNhNmZk
15
+ MDY4OTllMjJkOTJhMjA2YmYzMjMwZTUzZDlkNDNhYzI3NzU3OTI=
@@ -1,5 +1,9 @@
1
1
  # Revision history
2
2
 
3
+ ## 1.3.0 - Breaking change - PLEASE READ
4
+ * \#11 Support for Mongoid 4
5
+ * \#12 EncryptedHash will now stringify the keys before storing to be consistent with Mongoid's behavior
6
+
3
7
  ## 1.2.2
4
8
  * Accepted [pull request](https://github.com/KoanHealth/mongoid-encrypted-fields/pull/10) to support aliased fields with the uniqueness validator (@johnnyshields)
5
9
 
data/README.md CHANGED
@@ -12,8 +12,8 @@ Mongoid 3 supports [custom types](http://mongoid.org/en/mongoid/docs/documents.h
12
12
  Queries encrypt data before searching the database, so equality matches work automatically.
13
13
 
14
14
  ## Prerequisites
15
- * Ruby 1.9.3
16
- * [Mongoid](http://mongoid.org) 3.0
15
+ * >= Ruby 1.9.3
16
+ * >= [Mongoid](http://mongoid.org) 3.0
17
17
  * "Bring your own" encryption, see below
18
18
 
19
19
  ## Install
@@ -75,5 +75,9 @@ Queries encrypt data before searching the database, so equality matches work aut
75
75
  * Time
76
76
  * The uniqueness validator for encrypted fields is always case-sensitive. Using it with case-sensitive false raises an exception.
77
77
 
78
+ ## Related Articles
79
+ * [Storing Encrypted Data in MongoDB](http://jerryclinesmith.me/blog/2013/03/29/storing-encrypted-data-in-mongodb/)
80
+ * [Transparently Adding Encrypted Fields to a Rails App using Mongoid](http://blog.thesparktree.com/post/69538763994/transparently-adding-encrypted-fields-to-a-rails-app)
81
+
78
82
  ## Copyright
79
83
  (c) 2012 Koan Health. See LICENSE.txt for further details.
@@ -6,7 +6,6 @@ require 'mongoid-encrypted-fields/fields/encrypted_string'
6
6
  require 'mongoid-encrypted-fields/fields/encrypted_date'
7
7
  require 'mongoid-encrypted-fields/fields/encrypted_date_time'
8
8
  require 'mongoid-encrypted-fields/fields/encrypted_time'
9
- require 'mongoid-encrypted-fields/validations/uniqueness'
10
9
 
11
10
  module Mongoid
12
11
  module EncryptedFields
@@ -14,7 +13,21 @@ module Mongoid
14
13
  class << self
15
14
  # Set cipher used for all field encryption/decryption
16
15
  attr_accessor :cipher
16
+
17
+ def mongoid_major_version
18
+ @mongoid_major_version ||= ::Mongoid::VERSION[/([^\.]+)/].to_i
19
+ end
20
+
17
21
  end
18
22
 
19
23
  end
20
24
  end
25
+
26
+ case ::Mongoid::EncryptedFields.mongoid_major_version
27
+ when 3
28
+ require 'mongoid-encrypted-fields/mongoid3/validations/uniqueness'
29
+ when 4
30
+ require 'mongoid-encrypted-fields/mongoid4/validations/uniqueness'
31
+ else
32
+ raise "Unsupported version of Mongoid: #{::Mongoid::VERSION::MAJOR}"
33
+ end
@@ -10,7 +10,9 @@
10
10
  # p.address = {street: "123 Main St", city: "Springdale", state: "MD"}
11
11
  #
12
12
  # Get returns the unencrypted hash
13
- # puts p.address -> {:street=>"123 Main St", :city=>"Springdale", :state=>"MD"}
13
+ # puts p.address -> {'street'=>"123 Main St", 'city'=>"Springdale", 'state'=>"MD"}
14
+ #
15
+ # Note that symbols used as keys are converted to strings (just like using a Hash with Mongo)
14
16
  #
15
17
  # Use the encrypted property to see the encrypted value
16
18
  # puts p.address.encrypted -> '....'
@@ -22,7 +24,7 @@ module Mongoid
22
24
 
23
25
  # Return value to be encrypted
24
26
  def raw_value
25
- to_yaml
27
+ stringify_keys.to_yaml
26
28
  end
27
29
 
28
30
  class << self
@@ -1,13 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Mongoid
4
- module Validations # renamed to module Validatable in Mongoid 4.0
4
+ module Validations
5
5
 
6
6
  # Monkey-patch for Mongoid's uniqueness validator to enforce that the :case_sensitive option does not work
7
7
  # for encrypted fields; they must always be case-sensitive.
8
- #
9
8
  # Patch is confirmed to work on Mongoid >= 3.0.0
10
- # Should work in Mongoid >= 4.0.0 by renaming module Validations to Validatable
11
9
  class UniquenessValidator
12
10
 
13
11
  def setup_with_validation(klass)
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Mongoid
4
+ module Validatable
5
+
6
+ # Monkey-patch for Mongoid's uniqueness validator to enforce that the :case_sensitive option does not work
7
+ # for encrypted fields; they must always be case-sensitive.
8
+ # Patch is confirmed to work on Mongoid >= 4.0.0
9
+ class UniquenessValidator
10
+
11
+ def setup_with_validation(klass)
12
+ setup_without_validation(klass)
13
+ return if case_sensitive?
14
+ attributes.each do |attribute|
15
+ field_type = @klass.fields[@klass.database_field_name(attribute)].options[:type]
16
+ raise ArgumentError, "Encrypted field :#{attribute} cannot support case insensitive uniqueness" if field_type.method_defined?(:encrypted)
17
+ end
18
+ end
19
+
20
+ alias_method :setup_without_validation, :setup
21
+ alias_method :setup, :setup_with_validation
22
+
23
+ end
24
+ end
25
+ end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module EncryptedFields
3
- VERSION = '1.2.2'
3
+ VERSION = '1.3.0'
4
4
  end
5
5
  end
@@ -3,7 +3,4 @@ test:
3
3
  default:
4
4
  database: mongoid_encrypted_fields_test
5
5
  hosts:
6
- - localhost:27017
7
- options:
8
- safe: true
9
- consistency: :strong
6
+ - localhost:27017
@@ -40,7 +40,7 @@ module Mongoid
40
40
  it "encrypted hash should return unencrypted hash" do
41
41
  decrypted = subject.demongoize(encrypted)
42
42
  decrypted.is_a?(subject).should be_true
43
- decrypted.should eq(raw)
43
+ decrypted.should eq(raw.stringify_keys)
44
44
  end
45
45
 
46
46
  end
@@ -12,7 +12,7 @@ describe 'Single model' do
12
12
  let (:birth_date_encrypted) { Mongoid::EncryptedDate.mongoize(birth_date) }
13
13
  let (:address) { {street: '123 Main St', city: 'Anytown', state: 'TX' } }
14
14
  let (:address_encrypted) { Mongoid::EncryptedHash.mongoize(address) }
15
- let (:person) { Person.new(name: 'John Doe', ssn: ssn, birth_date: birth_date, address: address) }
15
+ let (:person) { Person.new(name: 'John Doe', ssn: ssn, birth_date: birth_date, address: address, duck_address: address) }
16
16
 
17
17
  it "model stores encrypted ssn" do
18
18
  person.attributes['ssn'].should eq(ssn_encrypted)
@@ -35,7 +35,7 @@ describe 'Single model' do
35
35
  end
36
36
 
37
37
  it "address getter returns raw value" do
38
- person.address.should eq(address)
38
+ person.address.should eq(address.stringify_keys)
39
39
  end
40
40
 
41
41
  describe "after save" do
@@ -67,9 +67,12 @@ describe 'Single model' do
67
67
  end
68
68
 
69
69
  it "encrypted address getter returns raw value" do
70
- @persisted.address.should eq(address)
70
+ @persisted.address.should eq(address.stringify_keys)
71
71
  end
72
72
 
73
+ it "encrypted address getter is equivalent to non-encrypted address getter" do
74
+ @persisted.address.should eq(@persisted.duck_address)
75
+ end
73
76
  end
74
77
 
75
78
  describe "find model by encrypted field" do
@@ -0,0 +1,153 @@
1
+ require "spec_helper"
2
+
3
+ if Mongoid::EncryptedFields.mongoid_major_version == 3
4
+ describe Mongoid::Validations::UniquenessValidator do
5
+
6
+ before(:all) do
7
+ Mongoid::EncryptedFields.cipher = GibberishCipher.new('my test password', 'weaksalt')
8
+ end
9
+
10
+ before(:each) do
11
+ Mongoid.purge!
12
+ Mongoid::IdentityMap.clear
13
+ end
14
+
15
+ describe "#valid?" do
16
+
17
+ let(:person) do
18
+ Person.new(name: "bill", ssn: "abc456789", credit_card: "12345678", phone_number: "12345678")
19
+ end
20
+
21
+ after do
22
+ Person.reset_callbacks(:validate)
23
+ end
24
+
25
+ context "when the value is in conflict" do
26
+
27
+ context "when the field is not encrypted" do
28
+
29
+ context "when the validation is case-sensitive" do
30
+
31
+ before do
32
+ Person.validates_uniqueness_of :name, case_sensitive: true
33
+ Person.create!(name: "bill")
34
+ end
35
+
36
+ it "correctly detects a uniqueness conflict" do
37
+ expect(person).to_not be_valid
38
+ end
39
+ end
40
+
41
+ context "when the validation is case-insensitive" do
42
+
43
+ before do
44
+ Person.validates_uniqueness_of :name, case_sensitive: false
45
+ Person.create!(name: "BiLl")
46
+ end
47
+
48
+ it "behaves as case-insensitive" do
49
+ expect(person).to_not be_valid
50
+ end
51
+ end
52
+ end
53
+
54
+ context "when the field is encrypted" do
55
+
56
+ context "when the validation is case-sensitive" do
57
+
58
+ before do
59
+ Person.validates_uniqueness_of :ssn
60
+ Person.create!(ssn: "abc456789")
61
+ end
62
+
63
+ it "behaves as case-sensitive" do
64
+ expect(person).not_to be_valid
65
+ end
66
+ end
67
+
68
+ context "when the validation is case-insensitive" do
69
+
70
+ it "throws an exception" do
71
+ expect { Person.validates_uniqueness_of :ssn, case_sensitive: false }.to raise_error 'Encrypted field :ssn cannot support case insensitive uniqueness'
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+
78
+ context "when the value is not conflict" do
79
+
80
+ context "when the field is not encrypted" do
81
+
82
+ before do
83
+ Person.validates_uniqueness_of :name
84
+ Person.create!(name: "ted")
85
+ end
86
+
87
+ it "correctly detects a uniqueness conflict" do
88
+ expect(person).to be_valid
89
+ end
90
+ end
91
+
92
+ context "when the field is encrypted" do
93
+
94
+ before do
95
+ Person.validates_uniqueness_of :ssn
96
+ Person.create!(ssn: "223456789")
97
+ end
98
+
99
+ it "correctly detects a uniqueness conflict" do
100
+ expect(person).to be_valid
101
+ end
102
+ end
103
+ end
104
+
105
+ context "when the field name is aliased" do
106
+
107
+ context "when the aliased name is used" do
108
+
109
+ context "when the field is encrypted" do
110
+
111
+ it "throws an exception" do
112
+ expect { Person.validates_uniqueness_of :credit_card, case_sensitive: false }.to raise_error 'Encrypted field :credit_card cannot support case insensitive uniqueness'
113
+ end
114
+ end
115
+
116
+ context "when the field is not encrypted" do
117
+
118
+ before do
119
+ Person.validates_uniqueness_of :phone_number, case_sensitive: false
120
+ Person.create!(phone_number: "12345678")
121
+ end
122
+
123
+ it "correctly detects a uniqueness conflict" do
124
+ expect(person).to_not be_valid
125
+ end
126
+ end
127
+ end
128
+
129
+ context "when the underlying name is used" do
130
+
131
+ context "when the field is encrypted" do
132
+
133
+ it "throws an exception" do
134
+ expect { Person.validates_uniqueness_of :cc, case_sensitive: false }.to raise_error 'Encrypted field :cc cannot support case insensitive uniqueness'
135
+ end
136
+ end
137
+
138
+ context "when the field is not encrypted" do
139
+
140
+ before do
141
+ Person.validates :ph, uniqueness: {case_sensitive: false}
142
+ Person.create!(phone_number: "12345678")
143
+ end
144
+
145
+ it "correctly detects a uniqueness conflict" do
146
+ expect(person).to_not be_valid
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,152 @@
1
+ require "spec_helper"
2
+
3
+ if Mongoid::EncryptedFields.mongoid_major_version == 4
4
+ describe Mongoid::Validatable::UniquenessValidator do
5
+
6
+ before(:all) do
7
+ Mongoid::EncryptedFields.cipher = GibberishCipher.new('my test password', 'weaksalt')
8
+ end
9
+
10
+ before(:each) do
11
+ Mongoid.purge!
12
+ end
13
+
14
+ describe "#valid?" do
15
+
16
+ let(:person) do
17
+ Person.new(name: "bill", ssn: "abc456789", credit_card: "12345678", phone_number: "12345678")
18
+ end
19
+
20
+ after do
21
+ Person.reset_callbacks(:validate)
22
+ end
23
+
24
+ context "when the value is in conflict" do
25
+
26
+ context "when the field is not encrypted" do
27
+
28
+ context "when the validation is case-sensitive" do
29
+
30
+ before do
31
+ Person.validates_uniqueness_of :name, case_sensitive: true
32
+ Person.create!(name: "bill")
33
+ end
34
+
35
+ it "correctly detects a uniqueness conflict" do
36
+ expect(person).to_not be_valid
37
+ end
38
+ end
39
+
40
+ context "when the validation is case-insensitive" do
41
+
42
+ before do
43
+ Person.validates_uniqueness_of :name, case_sensitive: false
44
+ Person.create!(name: "BiLl")
45
+ end
46
+
47
+ it "behaves as case-insensitive" do
48
+ expect(person).to_not be_valid
49
+ end
50
+ end
51
+ end
52
+
53
+ context "when the field is encrypted" do
54
+
55
+ context "when the validation is case-sensitive" do
56
+
57
+ before do
58
+ Person.validates_uniqueness_of :ssn
59
+ Person.create!(ssn: "abc456789")
60
+ end
61
+
62
+ it "behaves as case-sensitive" do
63
+ expect(person).not_to be_valid
64
+ end
65
+ end
66
+
67
+ context "when the validation is case-insensitive" do
68
+
69
+ it "throws an exception" do
70
+ expect { Person.validates_uniqueness_of :ssn, case_sensitive: false }.to raise_error 'Encrypted field :ssn cannot support case insensitive uniqueness'
71
+ end
72
+
73
+ end
74
+ end
75
+ end
76
+
77
+ context "when the value is not conflict" do
78
+
79
+ context "when the field is not encrypted" do
80
+
81
+ before do
82
+ Person.validates_uniqueness_of :name
83
+ Person.create!(name: "ted")
84
+ end
85
+
86
+ it "correctly detects a uniqueness conflict" do
87
+ expect(person).to be_valid
88
+ end
89
+ end
90
+
91
+ context "when the field is encrypted" do
92
+
93
+ before do
94
+ Person.validates_uniqueness_of :ssn
95
+ Person.create!(ssn: "223456789")
96
+ end
97
+
98
+ it "correctly detects a uniqueness conflict" do
99
+ expect(person).to be_valid
100
+ end
101
+ end
102
+ end
103
+
104
+ context "when the field name is aliased" do
105
+
106
+ context "when the aliased name is used" do
107
+
108
+ context "when the field is encrypted" do
109
+
110
+ it "throws an exception" do
111
+ expect { Person.validates_uniqueness_of :credit_card, case_sensitive: false }.to raise_error 'Encrypted field :credit_card cannot support case insensitive uniqueness'
112
+ end
113
+ end
114
+
115
+ context "when the field is not encrypted" do
116
+
117
+ before do
118
+ Person.validates_uniqueness_of :phone_number, case_sensitive: false
119
+ Person.create!(phone_number: "12345678")
120
+ end
121
+
122
+ it "correctly detects a uniqueness conflict" do
123
+ expect(person).to_not be_valid
124
+ end
125
+ end
126
+ end
127
+
128
+ context "when the underlying name is used" do
129
+
130
+ context "when the field is encrypted" do
131
+
132
+ it "throws an exception" do
133
+ expect { Person.validates_uniqueness_of :cc, case_sensitive: false }.to raise_error 'Encrypted field :cc cannot support case insensitive uniqueness'
134
+ end
135
+ end
136
+
137
+ context "when the field is not encrypted" do
138
+
139
+ before do
140
+ Person.validates :ph, uniqueness: {case_sensitive: false}
141
+ Person.create!(phone_number: "12345678")
142
+ end
143
+
144
+ it "correctly detects a uniqueness conflict" do
145
+ expect(person).to_not be_valid
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,11 +1,19 @@
1
- require 'rubygems'
2
1
  require 'bundler/setup'
2
+ require 'simplecov'
3
+
4
+ if ENV['TRAVIS']
5
+ require 'coveralls'
6
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
7
+ end
8
+
9
+ SimpleCov.start do
10
+ add_filter '/spec/'
11
+ add_filter '/examples/'
12
+ end
13
+
3
14
  require 'mongoid'
4
15
  require 'rspec'
5
16
 
6
- require 'coveralls'
7
- Coveralls.wear!
8
-
9
17
  require 'mongoid-encrypted-fields'
10
18
 
11
19
  Dir["#{File.dirname(__FILE__)}/../examples/**/*.rb"].each {|f| require f}
@@ -5,6 +5,7 @@ class Person
5
5
  field :ssn, type: Mongoid::EncryptedString
6
6
  field :birth_date, type: Mongoid::EncryptedDate
7
7
  field :address, type: Mongoid::EncryptedHash
8
+ field :duck_address, type: Hash
8
9
  field :ph, as: :phone_number, type: String
9
10
  field :cc, as: :credit_card, type: Mongoid::EncryptedString
10
11
 
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-encrypted-fields
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koan Health
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-13 00:00:00.000000000 Z
11
+ date: 2013-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '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'
27
27
  - !ruby/object:Gem::Dependency
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ! '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: A library for storing encrypted data in Mongo
98
112
  email:
99
113
  - development@koanhealth.com
@@ -101,20 +115,6 @@ executables: []
101
115
  extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
104
- - .coveralls.yml
105
- - .gitignore
106
- - .ruby-gemset
107
- - .ruby-version
108
- - .travis.yml
109
- - CHANGLOG.md
110
- - Gemfile
111
- - LICENSE.txt
112
- - README.md
113
- - Rakefile
114
- - examples/encrypted_strings_asymmetric_cipher.rb
115
- - examples/encrypted_strings_symmetric_cipher.rb
116
- - examples/gibberish_cipher.rb
117
- - lib/mongoid-encrypted-fields.rb
118
118
  - lib/mongoid-encrypted-fields/fields/encrypted_date.rb
119
119
  - lib/mongoid-encrypted-fields/fields/encrypted_date_time.rb
120
120
  - lib/mongoid-encrypted-fields/fields/encrypted_field.rb
@@ -122,9 +122,14 @@ files:
122
122
  - lib/mongoid-encrypted-fields/fields/encrypted_string.rb
123
123
  - lib/mongoid-encrypted-fields/fields/encrypted_time.rb
124
124
  - lib/mongoid-encrypted-fields/logging.rb
125
- - lib/mongoid-encrypted-fields/validations/uniqueness.rb
125
+ - lib/mongoid-encrypted-fields/mongoid3/validations/uniqueness.rb
126
+ - lib/mongoid-encrypted-fields/mongoid4/validations/uniqueness.rb
126
127
  - lib/mongoid-encrypted-fields/version.rb
127
- - mongoid-encrypted-fields.gemspec
128
+ - lib/mongoid-encrypted-fields.rb
129
+ - CHANGELOG.md
130
+ - LICENSE.txt
131
+ - README.md
132
+ - Rakefile
128
133
  - spec/config/mongoid.yml
129
134
  - spec/mongoid-encrypted-fields/fields/encrypted_date_spec.rb
130
135
  - spec/mongoid-encrypted-fields/fields/encrypted_datetime_spec.rb
@@ -133,11 +138,13 @@ files:
133
138
  - spec/mongoid-encrypted-fields/fields/encrypted_string_spec.rb
134
139
  - spec/mongoid-encrypted-fields/fields/encrypted_time_spec.rb
135
140
  - spec/mongoid-encrypted-fields/fields/model_spec.rb
136
- - spec/mongoid-encrypted-fields/validations/uniqueness_spec.rb
141
+ - spec/mongoid-encrypted-fields/mongoid3/validations/uniqueness_spec.rb
142
+ - spec/mongoid-encrypted-fields/mongoid4/validations/uniqueness_spec.rb
137
143
  - spec/spec_helper.rb
138
144
  - spec/support/models/person.rb
139
145
  homepage: https://github.com/KoanHealth/mongoid-encrypted-fields
140
- licenses: []
146
+ licenses:
147
+ - MIT
141
148
  metadata: {}
142
149
  post_install_message:
143
150
  rdoc_options: []
@@ -147,12 +154,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
154
  requirements:
148
155
  - - ! '>='
149
156
  - !ruby/object:Gem::Version
150
- version: '0'
157
+ version: '1.9'
151
158
  required_rubygems_version: !ruby/object:Gem::Requirement
152
159
  requirements:
153
160
  - - ! '>='
154
161
  - !ruby/object:Gem::Version
155
- version: '0'
162
+ version: 1.3.6
156
163
  requirements: []
157
164
  rubyforge_project:
158
165
  rubygems_version: 2.0.6
@@ -168,6 +175,7 @@ test_files:
168
175
  - spec/mongoid-encrypted-fields/fields/encrypted_string_spec.rb
169
176
  - spec/mongoid-encrypted-fields/fields/encrypted_time_spec.rb
170
177
  - spec/mongoid-encrypted-fields/fields/model_spec.rb
171
- - spec/mongoid-encrypted-fields/validations/uniqueness_spec.rb
178
+ - spec/mongoid-encrypted-fields/mongoid3/validations/uniqueness_spec.rb
179
+ - spec/mongoid-encrypted-fields/mongoid4/validations/uniqueness_spec.rb
172
180
  - spec/spec_helper.rb
173
181
  - spec/support/models/person.rb
data/.coveralls.yml DELETED
@@ -1 +0,0 @@
1
- service_name: travis-ci
data/.gitignore DELETED
@@ -1,23 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .sw?
6
- .yardoc
7
- .*.sw?
8
- Gemfile.lock
9
- InstalledFiles
10
- _yardoc
11
- coverage
12
- doc/
13
- lib/bundler/man
14
- pkg
15
- rdoc
16
- spec/reports
17
- test/tmp
18
- test/version_tmp
19
- tmp
20
-
21
- #Ignore IDEA directory
22
- /.idea
23
- .tags*
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- mongoid-encrypted-fields
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 1.9.3
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- bundler_args: --without development
3
- rvm:
4
- - 1.9.3
5
- notifications:
6
- recipients:
7
- - jerry.clinesmith@koanhealth.com
8
- services:
9
- - mongodb
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec
3
-
4
- gem 'rake'
5
- gem 'mongoid', '~> 3'
6
-
7
- gem 'coveralls', require: false
8
-
9
- group :test do
10
- gem 'rspec', '~> 2.13'
11
- gem 'gibberish', '~> 1.2.2'
12
- gem 'encrypted_strings', '~> 0.3'
13
- end
@@ -1,20 +0,0 @@
1
- require 'encrypted_strings'
2
-
3
- class EncryptedStringsAsymmetricCipher
4
-
5
- attr_reader :algorithm, :password, :public_key_file, :private_key_file
6
-
7
- def initialize(options = {})
8
- @options = options
9
- @options.each { |key, value| instance_variable_set "@#{key}", value }
10
- end
11
-
12
- def encrypt(data)
13
- data.encrypt(:asymmetric, @options)
14
- end
15
-
16
- def decrypt(data)
17
- data.decrypt(:asymmetric, @options)
18
- end
19
-
20
- end
@@ -1,20 +0,0 @@
1
- require 'encrypted_strings'
2
-
3
- class EncryptedStringsSymmetricCipher
4
-
5
- attr_reader :algorithm, :password
6
-
7
- def initialize(options = {})
8
- @options = options
9
- @options.each { |key, value| instance_variable_set "@#{key}", value }
10
- end
11
-
12
- def encrypt(data)
13
- data.encrypt(:symmetric, @options)
14
- end
15
-
16
- def decrypt(data)
17
- data.decrypt(:symmetric, @options)
18
- end
19
-
20
- end
@@ -1,20 +0,0 @@
1
- require 'gibberish/aes'
2
-
3
- # Gibberish uses a unique salt for every encryption, but we need the same text to return the same ciphertext
4
- # so Searching for encrypted field will work
5
- class GibberishCipher
6
-
7
- def initialize(password, salt)
8
- @cipher = Gibberish::AES.new(password)
9
- @salt = salt
10
- end
11
-
12
- def encrypt(data)
13
- @cipher.encrypt(data, salt: @salt)
14
- end
15
-
16
- def decrypt(data)
17
- @cipher.decrypt(data)
18
- end
19
-
20
- end
@@ -1,27 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'mongoid-encrypted-fields/version'
5
-
6
- Gem::Specification.new do |gem|
7
- gem.name = 'mongoid-encrypted-fields'
8
- gem.version = Mongoid::EncryptedFields::VERSION
9
- gem.authors = ['Koan Health']
10
- gem.email = ['development@koanhealth.com']
11
- gem.description = 'A library for storing encrypted data in Mongo'
12
- gem.summary = 'Custom types for storing encrypted data'
13
- gem.homepage = 'https://github.com/KoanHealth/mongoid-encrypted-fields'
14
-
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ['lib']
19
-
20
- gem.add_dependency 'mongoid', '~> 3'
21
-
22
- gem.add_development_dependency 'rake'
23
- gem.add_development_dependency 'rspec'
24
- gem.add_development_dependency 'gibberish', '~> 1.2.2'
25
- gem.add_development_dependency 'encrypted_strings', '~> 0.3'
26
- gem.add_development_dependency 'coveralls'
27
- end
@@ -1,151 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Validations::UniquenessValidator do
4
-
5
- before(:all) do
6
- Mongoid::EncryptedFields.cipher = GibberishCipher.new('my test password', 'weaksalt')
7
- end
8
-
9
- before(:each) do
10
- Mongoid.purge!
11
- Mongoid::IdentityMap.clear
12
- end
13
-
14
- describe "#valid?" do
15
-
16
- let(:person) do
17
- Person.new(name: "bill", ssn: "abc456789", credit_card: "12345678", phone_number: "12345678")
18
- end
19
-
20
- after do
21
- Person.reset_callbacks(:validate)
22
- end
23
-
24
- context "when the value is in conflict" do
25
-
26
- context "when the field is not encrypted" do
27
-
28
- context "when the validation is case-sensitive" do
29
-
30
- before do
31
- Person.validates_uniqueness_of :name, case_sensitive: true
32
- Person.create!(name: "bill")
33
- end
34
-
35
- it "correctly detects a uniqueness conflict" do
36
- expect(person).to_not be_valid
37
- end
38
- end
39
-
40
- context "when the validation is case-insensitive" do
41
-
42
- before do
43
- Person.validates_uniqueness_of :name, case_sensitive: false
44
- Person.create!(name: "BiLl")
45
- end
46
-
47
- it "behaves as case-insensitive" do
48
- expect(person).to_not be_valid
49
- end
50
- end
51
- end
52
-
53
- context "when the field is encrypted" do
54
-
55
- context "when the validation is case-sensitive" do
56
-
57
- before do
58
- Person.validates_uniqueness_of :ssn
59
- Person.create!(ssn: "abc456789")
60
- end
61
-
62
- it "behaves as case-sensitive" do
63
- expect(person).not_to be_valid
64
- end
65
- end
66
-
67
- context "when the validation is case-insensitive" do
68
-
69
- it "throws an exception" do
70
- expect { Person.validates_uniqueness_of :ssn, case_sensitive: false }.to raise_error 'Encrypted field :ssn cannot support case insensitive uniqueness'
71
- end
72
-
73
- end
74
- end
75
- end
76
-
77
- context "when the value is not conflict" do
78
-
79
- context "when the field is not encrypted" do
80
-
81
- before do
82
- Person.validates_uniqueness_of :name
83
- Person.create!(name: "ted")
84
- end
85
-
86
- it "correctly detects a uniqueness conflict" do
87
- expect(person).to be_valid
88
- end
89
- end
90
-
91
- context "when the field is encrypted" do
92
-
93
- before do
94
- Person.validates_uniqueness_of :ssn
95
- Person.create!(ssn: "223456789")
96
- end
97
-
98
- it "correctly detects a uniqueness conflict" do
99
- expect(person).to be_valid
100
- end
101
- end
102
- end
103
-
104
- context "when the field name is aliased" do
105
-
106
- context "when the aliased name is used" do
107
-
108
- context "when the field is encrypted" do
109
-
110
- it "throws an exception" do
111
- expect { Person.validates_uniqueness_of :credit_card, case_sensitive: false }.to raise_error 'Encrypted field :credit_card cannot support case insensitive uniqueness'
112
- end
113
- end
114
-
115
- context "when the field is not encrypted" do
116
-
117
- before do
118
- Person.validates_uniqueness_of :phone_number, case_sensitive: false
119
- Person.create!(phone_number: "12345678")
120
- end
121
-
122
- it "correctly detects a uniqueness conflict" do
123
- expect(person).to_not be_valid
124
- end
125
- end
126
- end
127
-
128
- context "when the underlying name is used" do
129
-
130
- context "when the field is encrypted" do
131
-
132
- it "throws an exception" do
133
- expect { Person.validates_uniqueness_of :cc, case_sensitive: false }.to raise_error 'Encrypted field :cc cannot support case insensitive uniqueness'
134
- end
135
- end
136
-
137
- context "when the field is not encrypted" do
138
-
139
- before do
140
- Person.validates :ph, uniqueness: { case_sensitive: false }
141
- Person.create!(phone_number: "12345678")
142
- end
143
-
144
- it "correctly detects a uniqueness conflict" do
145
- expect(person).to_not be_valid
146
- end
147
- end
148
- end
149
- end
150
- end
151
- end