umbrellio-sequel-plugins 0.4.0.107 → 0.4.0.145

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: b042d58a702375bd77b7ca54edc5fcfda8bd60add56a949c7801969c3cc07d3f
4
- data.tar.gz: e70ef852db7da472b4e31c918f96f8c81197449d1cf9f70e121c99bfb7ef9bfa
3
+ metadata.gz: d5d5aa7a6f7809d726257495ab1230d6273209e8c8a470df94faadbd0d3c82d3
4
+ data.tar.gz: 6cd47df601385a03216f20c79158eef81c8a85b1eeeb0ad6f0c15349d5d2f631
5
5
  SHA512:
6
- metadata.gz: b9013cb8c53474751b0646af8d4fef024dc7665f87b9926dd68d89c7c92adaa9b207d290578e9cff4a3de0bbf3ca19b55d01bc808e1f6627816bcc48ff10a459
7
- data.tar.gz: 87e04be02551911c2eb512a4fafe812e99add5091d087ccdbbd82dcd23b9a872e6e277c10bbdf2276d006fd076f26b7d562d81ca78a3ecfed59a7b2df4e35b40
6
+ metadata.gz: c78976f598b8dc8e22f3ad8f0be33d07833672615bbd60473035d3a4ef0f952053b5f16089b84e99bfc83864f313cc8f18a59b1fae895c8ac6ac1761598001b1
7
+ data.tar.gz: 502b777950b5bddbca58de8f56550da3f301f8d144e3d4e2420f45f09718592775bfe2116a5333bb2f1e321eeeb4a3d8255cc1e800797c3d4de1aac3fabf46a1
data/.gitignore CHANGED
@@ -10,6 +10,4 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
 
13
- Gemfile.lock
14
-
15
13
  log
@@ -1,25 +1,52 @@
1
1
  language: ruby
2
- matrix:
2
+
3
+ os: linux
4
+ dist: xenial
5
+
6
+ jobs:
3
7
  fast_finish: true
4
8
  include:
5
- - rvm: 2.4
6
9
  - rvm: 2.5
7
10
  - rvm: 2.6
11
+ - rvm: 2.7
8
12
  - rvm: ruby-head
9
13
  allow_failures:
10
14
  - rvm: ruby-head
11
- sudo: false
12
- cache: bundler
15
+
13
16
  services:
14
17
  - postgresql
18
+
15
19
  addons:
16
- postgresql: 9.6
17
- before_install: gem install bundler
20
+ postgresql: 12
21
+ apt:
22
+ packages:
23
+ - postgresql-12
24
+ - postgresql-client-12
25
+ - postgresql-server-dev-12
26
+ - postgresql-client-common
27
+ - postgresql-common
28
+
29
+ env:
30
+ global:
31
+ - PGPORT=5433
32
+
33
+ cache: bundler
34
+
35
+ before_install:
36
+ - gem install bundler
37
+ - sudo cp /etc/postgresql/9.6/main/pg_hba.conf /etc/postgresql/12/main/pg_hba.conf
38
+ - sudo service postgresql restart 12
39
+ - sleep 1
40
+
41
+ install: bundle install --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
42
+
18
43
  before_script:
19
44
  - psql -c 'create database sequel_plugins;' -U postgres
45
+
20
46
  script:
21
47
  - bundle exec rspec
22
48
  - bundle exec rubocop
49
+
23
50
  deploy:
24
51
  provider: rubygems
25
52
  api_key:
@@ -28,3 +55,4 @@ deploy:
28
55
  on:
29
56
  repo: umbrellio/umbrellio-sequel-plugins
30
57
  branch: master
58
+ rvm: 2.7
@@ -0,0 +1,117 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ umbrellio-sequel-plugins (0.4.0)
5
+ sequel
6
+ symbiont-ruby (>= 0.6)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (6.0.2.2)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 0.7, < 2)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ zeitwerk (~> 2.2)
17
+ ast (2.4.0)
18
+ coderay (1.1.2)
19
+ concurrent-ruby (1.1.6)
20
+ coveralls (0.8.23)
21
+ json (>= 1.8, < 3)
22
+ simplecov (~> 0.16.1)
23
+ term-ansicolor (~> 1.3)
24
+ thor (>= 0.19.4, < 2.0)
25
+ tins (~> 1.6)
26
+ diff-lcs (1.3)
27
+ docile (1.3.2)
28
+ i18n (1.8.2)
29
+ concurrent-ruby (~> 1.0)
30
+ jaro_winkler (1.5.4)
31
+ json (2.3.0)
32
+ method_source (1.0.0)
33
+ minitest (5.14.0)
34
+ money (6.13.7)
35
+ i18n (>= 0.6.4, <= 2)
36
+ parallel (1.19.1)
37
+ parser (2.7.1.0)
38
+ ast (~> 2.4.0)
39
+ pg (1.2.3)
40
+ pry (0.13.0)
41
+ coderay (~> 1.1)
42
+ method_source (~> 1.0)
43
+ rack (2.2.2)
44
+ rainbow (3.0.0)
45
+ rake (13.0.1)
46
+ rexml (3.2.4)
47
+ rspec (3.9.0)
48
+ rspec-core (~> 3.9.0)
49
+ rspec-expectations (~> 3.9.0)
50
+ rspec-mocks (~> 3.9.0)
51
+ rspec-core (3.9.1)
52
+ rspec-support (~> 3.9.1)
53
+ rspec-expectations (3.9.1)
54
+ diff-lcs (>= 1.2.0, < 2.0)
55
+ rspec-support (~> 3.9.0)
56
+ rspec-mocks (3.9.1)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.9.0)
59
+ rspec-support (3.9.2)
60
+ rubocop (0.81.0)
61
+ jaro_winkler (~> 1.5.1)
62
+ parallel (~> 1.10)
63
+ parser (>= 2.7.0.1)
64
+ rainbow (>= 2.2.2, < 4.0)
65
+ rexml
66
+ ruby-progressbar (~> 1.7)
67
+ unicode-display_width (>= 1.4.0, < 2.0)
68
+ rubocop-config-umbrellio (0.81.0.78)
69
+ rubocop (= 0.81.0)
70
+ rubocop-performance (= 1.5.2)
71
+ rubocop-rails (= 2.5.0)
72
+ rubocop-rspec (= 1.38.1)
73
+ rubocop-performance (1.5.2)
74
+ rubocop (>= 0.71.0)
75
+ rubocop-rails (2.5.0)
76
+ activesupport
77
+ rack (>= 1.1)
78
+ rubocop (>= 0.72.0)
79
+ rubocop-rspec (1.38.1)
80
+ rubocop (>= 0.68.1)
81
+ ruby-progressbar (1.10.1)
82
+ sequel (5.31.0)
83
+ simplecov (0.16.1)
84
+ docile (~> 1.1)
85
+ json (>= 1.8, < 3)
86
+ simplecov-html (~> 0.10.0)
87
+ simplecov-html (0.10.2)
88
+ symbiont-ruby (0.6.0)
89
+ sync (0.5.0)
90
+ term-ansicolor (1.7.1)
91
+ tins (~> 1.0)
92
+ thor (1.0.1)
93
+ thread_safe (0.3.6)
94
+ tins (1.24.1)
95
+ sync
96
+ tzinfo (1.2.7)
97
+ thread_safe (~> 0.1)
98
+ unicode-display_width (1.7.0)
99
+ zeitwerk (2.3.0)
100
+
101
+ PLATFORMS
102
+ ruby
103
+
104
+ DEPENDENCIES
105
+ bundler
106
+ coveralls (>= 0.8)
107
+ money
108
+ pg
109
+ pry
110
+ rake
111
+ rspec
112
+ rubocop-config-umbrellio
113
+ simplecov
114
+ umbrellio-sequel-plugins!
115
+
116
+ BUNDLED WITH
117
+ 2.1.4
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,40 @@ 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.reload
237
+ order.first_name # => "Ivan"
238
+ order.secret_data # => { "some_key" => "Some Value" }
239
+ ```
240
+
205
241
  ## Duplicate
206
242
 
207
243
  Enable: `Sequel::Model.plugin :duplicate`
@@ -239,14 +275,14 @@ item.get_column_value(:amount) # => 0.5e2
239
275
 
240
276
  ## MoneyAccessors
241
277
 
242
- **Important:** requires `money` gem described above.
278
+ **Important:** requires `money` gem described below.
243
279
 
244
280
  Plugin for using money field keys as model properties.
245
281
 
246
282
  Enable:
247
283
 
248
284
  ```ruby
249
- add_runtime_dependency "money"
285
+ gem "money"
250
286
  Sequel::Model.plugin :money_accessors
251
287
  ````
252
288
 
@@ -301,7 +337,7 @@ Example:
301
337
 
302
338
  ```ruby
303
339
  class User < Sequel::Model
304
- store :data, :first_name
340
+ store :data, :first_name
305
341
  end
306
342
 
307
343
  user = User.create(first_name: "John")
@@ -311,7 +347,7 @@ user.data # => {"first_name": "John"}
311
347
 
312
348
  ## Synchronize
313
349
 
314
- **Important:** requires a `synchronize` extension described above.
350
+ **Important:** requires a `synchronize` extension described below.
315
351
 
316
352
  Same as `DB#synchronize_with`
317
353
 
@@ -353,7 +389,7 @@ Example:
353
389
  ```ruby
354
390
  user = User.first
355
391
  user.with_lock do
356
- user.update(name: "James")
392
+ user.update(name: "James")
357
393
  end
358
394
  ```
359
395
 
@@ -0,0 +1,91 @@
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.reload
36
+ # order.first_name # => "Ivan"
37
+ # order.last_name # => "Smith"
38
+ # order.secret_data # => { "some_key" => "Some Value" }
39
+ def attr_encrypted(*attrs, key:)
40
+ include_encrypted_module!
41
+ attrs.each do |attr|
42
+ define_encrypted_setter(attr, key)
43
+ define_encrypted_getter(attr, key)
44
+ @_encrypted_attributes << attr
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def define_encrypted_setter(attr, key)
51
+ @_attr_encrypted_module.module_eval do
52
+ define_method("#{attr}=") do |value|
53
+ instance_variable_set("@#{attr}", value)
54
+
55
+ send("encrypted_#{attr}=", SimpleCrypt.encrypt(value.to_json, key))
56
+ end
57
+ end
58
+ end
59
+
60
+ def define_encrypted_getter(attr, key)
61
+ @_attr_encrypted_module.module_eval do
62
+ define_method(attr.to_s) do
63
+ instance_variable_get("@#{attr}") || begin
64
+ decrypted = SimpleCrypt.decrypt(send("encrypted_#{attr}"), key)
65
+
66
+ result = !decrypted.nil? ? JSON.parse(decrypted) : decrypted
67
+ instance_variable_set("@#{attr}", result)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def include_encrypted_module!
74
+ return if defined?(@_attr_encrypted_module)
75
+
76
+ @_encrypted_attributes ||= []
77
+ @_attr_encrypted_module = Module.new
78
+ prepend @_attr_encrypted_module
79
+ end
80
+ end
81
+
82
+ module InstanceMethods
83
+ def reload
84
+ self.class.instance_variable_get(:@_encrypted_attributes)&.each do |attr|
85
+ instance_variable_set("@#{attr}", nil)
86
+ end
87
+
88
+ super
89
+ end
90
+ end
91
+ 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
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "money"
4
4
 
5
+ Money.rounding_mode = BigDecimal::ROUND_HALF_UP
6
+
5
7
  # Creates accessors for money values
6
8
  module Sequel::Plugins::MoneyAccessors
7
9
  MoneyClassRequired = Class.new(StandardError)
@@ -39,7 +39,7 @@ module Sequel::Plugins::Upsert
39
39
  # @see #upsert_dataset
40
40
  def multi_upsert(rows, **options)
41
41
  rows = rows.map { |row| sequel_values(row) }
42
- upsert_dataset(options).multi_insert(rows)
42
+ upsert_dataset(**options).multi_insert(rows)
43
43
  end
44
44
 
45
45
  # Returns formatted row values
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_runtime_dependency "symbiont-ruby", ">= 0.6"
26
26
 
27
27
  spec.add_development_dependency "bundler"
28
- spec.add_development_dependency "coveralls"
28
+ spec.add_development_dependency "coveralls", ">= 0.8"
29
29
  spec.add_development_dependency "money"
30
30
  spec.add_development_dependency "pg"
31
31
  spec.add_development_dependency "pry"
@@ -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.107
4
+ version: 0.4.0.145
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-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.8'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '0.8'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: money
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +178,7 @@ files:
178
178
  - ".travis.yml"
179
179
  - CHANGELOG.md
180
180
  - Gemfile
181
+ - Gemfile.lock
181
182
  - LICENSE
182
183
  - README.md
183
184
  - Rakefile
@@ -189,6 +190,8 @@ files:
189
190
  - lib/sequel/extensions/pg_tools.rb
190
191
  - lib/sequel/extensions/slave.rb
191
192
  - lib/sequel/extensions/synchronize.rb
193
+ - lib/sequel/plugins/attr_encrypted.rb
194
+ - lib/sequel/plugins/attr_encrypted/simple_crypt.rb
192
195
  - lib/sequel/plugins/duplicate.rb
193
196
  - lib/sequel/plugins/get_column_value.rb
194
197
  - lib/sequel/plugins/money_accessors.rb