attr_keyring 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/tests.yml +6 -3
- data/README.md +15 -0
- data/gemfiles/6_1.gemfile +5 -0
- data/lib/attr_keyring/active_record.rb +1 -1
- data/lib/attr_keyring/encoders/json_encoder.rb +15 -0
- data/lib/attr_keyring/version.rb +1 -1
- data/lib/attr_keyring.rb +16 -5
- data/lib/keyring/encryptor/aes.rb +4 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a1335e867e0b79f0f8082b6cceaa30e40feeb7a9cb140dbb133989ad47af66f
|
4
|
+
data.tar.gz: fa5803034ce08ff55f515fc87e774eeb16b96597e229f55266bfdafd51225dd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d2bc02c88a3871191cc41e32707452f1df9c50040991a8b09394d06a7a06d83a84b3574ac2e1e291e41cb8525d190213e31066eb9922440bbbe3426271829eb
|
7
|
+
data.tar.gz: '00086d53fd3bd74cc0ab4a1e5b511b02ddb081dc01531df75999461200c15b5e87069e0b38eb62f5c353ed121cb8f4657ec1e130aebfc0d254528a9365896389'
|
data/.github/workflows/tests.yml
CHANGED
@@ -4,6 +4,8 @@ name: Tests
|
|
4
4
|
on:
|
5
5
|
pull_request:
|
6
6
|
push:
|
7
|
+
workflow_dispatch:
|
8
|
+
inputs: {}
|
7
9
|
|
8
10
|
jobs:
|
9
11
|
build:
|
@@ -12,9 +14,10 @@ jobs:
|
|
12
14
|
strategy:
|
13
15
|
fail-fast: false
|
14
16
|
matrix:
|
15
|
-
ruby: ["2.7", "3.0"]
|
17
|
+
ruby: ["2.7", "3.0", "3.1"]
|
16
18
|
gemfile:
|
17
19
|
- gemfiles/7_0.gemfile
|
20
|
+
- gemfiles/6_1.gemfile
|
18
21
|
- gemfiles/6_0.gemfile
|
19
22
|
|
20
23
|
services:
|
@@ -26,9 +29,9 @@ jobs:
|
|
26
29
|
--health-retries 5
|
27
30
|
|
28
31
|
steps:
|
29
|
-
- uses: actions/checkout@
|
32
|
+
- uses: actions/checkout@v3.0.2
|
30
33
|
|
31
|
-
- uses: actions/cache@
|
34
|
+
- uses: actions/cache@v3.0.1
|
32
35
|
with:
|
33
36
|
path: vendor/bundle
|
34
37
|
key: >
|
data/README.md
CHANGED
@@ -144,6 +144,21 @@ user.encrypted_email
|
|
144
144
|
#=> WG8Epo0ABz0Z1X5gX7kttc98w9Ei59B5uXGK36Zin9G0VqbxX3naOWOm4RI6w6Uu
|
145
145
|
```
|
146
146
|
|
147
|
+
If you want to store a hash, you can use the `encoder:` option.
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
class User < ApplicationRecord
|
151
|
+
attr_keyring ENV["USER_KEYRING"],
|
152
|
+
digest_salt: "<custom salt>"
|
153
|
+
|
154
|
+
attr_encrypt :data, encoder: JSON
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
An encoder is just an object that responds to the methods `dump(data)` and
|
159
|
+
`parse(data)`, just like the `JSON` interface. Alternatively, you can use
|
160
|
+
`AttrKeyring::Encoders::JSON`, which returns hashes with symbolized keys.
|
161
|
+
|
147
162
|
### Encryption
|
148
163
|
|
149
164
|
By default, AES-128-CBC is the algorithm used for encryption. This algorithm
|
data/lib/attr_keyring/version.rb
CHANGED
data/lib/attr_keyring.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module AttrKeyring
|
4
4
|
require "attr_keyring/version"
|
5
5
|
require "keyring"
|
6
|
+
require "attr_keyring/encoders/json_encoder"
|
6
7
|
|
7
8
|
def self.active_record
|
8
9
|
require "attr_keyring/active_record"
|
@@ -23,7 +24,7 @@ module AttrKeyring
|
|
23
24
|
attr_accessor :encrypted_attributes, :keyring, :keyring_column_name
|
24
25
|
end
|
25
26
|
|
26
|
-
self.encrypted_attributes =
|
27
|
+
self.encrypted_attributes = {}
|
27
28
|
self.keyring = Keyring.new({}, digest_salt: "")
|
28
29
|
self.keyring_column_name = :keyring_id
|
29
30
|
end
|
@@ -42,11 +43,12 @@ module AttrKeyring
|
|
42
43
|
self.keyring = Keyring.new(keyring, options)
|
43
44
|
end
|
44
45
|
|
45
|
-
def attr_encrypt(*attributes)
|
46
|
-
self.encrypted_attributes ||=
|
47
|
-
encrypted_attributes.push(*attributes)
|
46
|
+
def attr_encrypt(*attributes, encoder: nil)
|
47
|
+
self.encrypted_attributes ||= {}
|
48
48
|
|
49
49
|
attributes.each do |attribute|
|
50
|
+
encrypted_attributes[attribute.to_sym] = {encoder: encoder}
|
51
|
+
|
50
52
|
define_attr_encrypt_writer(attribute)
|
51
53
|
define_attr_encrypt_reader(attribute)
|
52
54
|
end
|
@@ -70,6 +72,8 @@ module AttrKeyring
|
|
70
72
|
clear_decrypted_column_cache(attribute)
|
71
73
|
return reset_encrypted_column(attribute) unless encryptable_value?(value)
|
72
74
|
|
75
|
+
encoder = self.class.encrypted_attributes[attribute][:encoder]
|
76
|
+
value = encoder.dump(value) if encoder
|
73
77
|
value = value.to_s
|
74
78
|
|
75
79
|
previous_keyring_id = public_send(self.class.keyring_column_name)
|
@@ -86,6 +90,7 @@ module AttrKeyring
|
|
86
90
|
|
87
91
|
private def attr_decrypt_column(attribute)
|
88
92
|
cache_name = :"@#{attribute}"
|
93
|
+
|
89
94
|
if instance_variable_defined?(cache_name)
|
90
95
|
return instance_variable_get(cache_name)
|
91
96
|
end
|
@@ -99,6 +104,9 @@ module AttrKeyring
|
|
99
104
|
public_send(self.class.keyring_column_name)
|
100
105
|
)
|
101
106
|
|
107
|
+
encoder = self.class.encrypted_attributes[attribute][:encoder]
|
108
|
+
decrypted_value = encoder.parse(decrypted_value) if encoder
|
109
|
+
|
102
110
|
instance_variable_set(cache_name, decrypted_value)
|
103
111
|
end
|
104
112
|
|
@@ -123,10 +131,13 @@ module AttrKeyring
|
|
123
131
|
|
124
132
|
keyring_id = self.class.keyring.current_key.id
|
125
133
|
|
126
|
-
self.class.encrypted_attributes.each do |attribute|
|
134
|
+
self.class.encrypted_attributes.each do |attribute, options|
|
127
135
|
value = public_send(attribute)
|
128
136
|
next unless encryptable_value?(value)
|
129
137
|
|
138
|
+
encoder = options[:encoder]
|
139
|
+
value = encoder.dump(value) if encoder
|
140
|
+
|
130
141
|
encrypted_value, _, digest = self.class.keyring.encrypt(value)
|
131
142
|
|
132
143
|
public_send("encrypted_#{attribute}=", encrypted_value)
|
@@ -38,7 +38,10 @@ module Keyring
|
|
38
38
|
expected_hmac = hmac_digest(key.signing_key, encrypted_payload)
|
39
39
|
|
40
40
|
unless verify_signature(expected_hmac, hmac)
|
41
|
-
raise InvalidAuthentication,
|
41
|
+
raise InvalidAuthentication,
|
42
|
+
"Expected HMAC to be " \
|
43
|
+
"#{Base64.strict_encode64(expected_hmac)}; " \
|
44
|
+
"got #{Base64.strict_encode64(hmac)} instead"
|
42
45
|
end
|
43
46
|
|
44
47
|
cipher.iv = iv
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_keyring
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -204,9 +204,11 @@ files:
|
|
204
204
|
- examples/keyring_sample.rb
|
205
205
|
- examples/sequel_sample.rb
|
206
206
|
- gemfiles/6_0.gemfile
|
207
|
+
- gemfiles/6_1.gemfile
|
207
208
|
- gemfiles/7_0.gemfile
|
208
209
|
- lib/attr_keyring.rb
|
209
210
|
- lib/attr_keyring/active_record.rb
|
211
|
+
- lib/attr_keyring/encoders/json_encoder.rb
|
210
212
|
- lib/attr_keyring/sequel.rb
|
211
213
|
- lib/attr_keyring/version.rb
|
212
214
|
- lib/keyring.rb
|
@@ -231,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
233
|
- !ruby/object:Gem::Version
|
232
234
|
version: '0'
|
233
235
|
requirements: []
|
234
|
-
rubygems_version: 3.
|
236
|
+
rubygems_version: 3.3.7
|
235
237
|
signing_key:
|
236
238
|
specification_version: 4
|
237
239
|
summary: Simple encryption-at-rest plugin for ActiveRecord.
|