attr_encrypted-magicless 1.3.42

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d5d7a845ee1490c1059e2422a1477e60b9e05b69
4
+ data.tar.gz: 39abf97b1b312557ae6b8882cce0c2329502c0f7
5
+ SHA512:
6
+ metadata.gz: 2f135436621000a8393118c9c477928d1d9c7bf2f4207c72497d57f5b04d6512f8658322990b8d0f1f39f145c15c14187b84f6d760253e8f52825b8c490d38f1
7
+ data.tar.gz: 1b751d8daa15e428aa57e9ff8b6a28972a5561cd3cad6528e8a6a8671024b91121dfb9d709f13ce8022b791d107a26e2d3bcd8c5dc111a192e6402ef77d279d8
@@ -0,0 +1,7 @@
1
+ .bundle
2
+ .DS_Store
3
+ .ruby-version
4
+ rdoc
5
+ pkg
6
+ Gemfile.lock
7
+ coverage
@@ -0,0 +1,6 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.3
5
+ env:
6
+ - ACTIVERECORD=4.2
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ ENV['ACTIVERECORD'] ||= '4.2'
4
+
5
+ gemspec
6
+
7
+ # support for testing with specific active record version
8
+ gem 'activerecord', "~> #{ENV['ACTIVERECORD']}" if ENV['ACTIVERECORD']
9
+ gem 'actionpack', "~> #{ENV['ACTIVERECORD']}" if ENV['ACTIVERECORD'] && ENV['ACTIVERECORD'] > '4.0'
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Sean Huber - shuber@huberry.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,336 @@
1
+ = attr_encrypted-magicless {<img src="https://travis-ci.org/estum/attr_encrypted.png" />}[https://travis-ci.org/estum/attr_encrypted]
2
+
3
+ Generates attr_accessors that encrypt and decrypt attributes transparently
4
+
5
+ It works with ANY class, however, you get a few extra features when you're using it with <tt>ActiveRecord</tt>.
6
+
7
+
8
+ == Installation
9
+
10
+ gem install attr_encrypted-magicless
11
+
12
+
13
+ == Usage
14
+
15
+ === Basic
16
+
17
+ Encrypting attributes has never been easier:
18
+
19
+ class User
20
+ include AttrEncrypted
21
+
22
+ attr_accessor :name
23
+ attr_encrypted :ssn, :key => 'a secret key'
24
+
25
+ def load
26
+ # loads the stored data
27
+ end
28
+
29
+ def save
30
+ # saves the :name and :encrypted_ssn attributes somewhere (e.g. filesystem, database, etc)
31
+ end
32
+ end
33
+
34
+ @user = User.new
35
+ @user.ssn = '123-45-6789'
36
+ @user.encrypted_ssn # returns the encrypted version of :ssn
37
+ @user.save
38
+
39
+ @user = User.load
40
+ @user.ssn # decrypts :encrypted_ssn and returns '123-45-6789'
41
+
42
+ The <tt>attr_encrypted</tt> method is also aliased as <tt>attr_encryptor</tt> to conform to Ruby's <tt>attr_</tt> naming conventions. I should have called this project <tt>attr_encryptor</tt> but it was too late when I realized it ='(.
43
+
44
+ === Adding required columns via database migration
45
+
46
+ By default, <tt>attr_encrypted</tt> uses the <tt>:single_iv_and_salt</tt>
47
+ encryption mode for compatibility with previous versions of the gem. This mode
48
+ uses a single IV and salt for each encrypted column. Create or modify your model
49
+ to add a column with the <tt>encrypted_</tt> prefix (which can be modified, see
50
+ below), e.g. <tt>encrypted_ssn</tt> via a migration like the following:
51
+
52
+ create_table :users do |t|
53
+ t.string :name
54
+ t.string :encrypted_ssn
55
+ t.timestamps
56
+ end
57
+
58
+ For enhanced security, you can use the <tt>:per_attribute_iv_and_salt</tt> mode.
59
+ This requires additional <tt>_salt</tt> and <tt>_iv</tt> columns with the
60
+ <tt>encrypted_</tt> prefix as follows and generates a unique salt and IV per
61
+ attribute:
62
+
63
+ create_table :users do |t|
64
+ t.string :name
65
+ t.string :encrypted_ssn
66
+ t.string :encrypted_ssn_salt
67
+ t.string :encrypted_ssn_iv
68
+ t.string :domain
69
+ t.timestamps
70
+ end
71
+
72
+ This mode is enabled by specifying a value of <tt>:per_attribute_iv_and_salt</tt>
73
+ via the <tt>:mode</tt> option as follows:
74
+
75
+ class User
76
+ include AttrEncrypted
77
+ attr_accessor :name
78
+ attr_encrypted :ssn, :key => 'a secret key', :mode => :per_attribute_iv_and_salt
79
+ end
80
+
81
+ Note that there are alternatives to storing the IV and salt in separate columns:
82
+ for example, see here[https://github.com/attr-encrypted/attr_encrypted/issues/118#issuecomment-45806629].
83
+ Note that migration from the old encryption scheme to the new is nontrivial. One
84
+ approach is described here[http://jjasonclark.com/switching_from_attr_encrypted_to_attr_encryptor],
85
+ though these instructions describe the now-defunct <tt>attr_encryptor</tt> gem
86
+ whose functionality has been merged into this project.
87
+
88
+ === Specifying the encrypted attribute name
89
+
90
+ By default, the encrypted attribute name is <tt>encrypted_#{attribute}</tt> (e.g. <tt>attr_encrypted :email</tt> would create an attribute named <tt>encrypted_email</tt>). So, if you're storing the encrypted attribute in the database, you need to make sure the <tt>encrypted_#{attribute}</tt> field exists in your table. You have a couple of options if you want to name your attribute something else.
91
+
92
+
93
+ ==== The <tt>:attribute</tt> option
94
+
95
+ You can simply pass the name of the encrypted attribute as the <tt>:attribute</tt> option:
96
+
97
+ class User
98
+ include AttrEncrypted
99
+ attr_encrypted :email, :key => 'a secret key', :attribute => 'email_encrypted'
100
+ end
101
+
102
+ This would generate an attribute named <tt>email_encrypted</tt>
103
+
104
+
105
+ ==== The <tt>:prefix</tt> and <tt>:suffix</tt> options
106
+
107
+ If you're planning on encrypting a few different attributes and you don't like the <tt>encrypted_#{attribute}</tt> naming convention then you can specify your own:
108
+
109
+ class User
110
+ include AttrEncrypted
111
+ attr_encrypted :email, :credit_card, :ssn, :key => 'a secret key', :prefix => 'secret_', :suffix => '_crypted'
112
+ end
113
+
114
+ This would generate the following attributes: <tt>secret_email_crypted</tt>, <tt>secret_credit_card_crypted</tt>, and <tt>secret_ssn_crypted</tt>.
115
+
116
+
117
+ === Encryption keys
118
+
119
+ Although a <tt>:key</tt> option may not be required (see custom encryptor below), it has a few special features
120
+
121
+
122
+ ==== Unique keys for each attribute
123
+
124
+ You can specify unique keys for each attribute if you'd like:
125
+
126
+ class User
127
+ include AttrEncrypted
128
+ attr_encrypted :email, :key => 'a secret key'
129
+ attr_encrypted :ssn, :key => 'a different secret key'
130
+ end
131
+
132
+
133
+ ==== Symbols representing instance methods as keys
134
+
135
+ If your class has an instance method that determines the encryption key to use, simply pass a symbol representing it like so:
136
+
137
+ class User
138
+ include AttrEncrypted
139
+ attr_encrypted :email, :key => :encryption_key
140
+
141
+ def encryption_key
142
+ # does some fancy logic and returns an encryption key
143
+ end
144
+ end
145
+
146
+
147
+ ==== Procs as keys
148
+
149
+ You can pass a proc/lambda object as the <tt>:key</tt> option as well:
150
+
151
+ class User
152
+ include AttrEncrypted
153
+ attr_encrypted :email, :key => proc { |user| user.key }
154
+ end
155
+
156
+ This can be used to create asymmetrical encryption by requiring users to provide their own encryption keys.
157
+
158
+
159
+ === Conditional encrypting
160
+
161
+ There may be times that you want to only encrypt when certain conditions are met. For example maybe you're using rails and you don't want to encrypt
162
+ attributes when you're in development mode. You can specify conditions like this:
163
+
164
+ class User < ActiveRecord::Base
165
+ attr_encrypted :email, :key => 'a secret key', :unless => Rails.env.development?
166
+ end
167
+
168
+ You can specify both <tt>:if</tt> and <tt>:unless</tt> options. If you pass a symbol representing an instance method then the result of the method will be evaluated. Any objects that respond to <tt>:call</tt> are evaluated as well.
169
+
170
+
171
+ === Custom encryptor
172
+
173
+ The <tt>Encryptor</tt> (see http://github.com/shuber/encryptor) class is used by default. You may use your own custom encryptor by specifying
174
+ the <tt>:encryptor</tt>, <tt>:encrypt_method</tt>, and <tt>:decrypt_method</tt> options
175
+
176
+ Lets suppose you'd like to use this custom encryptor class:
177
+
178
+ class SillyEncryptor
179
+ def self.silly_encrypt(options)
180
+ (options[:value] + options[:secret_key]).reverse
181
+ end
182
+
183
+ def self.silly_decrypt(options)
184
+ options[:value].reverse.gsub(/#{options[:secret_key]}$/, '')
185
+ end
186
+ end
187
+
188
+ Simply set up your class like so:
189
+
190
+ class User
191
+ include AttrEncrypted
192
+ attr_encrypted :email, :secret_key => 'a secret key', :encryptor => SillyEncryptor, :encrypt_method => :silly_encrypt, :decrypt_method => :silly_decrypt
193
+ end
194
+
195
+ Any options that you pass to <tt>attr_encrypted</tt> will be passed to the encryptor along with the <tt>:value</tt> option which contains the string to encrypt/decrypt. Notice it uses <tt>:secret_key</tt> instead of <tt>:key</tt>.
196
+
197
+
198
+ === Custom algorithms
199
+
200
+ The default <tt>Encryptor</tt> uses the standard ruby OpenSSL library. It's default algorithm is <tt>aes-256-cbc</tt>. You can modify this by passing the <tt>:algorithm</tt> option to the <tt>attr_encrypted</tt> call like so:
201
+
202
+ class User
203
+ include AttrEncrypted
204
+ attr_encrypted :email, :key => 'a secret key', :algorithm => 'bf'
205
+ end
206
+
207
+ Run <tt>openssl list-cipher-commands</tt> to view a list of algorithms supported on your platform. See http://github.com/shuber/encryptor for more information.
208
+
209
+ aes-128-cbc
210
+ aes-128-ecb
211
+ aes-192-cbc
212
+ aes-192-ecb
213
+ aes-256-cbc
214
+ aes-256-ecb
215
+ base64
216
+ bf
217
+ bf-cbc
218
+ bf-cfb
219
+ bf-ecb
220
+ bf-ofb
221
+ cast
222
+ cast-cbc
223
+ cast5-cbc
224
+ cast5-cfb
225
+ cast5-ecb
226
+ cast5-ofb
227
+ des
228
+ des-cbc
229
+ des-cfb
230
+ des-ecb
231
+ des-ede
232
+ des-ede-cbc
233
+ des-ede-cfb
234
+ des-ede-ofb
235
+ des-ede3
236
+ des-ede3-cbc
237
+ des-ede3-cfb
238
+ des-ede3-ofb
239
+ des-ofb
240
+ des3
241
+ desx
242
+ idea
243
+ idea-cbc
244
+ idea-cfb
245
+ idea-ecb
246
+ idea-ofb
247
+ rc2
248
+ rc2-40-cbc
249
+ rc2-64-cbc
250
+ rc2-cbc
251
+ rc2-cfb
252
+ rc2-ecb
253
+ rc2-ofb
254
+ rc4
255
+ rc4-40
256
+
257
+
258
+ === Default options
259
+
260
+ Let's imagine that you have a few attributes that you want to encrypt with different keys, but you don't like the <tt>encrypted_#{attribute}</tt> naming convention. Instead of having to define your class like this:
261
+
262
+ class User
263
+ include AttrEncrypted
264
+ attr_encrypted :email, :key => 'a secret key', :prefix => '', :suffix => '_crypted'
265
+ attr_encrypted :ssn, :key => 'a different secret key', :prefix => '', :suffix => '_crypted'
266
+ attr_encrypted :credit_card, :key => 'another secret key', :prefix => '', :suffix => '_crypted'
267
+ end
268
+
269
+ You can simply define some default options like so:
270
+
271
+ class User
272
+ include AttrEncrypted
273
+ attr_encrypted_options.merge!(:prefix => '', :suffix => '_crypted')
274
+ attr_encrypted :email, :key => 'a secret key'
275
+ attr_encrypted :ssn, :key => 'a different secret key'
276
+ attr_encrypted :credit_card, :key => 'another secret key'
277
+ end
278
+
279
+ This should help keep your classes clean and DRY.
280
+
281
+
282
+ === Encoding
283
+
284
+ You're probably going to be storing your encrypted attributes somehow (e.g. filesystem, database, etc) and may run into some issues trying to store a weird
285
+ encrypted string. I've had this problem myself using MySQL. You can simply pass the <tt>:encode</tt> option to automatically encode/decode when encrypting/decrypting.
286
+
287
+ class User
288
+ include AttrEncrypted
289
+ attr_encrypted :email, :key => 'some secret key', :encode => true
290
+ end
291
+
292
+ The default encoding is <tt>m*</tt> (base64). You can change this by setting <tt>:encode => 'some encoding'</tt>. See the <tt>Array#pack</tt> method at http://www.ruby-doc.org/core/classes/Array.html#M002245 for more encoding options.
293
+
294
+
295
+ === Marshaling
296
+
297
+ You may want to encrypt objects other than strings (e.g. hashes, arrays, etc). If this is the case, simply pass the <tt>:marshal</tt> option to automatically marshal when encrypting/decrypting.
298
+
299
+ class User
300
+ include AttrEncrypted
301
+ attr_encrypted :credentials, :key => 'some secret key', :marshal => true
302
+ end
303
+
304
+ You may also optionally specify <tt>:marshaler</tt>, <tt>:dump_method</tt>, and <tt>:load_method</tt> if you want to use something other than the default <tt>Marshal</tt> object.
305
+
306
+
307
+ === Encrypt/decrypt attribute methods
308
+
309
+ If you use the same key to encrypt every record (per attribute) like this:
310
+
311
+ class User
312
+ include AttrEncrypted
313
+ attr_encrypted :email, :key => 'a secret key'
314
+ end
315
+
316
+ Then you'll have these two class methods available for each attribute: <tt>User.encrypt_email(email_to_encrypt)</tt> and <tt>User.decrypt_email(email_to_decrypt)</tt>. This can be useful when you're using <tt>ActiveRecord</tt> (see below).
317
+
318
+
319
+ === ActiveRecord
320
+
321
+ If you're using this gem with <tt>ActiveRecord</tt>, you get a few extra features:
322
+
323
+
324
+ ==== Default options
325
+
326
+ For your convenience, the <tt>:encode</tt> option is set to true by default since you'll be storing everything in a database.
327
+
328
+
329
+ == Note on Patches/Pull Requests
330
+
331
+ * Fork the project.
332
+ * Make your feature addition or bug fix.
333
+ * Add tests for it. This is important so I don't break it in a
334
+ future version unintentionally.
335
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
336
+ * Send me a pull request. Bonus points for topic branches.
@@ -0,0 +1,24 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+ require "bundler/gem_tasks"
5
+
6
+ desc 'Test the attr_encrypted gem.'
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << 'lib'
9
+ t.pattern = 'test/**/*_test.rb'
10
+ t.verbose = true
11
+ end
12
+
13
+ desc 'Generate documentation for the attr_encrypted gem.'
14
+ RDoc::Task.new do |rdoc|
15
+ rdoc.main = "README.rdoc"
16
+ rdoc.rdoc_dir = "rdoc"
17
+ rdoc.title = 'attr_encrypted'
18
+ rdoc.options << '--line-numbers' << '--inline-source'
19
+ rdoc.rdoc_files.include('README*')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ desc 'Default: run unit tests.'
24
+ task :default => :test
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'attr_encrypted/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'attr_encrypted-magicless'
8
+ s.version = AttrEncrypted::VERSION
9
+
10
+ s.summary = 'Encrypt and decrypt attributes'
11
+ s.description = 'Generates attr_accessors that encrypt and decrypt attributes transparently'
12
+
13
+ s.authors = ['Sean Huber', 'S. Brent Faulkner', 'William Monk', 'Stephen Aghaulor']
14
+ s.email = ['shuber@huberry.com', 'sbfaulkner@gmail.com', 'billy.monk@gmail.com', 'saghaulor@gmail.com']
15
+ s.homepage = 'https://github.com/estum/attr_encrypted'
16
+
17
+ s.has_rdoc = false
18
+ s.rdoc_options = ['--line-numbers', '--inline-source', '--main', 'README.rdoc']
19
+
20
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|\.travis\.yml|\.gitignore)/}) }
21
+ s.bindir = 'exe'
22
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ s.require_paths = ['lib']
24
+ s.test_files = Dir['test/**/*']
25
+
26
+ s.add_dependency 'encryptor', '>= 1.3.0'
27
+ s.add_dependency 'activesupport', '>= 4.0', '< 5.0'
28
+
29
+ s.add_development_dependency 'bundler', '~> 1.10'
30
+ s.add_development_dependency 'rake', '~> 10.0'
31
+ s.add_development_dependency "rdoc"
32
+ s.add_development_dependency 'sqlite3'
33
+ s.add_development_dependency 'activerecord', '>= 4.0', '< 5.0'
34
+ s.add_development_dependency 'minitest'
35
+ s.add_development_dependency 'mocha', '~>1.0.0'
36
+ s.add_development_dependency 'simplecov'
37
+ s.add_development_dependency 'simplecov-rcov'
38
+ end