umbrellio-sequel-plugins 0.4.0.112 → 0.4.0.152
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 +4 -4
- data/README.md +54 -19
- data/lib/sequel/plugins/attr_encrypted.rb +98 -0
- data/lib/sequel/plugins/attr_encrypted/simple_crypt.rb +46 -0
- data/utils/database.rb +1 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c457e432fd30ccbc7eea5a66e94ce828c179dc25e45f403ee8a7cc78d23d8f1
|
4
|
+
data.tar.gz: 3fee2f7af3fedb7ed161964ce6a1bdd4b115b88d8d4faa67bc14f9d0317c74b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
16
|
+
$ bundle
|
17
17
|
|
18
18
|
# Extensions
|
19
19
|
|
20
|
-
- `CurrencyRates`
|
21
|
-
- `PGTools`
|
22
|
-
- `Slave`
|
23
|
-
- `Synchronize`
|
24
|
-
- `
|
25
|
-
- `
|
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
|
-
- `
|
30
|
-
- `
|
31
|
-
- `
|
32
|
-
- `
|
33
|
-
- `
|
34
|
-
- `
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
data/utils/database.rb
CHANGED
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.
|
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-
|
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
|
-
|
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
|