umbrellio-sequel-plugins 0.4.0.112 → 0.4.0.152

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: a60c4a9f3ea7a1e632f44ba475c8523c65eb693e5b92f6d8f36825510af59e8c
4
- data.tar.gz: aba42c9f420d1b042cb37b5410e76a9dc6eadcc2d8d38af1e97a8ae7b10f22a8
3
+ metadata.gz: 7c457e432fd30ccbc7eea5a66e94ce828c179dc25e45f403ee8a7cc78d23d8f1
4
+ data.tar.gz: 3fee2f7af3fedb7ed161964ce6a1bdd4b115b88d8d4faa67bc14f9d0317c74b8
5
5
  SHA512:
6
- metadata.gz: 7ac48cc499a39b5f42fa9eb264ba2afe095a4aa5d367730db5843397f2f97a70ac37a7911a81f0c62bd5d8ba049361b3cb87678b91ed96fb7c3d0074f8787431
7
- data.tar.gz: 8cc13c34e85496374c70b464f624cee2667d40c567c493f6261f9b6f4d60dfc28fb3e9df9fc5369e2bd3a73fdf45d9a4b96d8a0c88a2eed35595bb127b9e5bd8
6
+ metadata.gz: '093103fc7ae3108cc818312319d63ef2229073bfa48453a71d764de9f498bc597b09c5148219c12b930a334824ed6ef828c44b4a814470a90739bf41cca3e12e'
7
+ data.tar.gz: 416ed5d8f41e6d947fc8b82d4752e8caf55dd985f639d8b347b15e3e523fc067c133c14f4d21838c0b3221eb847ba3fe2433907d0349f4b42dfe865545511dee
data/README.md CHANGED
@@ -13,28 +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
- - `StoreAccessors`
32
- - `Synchronize`
33
- - `Upsert`
34
- - `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)
35
37
 
36
38
  # Tools
37
- - `TimestampMigratorUndoExtension`
39
+ - [`TimestampMigratorUndoExtension`](#TimestampMigratorUndoExtension)
38
40
 
39
41
  ## CurrencyRates
40
42
 
@@ -202,6 +204,39 @@ end
202
204
  # => <Husband @attributes={id:1, wife_id: 1}>
203
205
  ```
204
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
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.first_name # => "Ivan"
237
+ order.secret_data # => { "some_key" => "Some Value" }
238
+ ```
239
+
205
240
  ## Duplicate
206
241
 
207
242
  Enable: `Sequel::Model.plugin :duplicate`
@@ -239,14 +274,14 @@ item.get_column_value(:amount) # => 0.5e2
239
274
 
240
275
  ## MoneyAccessors
241
276
 
242
- **Important:** requires `money` gem described above.
277
+ **Important:** requires `money` gem described below.
243
278
 
244
279
  Plugin for using money field keys as model properties.
245
280
 
246
281
  Enable:
247
282
 
248
283
  ```ruby
249
- add_runtime_dependency "money"
284
+ gem "money"
250
285
  Sequel::Model.plugin :money_accessors
251
286
  ````
252
287
 
@@ -301,7 +336,7 @@ Example:
301
336
 
302
337
  ```ruby
303
338
  class User < Sequel::Model
304
- store :data, :first_name
339
+ store :data, :first_name
305
340
  end
306
341
 
307
342
  user = User.create(first_name: "John")
@@ -311,7 +346,7 @@ user.data # => {"first_name": "John"}
311
346
 
312
347
  ## Synchronize
313
348
 
314
- **Important:** requires a `synchronize` extension described above.
349
+ **Important:** requires a `synchronize` extension described below.
315
350
 
316
351
  Same as `DB#synchronize_with`
317
352
 
@@ -353,7 +388,7 @@ Example:
353
388
  ```ruby
354
389
  user = User.first
355
390
  user.with_lock do
356
- user.update(name: "James")
391
+ user.update(name: "James")
357
392
  end
358
393
  ```
359
394
 
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Creates encrypted attribute storing
4
+ module Sequel::Plugins::AttrEncrypted
5
+ SEPARATOR = "$"
6
+ require "sequel/plugins/attr_encrypted/simple_crypt"
7
+
8
+ module ClassMethods
9
+ # Setup attr encrypted
10
+ #
11
+ # @param attrs [Array<Symbol>] column names
12
+ # @param key [String] 32 bytes key
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
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.first_name # => "Ivan"
36
+ # order.last_name # => "Smith"
37
+ # order.secret_data # => { "some_key" => "Some Value" }
38
+ def attr_encrypted(*attrs, key:)
39
+ include_encrypted_module!
40
+ attrs.each do |attr|
41
+ define_encrypted_setter(attr, key)
42
+ define_encrypted_getter(attr, key)
43
+ @_encrypted_attributes << attr
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def define_encrypted_setter(attr, key)
50
+ @_attr_encrypted_module.module_eval do
51
+ define_method("#{attr}=") do |value|
52
+ instance_variable_set("@#{attr}", value)
53
+
54
+ send("encrypted_#{attr}=", SimpleCrypt.encrypt(value.to_json, key))
55
+ end
56
+ end
57
+ end
58
+
59
+ def define_encrypted_getter(attr, key)
60
+ @_attr_encrypted_module.module_eval do
61
+ define_method(attr.to_s) do
62
+ instance_variable_get("@#{attr}") || begin
63
+ decrypted = SimpleCrypt.decrypt(send("encrypted_#{attr}"), key)
64
+
65
+ result = !decrypted.nil? ? JSON.parse(decrypted) : decrypted
66
+ instance_variable_set("@#{attr}", result)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def include_encrypted_module!
73
+ return if defined?(@_attr_encrypted_module)
74
+
75
+ @_encrypted_attributes ||= []
76
+ @_attr_encrypted_module = Module.new
77
+ prepend @_attr_encrypted_module
78
+ end
79
+ end
80
+
81
+ module InstanceMethods
82
+ def save(*)
83
+ super.tap { _reset_encrypted_attrs_ivars }
84
+ end
85
+
86
+ def refresh(*)
87
+ super.tap { _reset_encrypted_attrs_ivars }
88
+ end
89
+
90
+ private
91
+
92
+ def _reset_encrypted_attrs_ivars
93
+ self.class.instance_variable_get(:@_encrypted_attributes)&.each do |attr|
94
+ instance_variable_set("@#{attr}", nil)
95
+ end
96
+ end
97
+ end
98
+ 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.112
4
+ version: 0.4.0.152
5
5
  platform: ruby
6
6
  authors:
7
7
  - nulldef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-07 00:00:00.000000000 Z
11
+ date: 2020-10-13 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
@@ -224,8 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
226
  - !ruby/object:Gem::Version
225
227
  version: '0'
226
228
  requirements: []
227
- rubyforge_project:
228
- rubygems_version: 2.7.7
229
+ rubygems_version: 3.0.8
229
230
  signing_key:
230
231
  specification_version: 4
231
232
  summary: Sequel plugins