crypt_keeper 1.0.0 → 1.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8256a26cb233344e7a8e71791aa528d931657317
4
- data.tar.gz: 1ac4af01a5fee7957b611d967c6991bdab5a73d9
3
+ metadata.gz: 0721f2abe4b641ef62278b76effaa56c2cb42cf7
4
+ data.tar.gz: b252fa5c0254f644721b50e5dbfbd4696bbe1fdd
5
5
  SHA512:
6
- metadata.gz: d9e9eecfd9eb95129d439624c4664890474fe9360b2a5097beb66f60b1e05f479192b9300530a703c0d38d6945c56c4def5c1a108b5d79099abba7fa5fd6dc35
7
- data.tar.gz: c41b3baa8a72c0114702162fcdb857b145bdd668b7139cb391d600f48fa0888fa9a152b190815a00526b7a093ac636366df657b38b371e47893c7c85804ffb36
6
+ metadata.gz: 9f84ddf6b8f31d846d3d154dddabaf1a34eb6c5093cf014c228ff61d43957ff8ab0baa9bb5c92fa8b4531a3a769586fb5b37b793e988ae0d1c9208d467bcdaee
7
+ data.tar.gz: cc33b4af5ae25d8e011767510c99004ad1dcf653c067a552d8661b684660b71afa07d7f8b87947da540e27d67b1a0e6f111539a63355d5d906814228eaf1a064
@@ -4,23 +4,43 @@ require 'active_support/lazy_load_hooks'
4
4
  module CryptKeeper
5
5
  module LogSubscriber
6
6
  module PostgresPgp
7
+ FILTER = /(\(*)pgp_(sym|pub)_(?<operation>decrypt|encrypt)(\(+.*\)+)/im
8
+
7
9
  # Public: Prevents sensitive data from being logged
8
10
  #
9
11
  # event - An ActiveSupport::Notifications::Event
10
12
  #
11
13
  # Returns a boolean.
12
14
  def sql(event)
13
- filter = /(\(*)pgp_(sym|pub)_(?<operation>decrypt|encrypt)(\(+.*\)+)/im
14
- payload = event.payload[:sql]
15
- .encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
15
+ payload = crypt_keeper_payload_parse(event.payload[:sql])
16
+
17
+ return if CryptKeeper.silence_logs? && payload =~ FILTER
16
18
 
17
- return if CryptKeeper.silence_logs? && payload =~ filter
19
+ event.payload[:sql] = crypt_keeper_filter_postgres_log(payload)
20
+ super(event)
21
+ end
18
22
 
19
- event.payload[:sql] = payload.gsub(filter) do |_|
23
+ private
24
+
25
+ # Private: Parses the payload to UTF.
26
+ #
27
+ # payload - the payload string
28
+ #
29
+ # Returns a string.
30
+ def crypt_keeper_payload_parse(payload)
31
+ payload.encode('UTF-8', 'binary',
32
+ invalid: :replace, undef: :replace, replace: '')
33
+ end
34
+
35
+ # Private: Filters the payload.
36
+ #
37
+ # payload - the payload string
38
+ #
39
+ # Returns a string.
40
+ def crypt_keeper_filter_postgres_log(payload)
41
+ payload.gsub(FILTER) do |_|
20
42
  "#{$~[:operation]}([FILTERED])"
21
43
  end
22
-
23
- super(event)
24
44
  end
25
45
  end
26
46
  end
@@ -4,6 +4,7 @@ module CryptKeeper
4
4
  module Provider
5
5
  class PostgresPgp < Base
6
6
  include CryptKeeper::Helper::SQL
7
+ include CryptKeeper::LogSubscriber::PostgresPgp
7
8
 
8
9
  attr_accessor :key
9
10
  attr_accessor :pgcrypto_options
@@ -25,18 +26,37 @@ module CryptKeeper
25
26
  #
26
27
  # Returns an encrypted string
27
28
  def encrypt(value)
28
- escape_and_execute_sql(["SELECT pgp_sym_encrypt(?, ?, ?)", value.to_s, key, pgcrypto_options])['pgp_sym_encrypt']
29
+ rescue_invalid_statement do
30
+ escape_and_execute_sql(["SELECT pgp_sym_encrypt(?, ?, ?)",
31
+ value.to_s, key, pgcrypto_options])['pgp_sym_encrypt']
32
+ end
29
33
  end
30
34
 
31
35
  # Public: Decrypts a string
32
36
  #
33
37
  # Returns a plaintext string
34
38
  def decrypt(value)
35
- escape_and_execute_sql(["SELECT pgp_sym_decrypt(?, ?)", value, key])['pgp_sym_decrypt']
39
+ rescue_invalid_statement do
40
+ escape_and_execute_sql(["SELECT pgp_sym_decrypt(?, ?)",
41
+ value, key])['pgp_sym_decrypt']
42
+ end
36
43
  end
37
44
 
38
45
  def search(records, field, criteria)
39
- records.where("(pgp_sym_decrypt(cast(\"#{field}\" AS bytea), ?) = ?)", key, criteria)
46
+ records.where("(pgp_sym_decrypt(cast(\"#{field}\" AS bytea), ?) = ?)",
47
+ key, criteria)
48
+ end
49
+
50
+ private
51
+
52
+ # Private: Rescues and filters invalid statement errors. Run the code
53
+ # within a block for it to be rescued.
54
+ def rescue_invalid_statement
55
+ yield
56
+ rescue ActiveRecord::StatementInvalid => e
57
+ message = crypt_keeper_payload_parse(e.message)
58
+ message = crypt_keeper_filter_postgres_log(message)
59
+ raise ActiveRecord::StatementInvalid, message
40
60
  end
41
61
  end
42
62
  end
@@ -1,3 +1,3 @@
1
1
  module CryptKeeper
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -28,11 +28,31 @@ describe CryptKeeper::Provider::PostgresPgp do
28
28
  specify { expect(subject.encrypt(integer_plain_text)).to_not eq(integer_plain_text) }
29
29
  specify { expect(subject.encrypt(integer_plain_text)).to_not be_empty }
30
30
  end
31
+
32
+ it "filters StatementInvalid errors" do
33
+ subject.pgcrypto_options = "invalid"
34
+
35
+ begin
36
+ subject.encrypt(plain_text)
37
+ rescue ActiveRecord::StatementInvalid => e
38
+ expect(e.message).to_not include("invalid")
39
+ expect(e.message).to_not include(ENCRYPTION_PASSWORD)
40
+ end
41
+ end
31
42
  end
32
43
 
33
44
  describe "#decrypt" do
34
45
  specify { expect(subject.decrypt(cipher_text)).to eq(plain_text) }
35
46
  specify { expect(subject.decrypt(integer_cipher_text)).to eq(integer_plain_text.to_s) }
47
+
48
+ it "filters StatementInvalid errors" do
49
+ begin
50
+ subject.decrypt("invalid")
51
+ rescue ActiveRecord::StatementInvalid => e
52
+ expect(e.message).to_not include("invalid")
53
+ expect(e.message).to_not include(ENCRYPTION_PASSWORD)
54
+ end
55
+ end
36
56
  end
37
57
 
38
58
  describe "#search" do
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: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Mazzi