umbrellio-sequel-plugins 0.4.0.121 → 0.4.0.134

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: 441b4a06a00be08f3b8019dbed3af3f3f804540af51ceb33b72322428047cfb1
4
- data.tar.gz: cf3aa331e6f80510afe733b7f3fcf9b43f76ad253dd6653049d388f6116cd524
3
+ metadata.gz: 61fbe7c339511660a7a6797732df54b1215d84820ba80d97f434076b329ac2af
4
+ data.tar.gz: a4802265e7bd4ffe9c21b7eaa9ba7d071bf75b81f09d6198412201882f59ede5
5
5
  SHA512:
6
- metadata.gz: 4d80895de1d2d82dd3af8f42f7496b900ae4ca21350d686dd28df78e5676e0b1d5935e118ea6d771ba2950021ef77e21277cff2f76e25631e228f78f009bd711
7
- data.tar.gz: 9ee64942f741c7dc96bf33a6f360cf9542d2fe2208ffe08f4ca43a2a4a8dadc77a8edb025918f885ce148ac98a91e9b738c9d392245f98b55203949a7f37d857
6
+ metadata.gz: 9ee225f47d644536885adf0f63569c64e0d079abb22faca00415c663ffdaafaf27679eb63af7206dabb4accdfa87fb025e8cacece1e59feaf8ce8bb96fce9d42
7
+ data.tar.gz: 4f65c05c159e82e6999e463bd2a5c10e1c37110b43d7cec383416c9d6acd90536777740c4b936186f4deade9ece47ef2542f1de63f0ac4620755682820120577
data/README.md CHANGED
@@ -13,29 +13,30 @@ gem 'umbrellio-sequel-plugins'
13
13
 
14
14
  And then execute:
15
15
 
16
- $ bundle
16
+ $ bundle
17
17
 
18
18
  # Extensions
19
19
 
20
- - `CurrencyRates`
21
- - `PGTools`
22
- - `Slave`
23
- - `Synchronize`
24
- - `methods_in_migrations`
25
- - `deferrable_foreign_keys`
20
+ - [`CurrencyRates`](#CurrencyRates)
21
+ - [`PGTools`](#PGTools)
22
+ - [`Slave`](#Slave)
23
+ - [`Synchronize`](#Synchronize)
24
+ - [`methods_in_migrations`](#methods_in_migrations)
25
+ - [`deferrable_foreign_keys`](#deferrable_foreign_keys)
26
26
 
27
27
  # Plugins
28
28
 
29
- - `Duplicate`
30
- - `GetColumnValue`
31
- - `MoneyAccessors`
32
- - `StoreAccessors`
33
- - `Synchronize`
34
- - `Upsert`
35
- - `WithLock`
29
+ - [`AttrEncrypted`](#AttrEncrypted)
30
+ - [`Duplicate`](#Duplicate)
31
+ - [`GetColumnValue`](#GetColumnValue)
32
+ - [`MoneyAccessors`](#MoneyAccessors)
33
+ - [`StoreAccessors`](#StoreAccessors)
34
+ - [`Synchronize`](#Synchronize)
35
+ - [`Upsert`](#Upsert)
36
+ - [`WithLock`](#WithLock)
36
37
 
37
38
  # Tools
38
- - `TimestampMigratorUndoExtension`
39
+ - [`TimestampMigratorUndoExtension`](#TimestampMigratorUndoExtension)
39
40
 
40
41
  ## CurrencyRates
41
42
 
@@ -203,6 +204,40 @@ end
203
204
  # => <Husband @attributes={id:1, wife_id: 1}>
204
205
  ```
205
206
 
207
+ ## AttrEncrypted
208
+
209
+ Enable: `Sequel::Model.plugin :attr_encrypted`
210
+
211
+ Plugin for storing encrypted model attributes.
212
+
213
+ Example:
214
+
215
+ ```ruby
216
+ Sequel.migration do
217
+ change do
218
+ alter_table :orders do
219
+ add_column :encrypted_first_name, :text
220
+ add_column :encrypted_last_name, :text
221
+ add_column :encrypted_secret_data, :text
222
+ end
223
+ end
224
+ end
225
+
226
+ class Order < Sequel::Model
227
+ attr_encrypted :first_name, :last_name, key: Settings.private_key
228
+ attr_encrypted :secret_data, key: Settings.another_private_key, json: true
229
+ end
230
+
231
+ Order.create(first_name: "Ivan")
232
+ # => INSERT INTO "orders" ("encrypted_first_name") VALUES ('/sTi9Q==$OTpuMRq5k8R3JayQ$WjSManQGP9UaZ3C40yDjKg==')
233
+
234
+ order = Order.create(first_name: "Ivan", last_name: "Smith",
235
+ secret_data: { "some_key" => "Some Value" })
236
+ order.reload
237
+ order.first_name # => "Ivan"
238
+ order.secret_data # => { "some_key" => "Some Value" }
239
+ ```
240
+
206
241
  ## Duplicate
207
242
 
208
243
  Enable: `Sequel::Model.plugin :duplicate`
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Creates encrypted attribute storing
4
+ module Sequel::Plugins::AttrEncrypted
5
+ SEPARATOR = "$"
6
+
7
+ module ClassMethods
8
+ # Setup attr encrypted
9
+ #
10
+ # @param attrs [Array<Symbol>] column names
11
+ # @param key [String] 32 bytes key
12
+ # @param json [Boolean] store attribute as json or not
13
+ # @example
14
+ # Sequel.migration do
15
+ # change do
16
+ # alter_table :orders do
17
+ # add_column :encrypted_first_name, :text
18
+ # add_column :encrypted_last_name, :text
19
+ # add_column :encrypted_secret_data, :text
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # class Order < Sequel::Model
25
+ # attr_encrypted :first_name, :last_name, key: Settings.private_key
26
+ # attr_encrypted :secret_data, key: Settings.another_private_key, json: true
27
+ # end
28
+
29
+ # Order.create(first_name: "Ivan")
30
+ # # => INSERT INTO "orders" ("encrypted_first_name")
31
+ # VALUES ('/sTi9Q==$OTpuMRq5k8R3JayQ$WjSManQGP9UaZ3C40yDjKg==')
32
+ #
33
+ # order = Order.create(first_name: "Ivan", last_name: "Smith",
34
+ # secret_data: { "some_key" => "Some Value" })
35
+ # order.reload
36
+ # order.first_name # => "Ivan"
37
+ # order.secret_data # => { "some_key" => "Some Value" }
38
+ def attr_encrypted(*attrs, key:, json: false)
39
+ include_encrypted_module!
40
+ attrs.each do |attr|
41
+ define_encrypted_setter(attr, key, json)
42
+ define_encrypted_getter(attr, key, json)
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def define_encrypted_setter(attr, key, json)
49
+ @_attr_encrypted_module.module_eval do
50
+ define_method("#{attr}=") do |value|
51
+ instance_variable_set("@#{attr}", value)
52
+
53
+ send("encrypted_#{attr}=", SimpleCrypt.encrypt(json ? value.to_json : value, key))
54
+ end
55
+ end
56
+ end
57
+
58
+ def define_encrypted_getter(attr, key, json)
59
+ @_attr_encrypted_module.module_eval do
60
+ define_method(attr.to_s) do
61
+ instance_variable_get("@#{attr}") || begin
62
+ decrypted = SimpleCrypt.decrypt(send("encrypted_#{attr}"), key)
63
+
64
+ result = json && !decrypted.nil? ? JSON.parse(decrypted) : decrypted
65
+ instance_variable_set("@#{attr}", result)
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ def include_encrypted_module!
72
+ return if defined?(@_attr_encrypted_module)
73
+
74
+ @_attr_encrypted_module = Module.new
75
+ prepend @_attr_encrypted_module
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sequel::Plugins::AttrEncrypted::SimpleCrypt
4
+ extend self
5
+ require "base64"
6
+
7
+ SEPARATOR = "$"
8
+
9
+ def encrypt(string, key)
10
+ return unless string.is_a?(String) && !string.empty?
11
+
12
+ encryptor = new_cipher(key, &:encrypt)
13
+ iv = encryptor.random_iv
14
+
15
+ encrypted = encryptor.update(string) + encryptor.final
16
+ dump(encrypted, iv, encryptor.auth_tag)
17
+ end
18
+
19
+ def decrypt(string, key)
20
+ encrypted, iv, auth_tag = parse(string) if string.is_a?(String)
21
+ return if [encrypted, iv, auth_tag].any?(&:nil?)
22
+
23
+ decryptor = new_cipher(key, &:decrypt)
24
+ decryptor.iv = iv
25
+ decryptor.auth_tag = auth_tag
26
+
27
+ decryptor.update(encrypted) + decryptor.final
28
+ end
29
+
30
+ private
31
+
32
+ def new_cipher(key)
33
+ result = OpenSSL::Cipher::AES256.new(:gcm)
34
+ yield(result)
35
+ result.key = key
36
+ result
37
+ end
38
+
39
+ def parse(string)
40
+ string.split(SEPARATOR).map { |x| Base64.strict_decode64(x) }
41
+ end
42
+
43
+ def dump(*values)
44
+ [*values].map { |x| Base64.strict_encode64(x) }.join(SEPARATOR)
45
+ end
46
+ end
@@ -22,6 +22,7 @@ Sequel.extension :pg_array_ops
22
22
  Sequel.extension :pg_json_ops
23
23
  Sequel.extension :pg_range_ops
24
24
 
25
+ Sequel::Model.plugin :attr_encrypted
25
26
  Sequel::Model.plugin :duplicate
26
27
  Sequel::Model.plugin :get_column_value
27
28
  Sequel::Model.plugin :money_accessors
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: umbrellio-sequel-plugins
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.121
4
+ version: 0.4.0.134
5
5
  platform: ruby
6
6
  authors:
7
7
  - nulldef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2020-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -190,6 +190,8 @@ files:
190
190
  - lib/sequel/extensions/pg_tools.rb
191
191
  - lib/sequel/extensions/slave.rb
192
192
  - lib/sequel/extensions/synchronize.rb
193
+ - lib/sequel/plugins/attr_encrypted.rb
194
+ - lib/sequel/plugins/attr_encrypted/simple_crypt.rb
193
195
  - lib/sequel/plugins/duplicate.rb
194
196
  - lib/sequel/plugins/get_column_value.rb
195
197
  - lib/sequel/plugins/money_accessors.rb