umbrellio-sequel-plugins 0.4.0.114 → 0.4.0.164

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: d8c7ff5ac5ebea27eafa18c31cd1d662265d4f482ef5918cadf94d0aa4f08f7f
4
- data.tar.gz: 3fa003eb8fa8c4f8fe5b0f5bb5bc43305a14248f02eeece91013329dfe7be17d
3
+ metadata.gz: 6bd4394bf53fcf0c95a1c67b2268c5def71d15f2a64fec6e30cb70fcb281caed
4
+ data.tar.gz: 57178f6c6365073e28bb3787f6253a774c6b134d6cd4a84656725e2d6400d373
5
5
  SHA512:
6
- metadata.gz: 0b252fd339fa0b4fc0c48861ae344b199cec544b81ad1b39524fc3a787e7a92ddcd7f8bf7160f5b97255ee99cdf08a1c9887872c2d4b28a0878adec9f3de41a6
7
- data.tar.gz: 077edb4f06abb73764d73eaab2ef3ee5a9bad1897e5faf9e7b1c892b775ff487b8d3273a74613aad4822336a180f59bd38aa83f50a7e10330007f386ffd8f534
6
+ metadata.gz: f34fda6b627aed0be50ae0a3fa6bc3978d7186f8477748870ff1871868ddbca2c0175b6bd4a7471b617406b28c0efee4ace1096d94795e40e402d7e0b2d0a1e9
7
+ data.tar.gz: b440a1b8b808c71b8c52fee03d0ead284dbbdf963cf3391fba385392703db6744b0aad41268e298430641709270f1f595edcabc63e3184ad0ec0d157beb8cecd
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
 
3
3
  os: linux
4
+
4
5
  dist: xenial
5
6
 
6
7
  jobs:
@@ -43,10 +44,6 @@ install: bundle install --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
43
44
  before_script:
44
45
  - psql -c 'create database sequel_plugins;' -U postgres
45
46
 
46
- script:
47
- - bundle exec rspec
48
- - bundle exec rubocop
49
-
50
47
  deploy:
51
48
  provider: rubygems
52
49
  api_key:
@@ -8,78 +8,81 @@ PATH
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (6.0.2.2)
11
+ activesupport (6.0.3.4)
12
12
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
13
  i18n (>= 0.7, < 2)
14
14
  minitest (~> 5.1)
15
15
  tzinfo (~> 1.1)
16
- zeitwerk (~> 2.2)
17
- ast (2.4.0)
18
- coderay (1.1.2)
19
- concurrent-ruby (1.1.6)
16
+ zeitwerk (~> 2.2, >= 2.2.2)
17
+ ast (2.4.1)
18
+ coderay (1.1.3)
19
+ concurrent-ruby (1.1.7)
20
20
  coveralls (0.8.23)
21
21
  json (>= 1.8, < 3)
22
22
  simplecov (~> 0.16.1)
23
23
  term-ansicolor (~> 1.3)
24
24
  thor (>= 0.19.4, < 2.0)
25
25
  tins (~> 1.6)
26
- diff-lcs (1.3)
26
+ diff-lcs (1.4.4)
27
27
  docile (1.3.2)
28
- i18n (1.8.2)
28
+ i18n (1.8.5)
29
29
  concurrent-ruby (~> 1.0)
30
- jaro_winkler (1.5.4)
31
- json (2.3.0)
30
+ json (2.3.1)
32
31
  method_source (1.0.0)
33
- minitest (5.14.0)
34
- money (6.13.7)
32
+ minitest (5.14.2)
33
+ money (6.13.8)
35
34
  i18n (>= 0.6.4, <= 2)
36
- parallel (1.19.1)
37
- parser (2.7.1.0)
38
- ast (~> 2.4.0)
35
+ parallel (1.20.1)
36
+ parser (2.7.2.0)
37
+ ast (~> 2.4.1)
39
38
  pg (1.2.3)
40
- pry (0.13.0)
39
+ pry (0.13.1)
41
40
  coderay (~> 1.1)
42
41
  method_source (~> 1.0)
43
- rack (2.2.2)
42
+ rack (2.2.3)
44
43
  rainbow (3.0.0)
45
44
  rake (13.0.1)
45
+ regexp_parser (2.0.0)
46
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)
47
+ rspec (3.10.0)
48
+ rspec-core (~> 3.10.0)
49
+ rspec-expectations (~> 3.10.0)
50
+ rspec-mocks (~> 3.10.0)
51
+ rspec-core (3.10.0)
52
+ rspec-support (~> 3.10.0)
53
+ rspec-expectations (3.10.0)
54
54
  diff-lcs (>= 1.2.0, < 2.0)
55
- rspec-support (~> 3.9.0)
56
- rspec-mocks (3.9.1)
55
+ rspec-support (~> 3.10.0)
56
+ rspec-mocks (3.10.0)
57
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)
58
+ rspec-support (~> 3.10.0)
59
+ rspec-support (3.10.0)
60
+ rubocop (0.90.0)
62
61
  parallel (~> 1.10)
63
- parser (>= 2.7.0.1)
62
+ parser (>= 2.7.1.1)
64
63
  rainbow (>= 2.2.2, < 4.0)
64
+ regexp_parser (>= 1.7)
65
65
  rexml
66
+ rubocop-ast (>= 0.3.0, < 1.0)
66
67
  ruby-progressbar (~> 1.7)
67
68
  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
69
+ rubocop-ast (0.8.0)
70
+ parser (>= 2.7.1.5)
71
+ rubocop-config-umbrellio (0.90.0.93)
72
+ rubocop (= 0.90.0)
73
+ rubocop-performance (= 1.7.1)
74
+ rubocop-rails (= 2.7.0)
75
+ rubocop-rspec (= 1.42.0)
76
+ rubocop-performance (1.7.1)
77
+ rubocop (>= 0.82.0)
78
+ rubocop-rails (2.7.0)
79
+ activesupport (>= 4.2.0)
77
80
  rack (>= 1.1)
78
- rubocop (>= 0.72.0)
79
- rubocop-rspec (1.38.1)
80
- rubocop (>= 0.68.1)
81
+ rubocop (>= 0.87.0)
82
+ rubocop-rspec (1.42.0)
83
+ rubocop (>= 0.87.0)
81
84
  ruby-progressbar (1.10.1)
82
- sequel (5.31.0)
85
+ sequel (5.39.0)
83
86
  simplecov (0.16.1)
84
87
  docile (~> 1.1)
85
88
  json (>= 1.8, < 3)
@@ -91,12 +94,12 @@ GEM
91
94
  tins (~> 1.0)
92
95
  thor (1.0.1)
93
96
  thread_safe (0.3.6)
94
- tins (1.24.1)
97
+ tins (1.26.0)
95
98
  sync
96
- tzinfo (1.2.7)
99
+ tzinfo (1.2.8)
97
100
  thread_safe (~> 0.1)
98
101
  unicode-display_width (1.7.0)
99
- zeitwerk (2.3.0)
102
+ zeitwerk (2.4.2)
100
103
 
101
104
  PLATFORMS
102
105
  ruby
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,39 @@ 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
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
+
206
240
  ## Duplicate
207
241
 
208
242
  Enable: `Sequel::Model.plugin :duplicate`
@@ -302,7 +336,7 @@ Example:
302
336
 
303
337
  ```ruby
304
338
  class User < Sequel::Model
305
- store :data, :first_name
339
+ store :data, :first_name
306
340
  end
307
341
 
308
342
  user = User.create(first_name: "John")
@@ -354,7 +388,7 @@ Example:
354
388
  ```ruby
355
389
  user = User.first
356
390
  user.with_lock do
357
- user.update(name: "James")
391
+ user.update(name: "James")
358
392
  end
359
393
  ```
360
394
 
data/Rakefile CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
5
6
 
6
7
  RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new(:lint)
7
9
 
8
- task default: :spec
10
+ task default: %i[lint spec]
@@ -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.new("aes-256-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
+ Array(values).map { |x| Base64.strict_encode64(x) }.join(SEPARATOR)
45
+ end
46
+ end
@@ -8,10 +8,10 @@ module Sequel
8
8
  # Rollback a migration
9
9
  def undo(version)
10
10
  path = files.find { |file| migration_version_from_file(get_filename(file)) == version }
11
- raise "Migration #{version} does not exist in the filesystem" unless path
11
+ error!("Migration #{version} does not exist in the filesystem") unless path
12
12
 
13
13
  filename = get_filename(path)
14
- raise "Migration #{version} is not applied" unless applied_migrations.include?(filename)
14
+ error!("Migration #{version} is not applied") unless applied_migrations.include?(filename)
15
15
 
16
16
  migration = get_migration(path)
17
17
 
@@ -41,7 +41,7 @@ module Sequel
41
41
  end
42
42
  end
43
43
 
44
- Sequel::TimestampMigrator.prepend TimestampMigratorLogger
44
+ Sequel::TimestampMigrator.prepend(TimestampMigratorLogger)
45
45
 
46
46
  private
47
47
 
@@ -57,6 +57,10 @@ module Sequel
57
57
  def get_filename(path)
58
58
  File.basename(path).downcase
59
59
  end
60
+
61
+ def error!(message)
62
+ raise Sequel::Migrator::Error, message
63
+ end
60
64
  end
61
65
  end
62
66
  # rubocop:enable Layout/ClassStructure
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "umbrellio_sequel_plugins.rb"
3
+ require_relative "umbrellio_sequel_plugins"
@@ -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.114
4
+ version: 0.4.0.164
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-10 00:00:00.000000000 Z
11
+ date: 2020-12-02 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