crypt_keeper 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # CryptKeeper
1
+ [![Build Status](https://secure.travis-ci.org/jmazzi/crypt_keeper.png?branch=master)](http://travis-ci.org/jmazzi/crypt_keeper)
2
+
3
+ ![CryptKeeper](http://i.imgur.com/qf0aD.jpg)
4
+
5
+ # CryptKeeper
2
6
 
3
7
  Provides transparent encryption for ActiveRecord. It is encryption agnostic.
4
8
  You can guard your data with any encryption algorithm you want. All you need
@@ -22,21 +26,49 @@ simple that *just works*.
22
26
  ## Usage
23
27
 
24
28
  ```ruby
25
-
26
29
  class MyModel < ActiveRecord::Base
27
- crypt_keeper :field, :other_field, encryptor: CryptKeeperProviders::Aes,
28
- passphrase: 'super_good_password'
30
+ crypt_keeper :field, :other_field, :encryptor => :aes, :passphrase => 'super_good_password'
29
31
  end
30
32
 
31
33
  model = MyModel.new(field: 'sometext')
32
34
  model.save! #=> Your data is now encrypted
33
35
  model.field #=> 'sometext'
34
-
35
36
  ```
36
37
 
37
38
  It works with all persistences methods: `update_attribute`, `update_attributes`,
38
39
  and save.
39
40
 
41
+ ## Creating your own encryptor
42
+
43
+ Creating your own encryptor is easy. All you have to do is create a class
44
+ under the `CryptKeeperProviders` namespace, like this:
45
+
46
+ ```ruby
47
+ module CryptKeeperProviders
48
+ class MyEncryptor
49
+ def initialize(options ={})
50
+ end
51
+
52
+ def encrypt(value)
53
+ end
54
+
55
+ def decrypt(value)
56
+ end
57
+ end
58
+ end
59
+
60
+ ```
61
+
62
+ Just require your code and setup your model to use it. Just pass the class name
63
+ as an underscored symbol
64
+
65
+
66
+ ```ruby
67
+ class MyModel < ActiveRecord::Base
68
+ crypt_keeper :field, :other_field, :encryptor => :my_encryptor, :passphrase => 'super_good_password'
69
+ end
70
+ ```
71
+
40
72
  ## Installation
41
73
 
42
74
  Add this line to your application's Gemfile:
data/crypt_keeper.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_runtime_dependency 'activerecord', '>= 3.0'
19
19
  gem.add_runtime_dependency 'activesupport', '>= 3.0'
20
- gem.add_runtime_dependency 'crypt_keeper_providers', '~> 0.0.3'
20
+ gem.add_runtime_dependency 'crypt_keeper_providers', '~> 0.0.4'
21
21
 
22
22
  gem.add_development_dependency 'rspec', '~> 2.10.0'
23
23
  gem.add_development_dependency 'guard', '~> 1.2.0'
@@ -9,14 +9,14 @@ module CryptKeeper
9
9
  private
10
10
 
11
11
  # Private: Encrypt each crypt_keeper_fields
12
- def before_save_encrypt
12
+ def encrypt_callback
13
13
  crypt_keeper_fields.each do |field|
14
14
  self[field] = self.class.encrypt read_attribute(field)
15
15
  end
16
16
  end
17
17
 
18
18
  # Private: Decrypt each crypt_keeper_fields
19
- def after_save_decrypt
19
+ def decrypt_callback
20
20
  crypt_keeper_fields.each do |field|
21
21
  self[field] = self.class.decrypt read_attribute(field)
22
22
  end
@@ -33,8 +33,7 @@ module CryptKeeper
33
33
  # Example
34
34
  #
35
35
  # class MyModel < ActiveRecord::Base
36
- # crypt_keeper :field, :other_field, encryptor: CryptKeeperProviders::Aes,
37
- # passphrase: 'super_good_password'
36
+ # crypt_keeper :field, :other_field, :encryptor => :aes, :passphrase => 'super_good_password'
38
37
  # end
39
38
  #
40
39
  def crypt_keeper(*args)
@@ -64,21 +63,26 @@ module CryptKeeper
64
63
 
65
64
  # Private: An instance of the encryptor class
66
65
  def encryptor
67
- crypt_keeper_encryptor.new(crypt_keeper_options.dup)
66
+ @encryptor ||= encryptor_klass.new(crypt_keeper_options.dup)
67
+ end
68
+
69
+ # Private: The encryptor class
70
+ def encryptor_klass
71
+ @encryptor_klass ||= "CryptKeeperProviders::#{crypt_keeper_encryptor.to_s.camelize}".constantize
68
72
  end
69
73
 
70
74
  # Private: Ensure that the encryptor responds to new
71
75
  def ensure_valid_encryptor!
72
- unless crypt_keeper_encryptor.respond_to?(:new)
73
- raise "You must specify an encryption class `crypt_keeper encryptor: EncryptionClass`"
76
+ unless defined? encryptor_klass
77
+ raise "You must specify a valid encryptor `crypt_keeper :encryptor => :aes`"
74
78
  end
75
79
  end
76
80
 
77
81
  # Private: Define callbacks for encryption
78
82
  def define_crypt_keeper_callbacks
79
- after_save :after_save_decrypt
80
- after_find :after_save_decrypt
81
- before_save :before_save_encrypt
83
+ after_save :decrypt_callback
84
+ after_find :decrypt_callback
85
+ before_save :encrypt_callback
82
86
 
83
87
  crypt_keeper_fields.each do |field|
84
88
  ensure_field_is_encryptable! field
@@ -1,3 +1,3 @@
1
1
  module CryptKeeper
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
data/spec/model_spec.rb CHANGED
@@ -3,55 +3,33 @@ require 'spec_helper'
3
3
  module CryptKeeper
4
4
  describe Model do
5
5
  subject { SensitiveData }
6
- let(:encryptor) do
7
- mock('Encryptor').tap do |m|
8
- m.stub :new
9
- end
10
- end
11
-
12
6
  describe "#crypt_keeper" do
13
7
  context "Fields" do
14
8
  it "should set the fields" do
15
- subject.crypt_keeper :storage, :secret, encryptor: encryptor
9
+ subject.crypt_keeper :storage, :secret, encryptor: :fake_encryptor
16
10
  subject.crypt_keeper_fields.should == [:storage, :secret]
17
11
  end
18
12
 
19
13
  it "should raise an exception with wrong field type" do
20
14
  msg = ":name must be of type 'text' to be used for encryption"
21
- expect { subject.crypt_keeper :name, encryptor: encryptor }.to raise_error(ArgumentError, msg)
15
+ expect { subject.crypt_keeper :name, encryptor: :fake_encryptor }.to raise_error(ArgumentError, msg)
22
16
  end
23
17
  end
24
18
 
25
19
  context "Options" do
26
20
  it "should set the options" do
27
- subject.crypt_keeper :storage, :secret, key1: 1, key2: 2, encryptor: encryptor
21
+ subject.crypt_keeper :storage, :secret, key1: 1, key2: 2, encryptor: :fake_encryptor
28
22
  subject.crypt_keeper_options.should == { key1: 1, key2: 2 }
29
23
  end
30
24
  end
31
25
  end
32
26
 
33
27
  context "Encryption" do
34
- let(:encryptor) do
35
- Class.new do
36
- def initialize(options = {})
37
- @passphrase = options[:passphrase]
38
- end
39
-
40
- def encrypt(data)
41
- @passphrase + data.reverse
42
- end
43
-
44
- def decrypt(data)
45
- data.sub(/^#{@passphrase}/, '').reverse
46
- end
47
- end
48
- end
49
-
50
28
  let(:plain_text) { 'plain_text' }
51
29
  let(:cipher_text) { 'tooltxet_nialp' }
52
30
 
53
31
  before do
54
- SensitiveData.crypt_keeper :storage, passphrase: 'tool', encryptor: encryptor
32
+ SensitiveData.crypt_keeper :storage, passphrase: 'tool', encryptor: :encryptor
55
33
  end
56
34
 
57
35
  subject { SensitiveData.new }
@@ -59,7 +37,7 @@ module CryptKeeper
59
37
  describe "#encrypt" do
60
38
  it "should encrypt the data" do
61
39
  subject.storage = plain_text
62
- subject.stub :after_save_decrypt
40
+ subject.stub :decrypt_callback
63
41
  subject.save!
64
42
  subject.storage.should == cipher_text
65
43
  end
@@ -68,7 +46,7 @@ module CryptKeeper
68
46
  describe "#decrypt" do
69
47
  it "should decrypt the data" do
70
48
  subject.storage = cipher_text
71
- subject.stub :before_save_encrypt
49
+ subject.stub :encrypt_callback
72
50
  subject.save!
73
51
  subject.storage.should == plain_text
74
52
  end
@@ -0,0 +1,26 @@
1
+ # A fake class that does no encryption
2
+ module CryptKeeperProviders
3
+ class FakeEncryptor
4
+ def initialize(*args)
5
+ end
6
+ end
7
+ end
8
+
9
+ # This class embeds the passphrase in the beginning of the string
10
+ # and then reverses the 'plaintext'
11
+ module CryptKeeperProviders
12
+ class Encryptor
13
+ def initialize(options = {})
14
+ @passphrase = options[:passphrase]
15
+ end
16
+
17
+ def encrypt(data)
18
+ @passphrase + data.reverse
19
+ end
20
+
21
+ def decrypt(data)
22
+ data.sub(/^#{@passphrase}/, '').reverse
23
+ end
24
+ end
25
+ end
26
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crypt_keeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-07-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &6479720 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *6479720
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: activesupport
27
- requirement: &6478940 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,21 +37,31 @@ dependencies:
32
37
  version: '3.0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *6478940
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '3.0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: crypt_keeper_providers
38
- requirement: &6494620 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
42
52
  - !ruby/object:Gem::Version
43
- version: 0.0.3
53
+ version: 0.0.4
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *6494620
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.4
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: rspec
49
- requirement: &6493320 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: 2.10.0
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *6493320
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.10.0
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: guard
60
- requirement: &6490560 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ~>
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: 1.2.0
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *6490560
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.2.0
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: guard-rspec
71
- requirement: &6488360 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ~>
@@ -76,10 +101,15 @@ dependencies:
76
101
  version: 1.1.0
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *6488360
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.1.0
80
110
  - !ruby/object:Gem::Dependency
81
111
  name: rake
82
- requirement: &6502220 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
83
113
  none: false
84
114
  requirements:
85
115
  - - ~>
@@ -87,10 +117,15 @@ dependencies:
87
117
  version: 0.9.2.2
88
118
  type: :development
89
119
  prerelease: false
90
- version_requirements: *6502220
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 0.9.2.2
91
126
  - !ruby/object:Gem::Dependency
92
127
  name: sqlite3
93
- requirement: &6500300 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
94
129
  none: false
95
130
  requirements:
96
131
  - - ! '>='
@@ -98,7 +133,12 @@ dependencies:
98
133
  version: '0'
99
134
  type: :development
100
135
  prerelease: false
101
- version_requirements: *6500300
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
102
142
  description: Transparent encryption for ActiveRecord that isn't over-engineered
103
143
  email:
104
144
  - jmazzi@gmail.com
@@ -121,6 +161,7 @@ files:
121
161
  - spec/model_spec.rb
122
162
  - spec/spec_helper.rb
123
163
  - spec/support/active_record.rb
164
+ - spec/support/encryptors.rb
124
165
  homepage: ''
125
166
  licenses: []
126
167
  post_install_message:
@@ -135,7 +176,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
176
  version: '0'
136
177
  segments:
137
178
  - 0
138
- hash: -259501510008969600
179
+ hash: 2759538915342928512
139
180
  required_rubygems_version: !ruby/object:Gem::Requirement
140
181
  none: false
141
182
  requirements:
@@ -144,10 +185,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
185
  version: '0'
145
186
  segments:
146
187
  - 0
147
- hash: -259501510008969600
188
+ hash: 2759538915342928512
148
189
  requirements: []
149
190
  rubyforge_project:
150
- rubygems_version: 1.8.11
191
+ rubygems_version: 1.8.23
151
192
  signing_key:
152
193
  specification_version: 3
153
194
  summary: Transparent encryption for ActiveRecord that isn't over-engineered
@@ -155,3 +196,4 @@ test_files:
155
196
  - spec/model_spec.rb
156
197
  - spec/spec_helper.rb
157
198
  - spec/support/active_record.rb
199
+ - spec/support/encryptors.rb