mongoid-encrypted-fields 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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