rom-encrypted_attribute 0.0.4 → 0.0.5

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
  SHA256:
3
- metadata.gz: a7799a80222e1784ae54379331e44b52035d1fea0544723ab3ad69aac8d0416a
4
- data.tar.gz: 1418ca1c2a31c539fec10c0c118c305216a439a19c19cdf1662ad1b158bed892
3
+ metadata.gz: edac4dc1b09b3b903aefc265d78a56a7fafd2f6d28f1b503d3f4fbe64eede9c6
4
+ data.tar.gz: c7de7fd6c2bc5c6de81ef0bf3f804f7cda02df4d5687156647155dd77e5c358e
5
5
  SHA512:
6
- metadata.gz: e1854858926a001395967f06fc4dcce28ef066e2e3819d4a3f45375abc1e55c671000de7ff3f7431d6641f31b68d92f012f75532db2cc137e35e9939b61b745a
7
- data.tar.gz: 5f8cf5402568abc7d46dd5cd96bf7443ed59d2bf74d69191349ff10ab0c41d89d1f9f154d180890d2344e1d973801c1f2294fae0d8aa2619cdfddf963135c77e
6
+ metadata.gz: d603a67e727a2079904ed7f45629fcc2fabe185297ea26f479b9573c8d8b1bb366c6a404ca3720176769890b70d280490cb198b7798731b8efbbe92a47d68581
7
+ data.tar.gz: dd4d03515ab81bbd335793688f202e73b21f9ad815d9881700e8cf99ff6dc69bc95aebe8c15a74440283b80c19c7c17850133770b98a06a19df54e61476f568f
data/README.md CHANGED
@@ -66,6 +66,7 @@ class SecretNotes < ::ROM::Relation[:sql]
66
66
  use :encrypted_attributes
67
67
  encrypt :content
68
68
  encrypt :title, :hash_digest_class: OpenSSL::Digest::SHA256
69
+ encrypt :maybe_encrypted, support_unencrypted_data: true
69
70
  end
70
71
  end
71
72
 
@@ -113,7 +114,7 @@ end
113
114
 
114
115
  ### Caveats
115
116
 
116
- * Due to [a bug](https://github.com/rom-rb/rom-sql/issues/423) in `rom-sql`, reading unencrypted data is always supported, which means that if there's a plain not-encrypted data in your database already, it will be read correctly. This might or might not be desirable, but for the time being there's no choice in configuring this behaviour.
117
+ * Due to [a bug](https://github.com/rom-rb/rom-sql/issues/423) in `rom-sql`, reading unencrypted data requires a monkey patch to ROM. Since this is quite aggressive, you are expected to opt-in to this by calling `ROM::SQL::Patch432.install!`.
117
118
  * Support for deterministic encryption from `ActiveRecord::Encryption` is not (yet) implemented
118
119
  * Support for key rotation is not (yet) implemented
119
120
 
@@ -7,11 +7,16 @@ require_relative "payload"
7
7
  module ROM
8
8
  module EncryptedAttribute
9
9
  class Decryptor
10
- def initialize(derivator:)
10
+ UnencryptedDataNotAllowed = Class.new(RuntimeError)
11
+
12
+ def initialize(derivator:, support_unencrypted_data: false)
11
13
  @derivator = derivator
14
+ @support_unencrypted_data = support_unencrypted_data
12
15
  end
13
16
 
14
17
  def decrypt(message)
18
+ return nil if message.nil?
19
+
15
20
  payload = ROM::EncryptedAttribute::Payload.decode(message)
16
21
 
17
22
  cipher = OpenSSL::Cipher.new("aes-256-gcm")
@@ -25,9 +30,11 @@ module ROM
25
30
  cipher.auth_data = ""
26
31
  cipher.update(payload.message) + cipher.final
27
32
  rescue JSON::ParserError
28
- # we need to unconditionally support of reading unencrypted data due to a bug in rom-sql
29
- # https://github.com/rom-rb/rom-sql/issues/423
30
- message
33
+ if @support_unencrypted_data
34
+ message
35
+ else
36
+ raise UnencryptedDataNotAllowed
37
+ end
31
38
  end
32
39
  end
33
40
  end
@@ -13,6 +13,8 @@ module ROM
13
13
  end
14
14
 
15
15
  def encrypt(message)
16
+ return nil if message.nil?
17
+
16
18
  cipher = OpenSSL::Cipher.new("aes-256-gcm")
17
19
  key = @derivator.derive(cipher.key_len)
18
20
  iv = cipher.random_iv
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # this is used to silence the redefinition warnings
4
+ require "warning"
5
+
6
+ # This provides a patch for rom-sql while https://github.com/rom-rb/rom-sql/pull/432
7
+ # is pending merge. It allows to block reading unencrypted values from the database.
8
+ # You need to opt-in for this patch yourself by calling:
9
+ #
10
+ # ROM::SQL::Patch432.install!
11
+ #
12
+ # The patch can be reverted with
13
+ # ROM::SQL::Patch432.uninstall!
14
+ #
15
+ # Note: that you don't need this if you are using PostgreSQL.
16
+ # Also note that this will emit a warning of overwriting a method.
17
+ module ROM
18
+ module SQL
19
+ module Patch432
20
+ def self.install!
21
+ Warning.ignore(:method_redefined)
22
+ ROM::SQL::Commands::Create.class_eval do
23
+ def insert(tuples)
24
+ pks = tuples.map { |tuple| relation.insert(tuple) }
25
+ relation.dataset.where(relation.primary_key => pks).to_a
26
+ end
27
+
28
+ def multi_insert(tuples)
29
+ pks = relation.multi_insert(tuples, return: :primary_key)
30
+ relation.dataset.where(relation.primary_key => pks).to_a
31
+ end
32
+ end
33
+ Warning.ignore(:method_redefined, false)
34
+ end
35
+
36
+ def self.uninstall!
37
+ Warning.ignore(:method_redefined)
38
+ ROM::SQL::Commands::Create.class_eval do
39
+ def insert(tuples)
40
+ pks = tuples.map { |tuple| relation.insert(tuple) }
41
+ relation.where(relation.primary_key => pks).to_a
42
+ end
43
+
44
+ def multi_insert(tuples)
45
+ pks = relation.multi_insert(tuples, return: :primary_key)
46
+ relation.where(relation.primary_key => pks).to_a
47
+ end
48
+ end
49
+ Warning.ignore(:method_redefined, false)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ROM
4
4
  module EncryptedAttribute
5
- VERSION = "0.0.4"
5
+ VERSION = "0.0.5"
6
6
  end
7
7
  end
@@ -12,19 +12,24 @@ module ROM
12
12
  module EncryptedAttribute
13
13
  extend Dry::Configurable
14
14
 
15
+ module Types
16
+ include Dry.Types()
17
+ end
18
+
15
19
  setting :primary_key
16
20
  setting :key_derivation_salt
17
21
  setting :hash_digest_class, default: OpenSSL::Digest::SHA1
22
+ setting :support_unencrypted_data, default: false
18
23
 
19
- def self.define_encrypted_attribute_types(primary_key:, key_derivation_salt:, hash_digest_class: OpenSSL::Digest::SHA1)
24
+ def self.define_encrypted_attribute_types(primary_key:, key_derivation_salt:, hash_digest_class: OpenSSL::Digest::SHA1, support_unencrypted_data: false)
20
25
  key_derivator = KeyDerivator.new(salt: key_derivation_salt, secret: primary_key,
21
26
  hash_digest_class: hash_digest_class)
22
27
 
23
- reader_type = Dry.Types.Constructor(String) do |value|
24
- ROM::EncryptedAttribute::Decryptor.new(derivator: key_derivator).decrypt(value)
28
+ reader_type = Dry.Types.Constructor(Types::String.optional) do |value|
29
+ ROM::EncryptedAttribute::Decryptor.new(derivator: key_derivator, support_unencrypted_data: support_unencrypted_data).decrypt(value)
25
30
  end
26
31
 
27
- writer_type = Dry.Types.Constructor(String) do |value|
32
+ writer_type = Dry.Types.Constructor(Types::String.optional) do |value|
28
33
  ROM::EncryptedAttribute::Encryptor.new(derivator: key_derivator).encrypt(value)
29
34
  end
30
35
 
@@ -11,10 +11,11 @@ module ROM
11
11
  primary_key = options.fetch(:primary_key, ROM::EncryptedAttribute.config.primary_key)
12
12
  key_derivation_salt = options.fetch(:key_derivation_salt, ROM::EncryptedAttribute.config.key_derivation_salt)
13
13
  hash_digest_class = options.fetch(:hash_digest_class, ROM::EncryptedAttribute.config.hash_digest_class)
14
+ support_unencrypted_data = options.fetch(:support_unencrypted_data, EncryptedAttribute.config.support_unencrypted_data)
14
15
 
15
16
  encrypted_string, encrypted_string_reader =
16
17
  ROM::EncryptedAttribute.define_encrypted_attribute_types(
17
- primary_key: primary_key, key_derivation_salt: key_derivation_salt, hash_digest_class: hash_digest_class
18
+ primary_key: primary_key, key_derivation_salt: key_derivation_salt, hash_digest_class: hash_digest_class, support_unencrypted_data: support_unencrypted_data
18
19
  )
19
20
 
20
21
  attrs =
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom-encrypted_attribute
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paweł Świątkowski
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-10-26 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: dry-types
@@ -66,7 +65,6 @@ dependencies:
66
65
  - - ">="
67
66
  - !ruby/object:Gem::Version
68
67
  version: '1.0'
69
- description:
70
68
  email:
71
69
  - katafrakt@vivaldi.net
72
70
  executables: []
@@ -83,14 +81,13 @@ files:
83
81
  - lib/rom/encrypted_attribute/encryptor.rb
84
82
  - lib/rom/encrypted_attribute/key_derivator.rb
85
83
  - lib/rom/encrypted_attribute/payload.rb
84
+ - lib/rom/encrypted_attribute/rom_sql_patch.rb
86
85
  - lib/rom/encrypted_attribute/version.rb
87
86
  - lib/rom/plugins/schema/encrypted_attributes.rb
88
87
  - rom-encrypted_attribute.gemspec
89
- homepage:
90
88
  licenses: []
91
89
  metadata:
92
90
  source_code_uri: https://github.com/katafrakt/rom-encrypted_attribute
93
- post_install_message:
94
91
  rdoc_options: []
95
92
  require_paths:
96
93
  - lib
@@ -105,8 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
102
  - !ruby/object:Gem::Version
106
103
  version: '0'
107
104
  requirements: []
108
- rubygems_version: 3.5.16
109
- signing_key:
105
+ rubygems_version: 3.6.7
110
106
  specification_version: 4
111
107
  summary: Encrypted attributes for ROM
112
108
  test_files: []