lockbox 0.3.3 → 0.3.4

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: 8198d9c7bf3be294c7efc7c7d03abbe64ccf8d487a0a81ad01151b225dbfde92
4
- data.tar.gz: dd51f9c1dc06a4cc657fb8b25a05f4a2960a2bce6883fd97dd41d1ac7e426e91
3
+ metadata.gz: c64ea693f929a79e495419fe5203760f73a2e1047602031eb90dcfd6542448d7
4
+ data.tar.gz: d5c43889eb01598b80ed47bb2d521fbd4970a94bf0e0880770f66f54d0ccfca9
5
5
  SHA512:
6
- metadata.gz: fe9c1274693558f3e184b7881f027c0e1ce895aeacd2c222451ea87a61ed7ff1064ed324a2e11a3bf35f60fa3647698ded89574a8c378ef42c0b538fe6606e1c
7
- data.tar.gz: 65ea6fb170250edf535692e085700430e4fe25ebca07e63d17de7e2f99afcb0d3089787a4b90c193b3314ae9bcde9540454eae3685a242da1e166c36d2982b19
6
+ metadata.gz: 760e4d28aaa0e3c059541ee91367112036e34bb87b64232d6de3a5e0c016ed59d47c79ea8549d67bb30922277869eed1187d2c5d77349430b7de81d50f2bc7d3
7
+ data.tar.gz: cee190766d994e26e05fce781c17404fd99fa74d1606c57f1103ed4e428abb0f2256779f005ace00123e07901fd3c4435083e6e950d8d01e92609625dfeca2da
@@ -1,3 +1,8 @@
1
+ ## 0.3.4 (2020-04-05)
2
+
3
+ - Fixed `migrating: true` with `validate: false`
4
+ - Fixed serialization when migrating certain column types
5
+
1
6
  ## 0.3.3 (2020-02-16)
2
7
 
3
8
  - Improved performance of `rotate` for attributes with blind indexes
data/README.md CHANGED
@@ -472,7 +472,7 @@ class UsersController < ApplicationController
472
472
  LockboxAudit.create!(
473
473
  subject: @user,
474
474
  viewer: current_user,
475
- data: ["email", "dob"],
475
+ data: ["name", "email"],
476
476
  context: "#{controller_name}##{action_name}",
477
477
  ip: request.remote_ip
478
478
  )
@@ -70,7 +70,7 @@ module Lockbox
70
70
  nonce, ciphertext = extract_nonce(@box, ciphertext)
71
71
  @box.decrypt(nonce, ciphertext, associated_data)
72
72
  end
73
- message = Lockbox.unpad(message, size: @padding) if @padding
73
+ message = Lockbox.unpad!(message, size: @padding) if @padding
74
74
  message
75
75
  end
76
76
 
@@ -3,6 +3,8 @@ module Lockbox
3
3
  def initialize(**options)
4
4
  options = Lockbox.default_options.merge(options)
5
5
  @encode = options.delete(:encode)
6
+ # option may be renamed to binary: true
7
+ # warn "[lockbox] Lockbox 1.0 will default to encode: true. Pass encode: false to keep the current behavior." if @encode.nil?
6
8
  previous_versions = options.delete(:previous_versions)
7
9
 
8
10
  @boxes =
@@ -81,16 +83,19 @@ module Lockbox
81
83
  target.set_encoding(source.external_encoding) if source.respond_to?(:external_encoding)
82
84
  end
83
85
 
86
+ # TODO remove in 0.4.0
84
87
  # legacy for attr_encrypted
85
88
  def self.encrypt(options)
86
89
  box(options).encrypt(options[:value])
87
90
  end
88
91
 
92
+ # TODO remove in 0.4.0
89
93
  # legacy for attr_encrypted
90
94
  def self.decrypt(options)
91
95
  box(options).decrypt(options[:value])
92
96
  end
93
97
 
98
+ # TODO remove in 0.4.0
94
99
  # legacy for attr_encrypted
95
100
  def self.box(options)
96
101
  options = options.slice(:key, :encryption_key, :decryption_key, :algorithm, :previous_versions)
@@ -67,7 +67,7 @@ module Lockbox
67
67
 
68
68
  relation = relation.merge(or_relation)
69
69
  else
70
- relation = relation.or(attributes.map { |a| {a => nil} })
70
+ relation.merge(relation.unscoped.or(attributes.map { |a| {a => nil} }))
71
71
  end
72
72
  end
73
73
 
@@ -125,7 +125,13 @@ module Lockbox
125
125
  serialize name, JSON if options[:type] == :json
126
126
  serialize name, Hash if options[:type] == :hash
127
127
  elsif !attributes_to_define_after_schema_loads.key?(name.to_s)
128
- attribute name, :string
128
+ # when migrating it's best to specify the type directly
129
+ # however, we can try to use the original type if its already defined
130
+ if attributes_to_define_after_schema_loads.key?(original_name.to_s)
131
+ attribute name, attributes_to_define_after_schema_loads[original_name.to_s].first
132
+ else
133
+ attribute name, :string
134
+ end
129
135
  end
130
136
 
131
137
  define_method("#{name}_was") do
@@ -330,9 +336,23 @@ module Lockbox
330
336
  end
331
337
 
332
338
  if options[:migrating]
333
- before_validation do
334
- send("#{name}=", send(original_name)) if send("#{original_name}_changed?")
339
+ # TODO reuse module
340
+ m = Module.new do
341
+ define_method "#{original_name}=" do |value|
342
+ result = super(value)
343
+ send("#{name}=", send(original_name))
344
+ result
345
+ end
346
+
347
+ unless activerecord
348
+ define_method "reset_#{original_name}!" do
349
+ result = super()
350
+ send("#{name}=", send(original_name))
351
+ result
352
+ end
353
+ end
335
354
  end
355
+ prepend m
336
356
  end
337
357
  end
338
358
  end
@@ -3,16 +3,24 @@ module Lockbox
3
3
  PAD_FIRST_BYTE = "\x80".b
4
4
  PAD_ZERO_BYTE = "\x00".b
5
5
 
6
+ def pad(str, **options)
7
+ pad!(str.dup, **options)
8
+ end
9
+
10
+ def unpad(str, **options)
11
+ unpad!(str.dup, **options)
12
+ end
13
+
6
14
  # ISO/IEC 7816-4
7
15
  # same as Libsodium
8
16
  # https://libsodium.gitbook.io/doc/padding
9
17
  # apply prior to encryption
10
18
  # note: current implementation does not
11
19
  # try to minimize side channels
12
- def pad(str, size: 16)
20
+ def pad!(str, size: 16)
13
21
  raise ArgumentError, "Invalid size" if size < 1
14
22
 
15
- str = str.dup.force_encoding(Encoding::BINARY)
23
+ str.force_encoding(Encoding::BINARY)
16
24
 
17
25
  pad_length = size - 1
18
26
  pad_length -= str.bytesize % size
@@ -27,12 +35,10 @@ module Lockbox
27
35
 
28
36
  # note: current implementation does not
29
37
  # try to minimize side channels
30
- def unpad(str, size: 16)
38
+ def unpad!(str, size: 16)
31
39
  raise ArgumentError, "Invalid size" if size < 1
32
40
 
33
- if str.encoding != Encoding::BINARY
34
- str = str.dup.force_encoding(Encoding::BINARY)
35
- end
41
+ str.force_encoding(Encoding::BINARY)
36
42
 
37
43
  i = 1
38
44
  while i <= size
@@ -40,7 +46,8 @@ module Lockbox
40
46
  when PAD_ZERO_BYTE
41
47
  i += 1
42
48
  when PAD_FIRST_BYTE
43
- return str[0..-(i + 1)]
49
+ str.slice!(-i..-1)
50
+ return str
44
51
  else
45
52
  break
46
53
  end
@@ -2,6 +2,7 @@ module Lockbox
2
2
  class Utils
3
3
  def self.build_box(context, options, table, attribute)
4
4
  options = options.except(:attribute, :encrypted_attribute, :migrating, :attached, :type)
5
+ options[:encode] = false unless options.key?(:encode)
5
6
  options.each do |k, v|
6
7
  if v.is_a?(Proc)
7
8
  options[k] = context.instance_exec(&v) if v.respond_to?(:call)
@@ -1,3 +1,3 @@
1
1
  module Lockbox
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lockbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-16 00:00:00.000000000 Z
11
+ date: 2020-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler