attr_encrypted-magicless 1.3.42

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