umbrellio-sequel-plugins 0.4.0.121 → 0.4.0.134

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