crypt_keeper 0.12.0 → 0.13.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.
- data/README.md +1 -0
- data/lib/crypt_keeper/provider/postgres_pgp.rb +4 -1
- data/lib/crypt_keeper/version.rb +1 -1
- data/spec/log_subscriber/mysql_aes_spec.rb +2 -2
- data/spec/log_subscriber/postgres_pgp_spec.rb +1 -1
- data/spec/model_spec.rb +2 -7
- data/spec/provider/postgres_pgp_spec.rb +19 -0
- data/spec/support/active_record.rb +18 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -99,6 +99,7 @@ There are two included encryptors.
|
|
99
99
|
`CREATE EXTENSION IF NOT EXISTS pgcrypto`
|
100
100
|
* ActiveRecord logs are [automatically](https://github.com/jmazzi/crypt_keeper/blob/master/lib/crypt_keeper/log_subscriber/postgres_pgp.rb)
|
101
101
|
filtered for you to protect senitive data from being logged.
|
102
|
+
* Custom options can be set through the `:pgcrypto_options`. E.g. `crypt_keeper :field, encryptor: :postgres_pgp, pgcrypto_options: 'compress-level=9'
|
102
103
|
|
103
104
|
## Requirements
|
104
105
|
|
@@ -5,6 +5,7 @@ module CryptKeeper
|
|
5
5
|
class PostgresPgp
|
6
6
|
include CryptKeeper::Helper::SQL
|
7
7
|
attr_accessor :key
|
8
|
+
attr_accessor :pgcrypto_options
|
8
9
|
|
9
10
|
# Public: Initializes the encryptor
|
10
11
|
#
|
@@ -15,13 +16,15 @@ module CryptKeeper
|
|
15
16
|
@key = options.fetch(:key) do
|
16
17
|
raise ArgumentError, "Missing :key"
|
17
18
|
end
|
19
|
+
|
20
|
+
@pgcrypto_options = options.fetch(:pgcrypto_options, '')
|
18
21
|
end
|
19
22
|
|
20
23
|
# Public: Encrypts a string
|
21
24
|
#
|
22
25
|
# Returns an encrypted string
|
23
26
|
def encrypt(value)
|
24
|
-
escape_and_execute_sql(["SELECT pgp_sym_encrypt(?, ?)", value.to_s, key])['pgp_sym_encrypt']
|
27
|
+
escape_and_execute_sql(["SELECT pgp_sym_encrypt(?, ?, ?)", value.to_s, key, pgcrypto_options])['pgp_sym_encrypt']
|
25
28
|
end
|
26
29
|
|
27
30
|
# Public: Decrypts a string
|
data/lib/crypt_keeper/version.rb
CHANGED
@@ -12,7 +12,7 @@ module CryptKeeper::LogSubscriber
|
|
12
12
|
subject { ::ActiveRecord::LogSubscriber.new }
|
13
13
|
|
14
14
|
let(:input_query) do
|
15
|
-
"SELECT AES_ENCRYPT('encrypt_value', 'encrypt_key'),
|
15
|
+
"SELECT AES_ENCRYPT('encrypt_value', 'encrypt_key'), AES_DECRYPT('decrypt_value', 'decrypt_key') FROM DUAL;"
|
16
16
|
end
|
17
17
|
|
18
18
|
let(:output_query) do
|
@@ -24,7 +24,7 @@ module CryptKeeper::LogSubscriber
|
|
24
24
|
event.payload[:sql].should == output_query
|
25
25
|
end
|
26
26
|
|
27
|
-
subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql:
|
27
|
+
subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_query }))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -24,7 +24,7 @@ module CryptKeeper::LogSubscriber
|
|
24
24
|
event.payload[:sql].should == output_query
|
25
25
|
end
|
26
26
|
|
27
|
-
subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql:
|
27
|
+
subject.sql(ActiveSupport::Notifications::Event.new(:sql, 1, 1, 1, { sql: input_query }))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
data/spec/model_spec.rb
CHANGED
@@ -131,15 +131,10 @@ module CryptKeeper
|
|
131
131
|
specify { record.should_not be_changed }
|
132
132
|
|
133
133
|
it "unchanged plaintext does not trigger a save" do
|
134
|
-
queries =
|
135
|
-
|
136
|
-
subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |name, started, finished, id, payload|
|
137
|
-
queries << payload[:sql]
|
134
|
+
queries = logged_queries do
|
135
|
+
SensitiveData.find(record.id).save
|
138
136
|
end
|
139
137
|
|
140
|
-
SensitiveData.find(record.id).save
|
141
|
-
ActiveSupport::Notifications.unsubscribe subscriber
|
142
|
-
|
143
138
|
updates = queries.select { |query| query.match(/^UPDATE /) }
|
144
139
|
|
145
140
|
queries.should_not be_empty
|
@@ -34,6 +34,25 @@ module CryptKeeper
|
|
34
34
|
describe "#decrypt" do
|
35
35
|
specify { subject.decrypt(cipher_text).should == plain_text }
|
36
36
|
end
|
37
|
+
|
38
|
+
describe "Custom pgcrypto options" do
|
39
|
+
let(:pgcrypto_options) { 'compress-level=0' }
|
40
|
+
|
41
|
+
subject { PostgresPgp.new key: 'candy', pgcrypto_options: pgcrypto_options }
|
42
|
+
|
43
|
+
it "reads and writes" do
|
44
|
+
queries = logged_queries do
|
45
|
+
encrypted = subject.encrypt(plain_text)
|
46
|
+
subject.decrypt(encrypted).should == plain_text
|
47
|
+
end
|
48
|
+
|
49
|
+
queries.should_not be_empty
|
50
|
+
|
51
|
+
queries.select { |query| query.include?("pgp_sym_encrypt") }.each do |q|
|
52
|
+
q.should include(pgcrypto_options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
37
56
|
end
|
38
57
|
end
|
39
58
|
end
|
@@ -42,7 +42,25 @@ module CryptKeeper
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
module LoggedQueries
|
46
|
+
# Logs the queries run inside the block, and return them.
|
47
|
+
def logged_queries(&block)
|
48
|
+
queries = []
|
49
|
+
|
50
|
+
subscriber = ActiveSupport::Notifications
|
51
|
+
.subscribe('sql.active_record') do |name, started, finished, id, payload|
|
52
|
+
queries << payload[:sql]
|
53
|
+
end
|
54
|
+
|
55
|
+
block.call
|
56
|
+
|
57
|
+
queries
|
58
|
+
|
59
|
+
ensure ActiveSupport::Notifications.unsubscribe(subscriber)
|
60
|
+
end
|
61
|
+
end
|
45
62
|
|
46
63
|
RSpec.configure do |config|
|
47
64
|
config.extend CryptKeeper::ConnectionHelpers
|
65
|
+
config.include LoggedQueries
|
48
66
|
end
|
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.
|
4
|
+
version: 0.13.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -261,7 +261,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
261
261
|
version: '0'
|
262
262
|
segments:
|
263
263
|
- 0
|
264
|
-
hash:
|
264
|
+
hash: -2554365943607960081
|
265
265
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
266
266
|
none: false
|
267
267
|
requirements:
|
@@ -270,7 +270,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
270
270
|
version: '0'
|
271
271
|
segments:
|
272
272
|
- 0
|
273
|
-
hash:
|
273
|
+
hash: -2554365943607960081
|
274
274
|
requirements: []
|
275
275
|
rubyforge_project:
|
276
276
|
rubygems_version: 1.8.23
|