sidekiq-field-encryptor 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +2 -0
- data/.github/workflows/test.yml +49 -0
- data/.rspec +2 -1
- data/.rubocop-https---raw-githubusercontent-com-aptible-dryer-lint-main--rubocop-base-yml +353 -0
- data/.rubocop.yml +16 -0
- data/.rubocop_ignore.yml +11 -0
- data/Gemfile +2 -0
- data/README.md +2 -3
- data/Rakefile +2 -3
- data/SECURITY.md +23 -0
- data/lib/sidekiq-field-encryptor/encryptor.rb +13 -6
- data/lib/sidekiq-field-encryptor/version.rb +3 -1
- data/lib/sidekiq-field-encryptor.rb +2 -0
- data/sidekiq-field-encryptor.gemspec +6 -5
- data/spec/sidekiq-field-encryptor/encryptor_spec.rb +21 -17
- data/spec/spec_helper.rb +2 -0
- metadata +22 -19
- data/.travis.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17ebe672dfa0a9ce9941c411ae902205222c07606a74cb4515fcd69bea950a00
|
4
|
+
data.tar.gz: 6e5a0a1942a16b0a59a04ff8b6f31d4a60637bf7036634286ed7892c726ec705
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 223e413322218a774fad26818770f62a3604e2461e8a3941f52f4670a211c1a0ccacdb57642a7abd8d79d34a25a0d49dd44d6dacd044808f6ff3b69580ced6b2
|
7
|
+
data.tar.gz: 0bccf7635de692edb8c21bf39dc86f15c7fb96015df2df2623f3636922b72ab7a7c822f99f2357eaae9245ffd6f525229594029cf8053eeb193779f3187a7a8e
|
data/.github/CODEOWNERS
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
- master
|
8
|
+
push:
|
9
|
+
branches:
|
10
|
+
- main
|
11
|
+
- master
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
name: Test Ruby ${{ matrix.RUBY_VERSION }}
|
16
|
+
runs-on: ubuntu-24.04
|
17
|
+
strategy:
|
18
|
+
fail-fast: false
|
19
|
+
matrix:
|
20
|
+
RUBY_VERSION: ["2.6", "3.3"]
|
21
|
+
steps:
|
22
|
+
- name: Check out code
|
23
|
+
uses: actions/checkout@v4
|
24
|
+
|
25
|
+
- name: Install Ruby
|
26
|
+
uses: ruby/setup-ruby@v1
|
27
|
+
with:
|
28
|
+
ruby-version: ${{ matrix.RUBY_VERSION }}
|
29
|
+
bundler-cache: true
|
30
|
+
|
31
|
+
- name: Run Lint
|
32
|
+
run: bundle exec rubocop
|
33
|
+
|
34
|
+
- name: Run Tests
|
35
|
+
run: bundle exec rspec
|
36
|
+
|
37
|
+
results:
|
38
|
+
if: ${{ always() }}
|
39
|
+
runs-on: ubuntu-latest
|
40
|
+
name: Final Results
|
41
|
+
needs: [test]
|
42
|
+
steps:
|
43
|
+
- run: exit 1
|
44
|
+
# see https://stackoverflow.com/a/67532120/4907315
|
45
|
+
if: >-
|
46
|
+
${{
|
47
|
+
contains(needs.*.result, 'failure')
|
48
|
+
|| contains(needs.*.result, 'cancelled')
|
49
|
+
}}
|
data/.rspec
CHANGED
@@ -0,0 +1,353 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
|
4
|
+
Gemspec/DeprecatedAttributeAssignment:
|
5
|
+
Enabled: true
|
6
|
+
|
7
|
+
Gemspec/RequireMFA:
|
8
|
+
Enabled: true
|
9
|
+
|
10
|
+
Layout/LineContinuationLeadingSpace:
|
11
|
+
Enabled: true
|
12
|
+
|
13
|
+
Layout/LineContinuationSpacing:
|
14
|
+
Enabled: true
|
15
|
+
|
16
|
+
Layout/LineEndStringConcatenationIndentation:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Layout/SpaceBeforeBrackets:
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Lint/AmbiguousAssignment:
|
23
|
+
Enabled: true
|
24
|
+
|
25
|
+
Lint/AmbiguousOperatorPrecedence:
|
26
|
+
Enabled: true
|
27
|
+
|
28
|
+
Lint/AmbiguousRange:
|
29
|
+
Enabled: true
|
30
|
+
|
31
|
+
Lint/ConstantOverwrittenInRescue:
|
32
|
+
Enabled: true
|
33
|
+
|
34
|
+
Lint/DeprecatedConstants:
|
35
|
+
Enabled: true
|
36
|
+
|
37
|
+
Lint/DuplicateBranch:
|
38
|
+
Enabled: true
|
39
|
+
|
40
|
+
Lint/DuplicateMagicComment:
|
41
|
+
Enabled: true
|
42
|
+
|
43
|
+
Lint/DuplicateRegexpCharacterClassElement:
|
44
|
+
Enabled: true
|
45
|
+
|
46
|
+
Lint/EmptyBlock:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Lint/EmptyClass:
|
50
|
+
Enabled: true
|
51
|
+
|
52
|
+
Lint/EmptyInPattern:
|
53
|
+
Enabled: true
|
54
|
+
|
55
|
+
Lint/IncompatibleIoSelectWithFiberScheduler:
|
56
|
+
Enabled: true
|
57
|
+
|
58
|
+
Lint/LambdaWithoutLiteralBlock:
|
59
|
+
Enabled: true
|
60
|
+
|
61
|
+
Lint/NoReturnInBeginEndBlocks:
|
62
|
+
Enabled: true
|
63
|
+
|
64
|
+
Lint/NonAtomicFileOperation:
|
65
|
+
Enabled: true
|
66
|
+
|
67
|
+
Lint/NumberedParameterAssignment:
|
68
|
+
Enabled: true
|
69
|
+
|
70
|
+
Lint/OrAssignmentToConstant:
|
71
|
+
Enabled: true
|
72
|
+
|
73
|
+
Lint/RedundantDirGlobSort:
|
74
|
+
Enabled: true
|
75
|
+
|
76
|
+
Lint/RefinementImportMethods:
|
77
|
+
Enabled: true
|
78
|
+
|
79
|
+
Lint/RequireRangeParentheses:
|
80
|
+
Enabled: true
|
81
|
+
|
82
|
+
Lint/RequireRelativeSelfPath:
|
83
|
+
Enabled: true
|
84
|
+
|
85
|
+
Lint/SymbolConversion:
|
86
|
+
Enabled: true
|
87
|
+
|
88
|
+
Lint/ToEnumArguments:
|
89
|
+
Enabled: true
|
90
|
+
|
91
|
+
Lint/TripleQuotes:
|
92
|
+
Enabled: true
|
93
|
+
|
94
|
+
Lint/UnexpectedBlockArity:
|
95
|
+
Enabled: true
|
96
|
+
|
97
|
+
Lint/UnmodifiedReduceAccumulator:
|
98
|
+
Enabled: true
|
99
|
+
|
100
|
+
Lint/UselessRuby2Keywords:
|
101
|
+
Enabled: true
|
102
|
+
|
103
|
+
Security/CompoundHash:
|
104
|
+
Enabled: true
|
105
|
+
|
106
|
+
Security/IoMethods:
|
107
|
+
Enabled: true
|
108
|
+
|
109
|
+
Style/ArgumentsForwarding:
|
110
|
+
Enabled: true
|
111
|
+
|
112
|
+
Style/CollectionCompact:
|
113
|
+
Enabled: true
|
114
|
+
|
115
|
+
Style/DocumentDynamicEvalDefinition:
|
116
|
+
Enabled: true
|
117
|
+
|
118
|
+
Style/EmptyHeredoc:
|
119
|
+
Enabled: true
|
120
|
+
|
121
|
+
Style/EndlessMethod:
|
122
|
+
Enabled: true
|
123
|
+
|
124
|
+
Style/EnvHome:
|
125
|
+
Enabled: true
|
126
|
+
|
127
|
+
Style/FetchEnvVar:
|
128
|
+
Enabled: true
|
129
|
+
|
130
|
+
Style/FileRead:
|
131
|
+
Enabled: true
|
132
|
+
|
133
|
+
Style/FileWrite:
|
134
|
+
Enabled: true
|
135
|
+
|
136
|
+
# TODO - remove this when this has been released on rubocop
|
137
|
+
Style/GuardClause:
|
138
|
+
Enabled: false
|
139
|
+
|
140
|
+
Style/HashConversion:
|
141
|
+
Enabled: true
|
142
|
+
|
143
|
+
Style/HashExcept:
|
144
|
+
Enabled: true
|
145
|
+
|
146
|
+
Style/IfWithBooleanLiteralBranches:
|
147
|
+
Enabled: true
|
148
|
+
|
149
|
+
Style/InPatternThen:
|
150
|
+
Enabled: true
|
151
|
+
|
152
|
+
Style/MagicCommentFormat:
|
153
|
+
Enabled: true
|
154
|
+
|
155
|
+
Style/MapCompactWithConditionalBlock:
|
156
|
+
Enabled: true
|
157
|
+
|
158
|
+
Style/MapToHash:
|
159
|
+
Enabled: true
|
160
|
+
|
161
|
+
Style/MultilineInPatternThen:
|
162
|
+
Enabled: true
|
163
|
+
|
164
|
+
Style/NegatedIfElseCondition:
|
165
|
+
Enabled: true
|
166
|
+
|
167
|
+
Style/NestedFileDirname:
|
168
|
+
Enabled: true
|
169
|
+
|
170
|
+
Style/NilLambda:
|
171
|
+
Enabled: true
|
172
|
+
|
173
|
+
Style/NumberedParameters:
|
174
|
+
Enabled: true
|
175
|
+
|
176
|
+
Style/NumberedParametersLimit:
|
177
|
+
Enabled: true
|
178
|
+
|
179
|
+
Style/NumericLiterals:
|
180
|
+
Enabled: false
|
181
|
+
|
182
|
+
Style/ObjectThen:
|
183
|
+
Enabled: true
|
184
|
+
|
185
|
+
Style/OpenStructUse:
|
186
|
+
Enabled: true
|
187
|
+
|
188
|
+
Style/OperatorMethodCall:
|
189
|
+
Enabled: true
|
190
|
+
|
191
|
+
Style/QuotedSymbols:
|
192
|
+
Enabled: true
|
193
|
+
|
194
|
+
Style/RedundantArgument:
|
195
|
+
Enabled: true
|
196
|
+
|
197
|
+
Style/RedundantEach:
|
198
|
+
Enabled: true
|
199
|
+
|
200
|
+
Style/RedundantInitialize:
|
201
|
+
Enabled: true
|
202
|
+
|
203
|
+
Style/RedundantSelfAssignmentBranch:
|
204
|
+
Enabled: true
|
205
|
+
|
206
|
+
Style/RedundantStringEscape:
|
207
|
+
Enabled: true
|
208
|
+
|
209
|
+
Style/SelectByRegexp:
|
210
|
+
Enabled: true
|
211
|
+
|
212
|
+
Style/StringChars:
|
213
|
+
Enabled: true
|
214
|
+
|
215
|
+
Style/SwapValues:
|
216
|
+
Enabled: true
|
217
|
+
|
218
|
+
RSpec/BeEq:
|
219
|
+
Enabled: true
|
220
|
+
|
221
|
+
RSpec/BeNil:
|
222
|
+
Enabled: true
|
223
|
+
|
224
|
+
RSpec/ChangeByZero:
|
225
|
+
Enabled: true
|
226
|
+
|
227
|
+
RSpec/ClassCheck:
|
228
|
+
Enabled: true
|
229
|
+
|
230
|
+
RSpec/ExcessiveDocstringSpacing:
|
231
|
+
Enabled: true
|
232
|
+
|
233
|
+
RSpec/IdenticalEqualityAssertion:
|
234
|
+
Enabled: true
|
235
|
+
|
236
|
+
RSpec/SortMetadata:
|
237
|
+
Enabled: true
|
238
|
+
|
239
|
+
RSpec/SubjectDeclaration:
|
240
|
+
Enabled: true
|
241
|
+
|
242
|
+
RSpec/StubbedMock:
|
243
|
+
Enabled: false
|
244
|
+
|
245
|
+
RSpec/VerifiedDoubleReference:
|
246
|
+
Enabled: true
|
247
|
+
|
248
|
+
###############################################################################
|
249
|
+
## Customizations ##
|
250
|
+
###############################################################################
|
251
|
+
|
252
|
+
# Try to keep a balance between the fact that some people are
|
253
|
+
# working from laptops and the fact that unnecessarily short
|
254
|
+
# lines make code hard to read.
|
255
|
+
Layout/LineLength:
|
256
|
+
Enabled: true
|
257
|
+
Max: 120
|
258
|
+
|
259
|
+
# TODO: We have enough places where this isn't used that it would
|
260
|
+
# be hard to switch, but maybe we should enable in the future?
|
261
|
+
RSpec/NamedSubject:
|
262
|
+
Enabled: false
|
263
|
+
|
264
|
+
# Sometimes our tests are only confirming that
|
265
|
+
# an exception isn't raised.
|
266
|
+
RSpec/NoExpectationExample:
|
267
|
+
Enabled: false
|
268
|
+
|
269
|
+
# These sometimes make tests look nicer.
|
270
|
+
RSpec/NestedGroups:
|
271
|
+
Enabled: false
|
272
|
+
|
273
|
+
RSpec/RepeatedExampleGroupBody:
|
274
|
+
Enabled: false
|
275
|
+
|
276
|
+
RSpec/MultipleMemoizedHelpers:
|
277
|
+
Max: 20
|
278
|
+
|
279
|
+
RSpec/SubjectStub:
|
280
|
+
Enabled: false
|
281
|
+
|
282
|
+
RSpec/MessageSpies:
|
283
|
+
Enabled: false
|
284
|
+
|
285
|
+
RSpec/ExpectInHook:
|
286
|
+
Enabled: false
|
287
|
+
|
288
|
+
RSpec/MultipleExpectations:
|
289
|
+
Enabled: false
|
290
|
+
|
291
|
+
RSpec/ExampleLength:
|
292
|
+
Enabled: false
|
293
|
+
|
294
|
+
# These aren't effective enough at calculating the right
|
295
|
+
# kinds of complexity.
|
296
|
+
Metrics/CyclomaticComplexity:
|
297
|
+
Enabled: false
|
298
|
+
|
299
|
+
Metrics/AbcSize:
|
300
|
+
Enabled: false
|
301
|
+
|
302
|
+
Metrics/PerceivedComplexity:
|
303
|
+
Enabled: false
|
304
|
+
|
305
|
+
# Favor explicit over implicit.
|
306
|
+
Metrics/ParameterLists:
|
307
|
+
Max: 20
|
308
|
+
|
309
|
+
Style/HashSyntax:
|
310
|
+
Enabled: false
|
311
|
+
|
312
|
+
Naming/BlockForwarding:
|
313
|
+
Enabled: true
|
314
|
+
EnforcedStyle: explicit
|
315
|
+
|
316
|
+
# This probably isn't right to disable, but at the same time, there
|
317
|
+
# are places where we're using (valid) boilerplate code that adds up.
|
318
|
+
Metrics/MethodLength:
|
319
|
+
Enabled: false
|
320
|
+
|
321
|
+
# This probably isn't best to change either, but some modules and corresponding
|
322
|
+
# helpers will have a fair number of lines and this seems arbitrarily limiting
|
323
|
+
Metrics/ModuleLength:
|
324
|
+
Enabled: false
|
325
|
+
|
326
|
+
# We may want to re-enable this in the future with a reasonable value,
|
327
|
+
# but right now this is overly prescriptive, especially in scenarios
|
328
|
+
# where we have a lot of boilerplate code.
|
329
|
+
Metrics/ClassLength:
|
330
|
+
Enabled: false
|
331
|
+
|
332
|
+
# This is fine being a judgement call.
|
333
|
+
Metrics/BlockLength:
|
334
|
+
Enabled: false
|
335
|
+
|
336
|
+
# This is overly prescriptive with minimal gain.
|
337
|
+
RSpec/ContextWording:
|
338
|
+
Enabled: false
|
339
|
+
|
340
|
+
# This is allowing something implicit, which isn't ideal,
|
341
|
+
# but it's also something we heavily leverage.
|
342
|
+
RSpec/LetSetup:
|
343
|
+
Enabled: false
|
344
|
+
|
345
|
+
# This doesn't feel great to add, but unfortunately it's making
|
346
|
+
# incorrect assumptions about some of our function names
|
347
|
+
# which causes a lot of false positives.
|
348
|
+
RSpec/PredicateMatcher:
|
349
|
+
Enabled: false
|
350
|
+
|
351
|
+
# There are valid reasons to do this.
|
352
|
+
RSpec/InstanceVariable:
|
353
|
+
Enabled: false
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
inherit_from:
|
2
|
+
- https://raw.githubusercontent.com/aptible/dryer-lint/main/.rubocop.base.yml
|
3
|
+
- .rubocop_ignore.yml
|
4
|
+
|
5
|
+
Style/GuardClause:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
AllCops:
|
9
|
+
TargetRubyVersion: 3.1
|
10
|
+
NewCops: disable
|
11
|
+
Include:
|
12
|
+
- !ruby/regexp /\.rb$/
|
13
|
+
- !ruby/regexp /Gemfile$/
|
14
|
+
- !ruby/regexp /\.gemspec$/
|
15
|
+
- !ruby/regexp /\.rake$/
|
16
|
+
- !ruby/regexp /Rakefile$/
|
data/.rubocop_ignore.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# ![](https://raw.github.com/aptible/straptible/master/lib/straptible/rails/templates/public.api/icon-60px.png) Sidekiq::Field::Encryptor
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/sidekiq-field-encryptor.png)](https://rubygems.org/gems/sidekiq-field-encryptor)
|
4
|
-
[![Build Status](https://travis-ci.org/aptible/sidekiq-field-encryptor.png?branch=master)](https://travis-ci.org/aptible/sidekiq-field-encryptor)
|
5
4
|
[![Dependency Status](https://gemnasium.com/aptible/sidekiq-field-encryptor.png)](https://gemnasium.com/aptible/sidekiq-field-encryptor)
|
6
5
|
|
7
6
|
This is a utility which is intended to be used for encrypting sensitive data in Sidekiq jobs. The data is encrypted before sending it to Redis, and decrypted right before the Sidekiq job is executed.
|
@@ -39,11 +38,11 @@ decrypt the values inside the client before the job is executed.
|
|
39
38
|
|
40
39
|
1. Fork the project.
|
41
40
|
1. Commit your changes, with specs.
|
42
|
-
1. Ensure that your code passes specs (`
|
41
|
+
1. Ensure that your code passes specs (`bundle exec rspec`) and meets Aptible's Ruby style guide (`bundle exec rubocop`).
|
43
42
|
1. Create a new pull request on GitHub.
|
44
43
|
|
45
44
|
## Copyright and License
|
46
45
|
|
47
46
|
MIT License, see [LICENSE](LICENSE.md) for details.
|
48
47
|
|
49
|
-
Copyright (c)
|
48
|
+
Copyright (c) 2024 [Aptible](https://www.aptible.com), Blake Pettersson, and contributors.
|
data/Rakefile
CHANGED
data/SECURITY.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Aptible Open Source Security Policies and Procedures
|
2
|
+
|
3
|
+
This document outlines security procedures and general policies for the Aptible open source projects as found on https://github.com/aptible.
|
4
|
+
|
5
|
+
* [Reporting a Vulnerability](#reporting-a-vulnerability)
|
6
|
+
* [Responsible Disclosure Policy](#responsible-disclosure-policy)
|
7
|
+
|
8
|
+
## Reporting a Vulnerability
|
9
|
+
|
10
|
+
The Aptible team and community take all security vulnerabilities
|
11
|
+
seriously. Thank you for improving the security of our open source software. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.
|
12
|
+
|
13
|
+
Report security vulnerabilities by emailing the Aptible security team at:
|
14
|
+
|
15
|
+
security@aptible.com
|
16
|
+
|
17
|
+
Security researchers can also privately report security vulnerabilities to repository maintainers using the GitHub "Report a Vulnerability" feature. [See how-to here](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability).
|
18
|
+
|
19
|
+
The Aptible team will acknowledge your email within 24 business hours and send a detailed response within 48 business hours indicating the next steps in handling your report. The Aptible security team will keep you informed of the progress and may ask for additional information or guidance.
|
20
|
+
|
21
|
+
## Responsible Disclosure Policy
|
22
|
+
|
23
|
+
Please see Aptible's Responsible Disclosure Policy here: https://www.aptible.com/legal/responsible-disclosure/
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'base64'
|
2
4
|
require 'encryptor'
|
3
5
|
require 'json'
|
@@ -22,9 +24,10 @@ require 'sidekiq-field-encryptor/version'
|
|
22
24
|
# Will encrypt the values {'x' => 1} and 'b' when storing the job in Redis and
|
23
25
|
# decrypt the values inside the client before the job is executed.
|
24
26
|
module SidekiqFieldEncryptor
|
25
|
-
SERIALIZE_JSON = 'json'
|
26
|
-
SERIALIZE_MARHSALL = 'marshal'
|
27
|
+
SERIALIZE_JSON = 'json'
|
28
|
+
SERIALIZE_MARHSALL = 'marshal'
|
27
29
|
|
30
|
+
# Shared methods between client and base
|
28
31
|
class Base
|
29
32
|
def initialize(options = {})
|
30
33
|
@encryption_key = options[:encryption_key]
|
@@ -60,7 +63,7 @@ module SidekiqFieldEncryptor
|
|
60
63
|
JSON.parse(value, quirks_mode: true)
|
61
64
|
when SERIALIZE_MARHSALL, nil
|
62
65
|
# No method used to be Marshall, so we respect this here
|
63
|
-
Marshal.load(value)
|
66
|
+
Marshal.load(value) # rubocop:disable Security/MarshalLoad
|
64
67
|
else
|
65
68
|
raise "Invalid serialization_method: #{@serialization_method}"
|
66
69
|
end
|
@@ -68,7 +71,7 @@ module SidekiqFieldEncryptor
|
|
68
71
|
|
69
72
|
def encrypt(value)
|
70
73
|
plaintext = serialize(value)
|
71
|
-
iv = OpenSSL::Cipher
|
74
|
+
iv = OpenSSL::Cipher.new(@encryption_algorithm).random_iv
|
72
75
|
args = { key: @encryption_key, iv: iv, algorithm: @encryption_algorithm }
|
73
76
|
ciphertext = ::Encryptor.encrypt(plaintext, **args)
|
74
77
|
[
|
@@ -90,23 +93,26 @@ module SidekiqFieldEncryptor
|
|
90
93
|
def process_message(message)
|
91
94
|
fields = @encrypted_fields[message['class']]
|
92
95
|
return unless fields
|
96
|
+
|
93
97
|
assert_key_configured
|
94
98
|
message['args'].size.times.each do |arg_index|
|
95
99
|
to_encrypt = fields[arg_index]
|
96
100
|
next unless to_encrypt
|
101
|
+
|
97
102
|
raw_value = message['args'][arg_index]
|
98
103
|
if to_encrypt == true
|
99
104
|
message['args'][arg_index] = yield(raw_value)
|
100
105
|
elsif to_encrypt.is_a?(Array) && raw_value.is_a?(Hash)
|
101
|
-
message['args'][arg_index] =
|
106
|
+
message['args'][arg_index] = raw_value.to_h do |key, value|
|
102
107
|
value = yield(value) if to_encrypt.member?(key.to_s)
|
103
108
|
[key, value]
|
104
|
-
end
|
109
|
+
end
|
105
110
|
end
|
106
111
|
end
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
115
|
+
# Used when encrypting fields
|
110
116
|
class Client < Base
|
111
117
|
def call(_, message, _, _)
|
112
118
|
process_message(message) { |value| encrypt(value) }
|
@@ -114,6 +120,7 @@ module SidekiqFieldEncryptor
|
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
123
|
+
# Used when decrypting fields
|
117
124
|
class Server < Base
|
118
125
|
def call(_, message, _)
|
119
126
|
process_message(message) { |value| decrypt(value) }
|
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
|
5
6
|
require 'English'
|
@@ -16,13 +17,13 @@ Gem::Specification.new do |spec|
|
|
16
17
|
spec.license = 'MIT'
|
17
18
|
|
18
19
|
spec.files = `git ls-files`.split($RS)
|
19
|
-
spec.test_files = spec.files.grep(%r{^spec/})
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
22
|
spec.add_dependency 'encryptor'
|
23
23
|
|
24
24
|
spec.add_development_dependency 'bundler'
|
25
|
-
spec.add_development_dependency 'aptible-tasks'
|
26
25
|
spec.add_development_dependency 'rake'
|
27
|
-
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.12'
|
27
|
+
spec.add_development_dependency 'rubocop-rspec'
|
28
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
28
29
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe SidekiqFieldEncryptor::Client do
|
4
|
-
let(:key) { OpenSSL::Cipher
|
6
|
+
let(:key) { OpenSSL::Cipher.new('aes-256-cbc').random_key }
|
5
7
|
let(:message) do
|
6
8
|
{ 'class' => 'FooJob', 'args' => [1, 2, { 'a' => 'A', 'b' => 'B' }] }
|
7
9
|
end
|
@@ -10,8 +12,9 @@ describe SidekiqFieldEncryptor::Client do
|
|
10
12
|
it "doesn't fail when encryption isn't attempted" do
|
11
13
|
subject.call('FooJob', message, nil, nil) {}
|
12
14
|
end
|
15
|
+
|
13
16
|
it 'fails when encryption is attempted' do
|
14
|
-
client =
|
17
|
+
client = described_class.new(
|
15
18
|
encrypted_fields: { 'FooJob' => { 1 => true } }
|
16
19
|
)
|
17
20
|
expect { client.call('FooJob', message, nil, nil) {} }
|
@@ -21,9 +24,9 @@ describe SidekiqFieldEncryptor::Client do
|
|
21
24
|
|
22
25
|
describe 'with an encryption key' do
|
23
26
|
subject do
|
24
|
-
|
27
|
+
described_class.new(
|
25
28
|
encryption_key: key,
|
26
|
-
encrypted_fields: { 'FooJob' => { 1 => true, 2 => %w
|
29
|
+
encrypted_fields: { 'FooJob' => { 1 => true, 2 => %w[b d] } }
|
27
30
|
)
|
28
31
|
end
|
29
32
|
|
@@ -37,16 +40,16 @@ describe SidekiqFieldEncryptor::Client do
|
|
37
40
|
end
|
38
41
|
|
39
42
|
it 'supports setting the encryption algorithm' do
|
40
|
-
key = OpenSSL::Cipher
|
41
|
-
fields = { 'FooJob' => { 1 => true, 2 => %w
|
43
|
+
key = OpenSSL::Cipher.new('aes-128-cbc').random_key
|
44
|
+
fields = { 'FooJob' => { 1 => true, 2 => %w[b d] } }
|
42
45
|
|
43
|
-
ko =
|
46
|
+
ko = described_class.new(
|
44
47
|
encryption_key: key,
|
45
48
|
encryption_algorithm: 'aes-256-cbc',
|
46
49
|
encrypted_fields: fields
|
47
50
|
)
|
48
51
|
|
49
|
-
ok =
|
52
|
+
ok = described_class.new(
|
50
53
|
encryption_key: key,
|
51
54
|
encryption_algorithm: 'aes-128-cbc',
|
52
55
|
encrypted_fields: fields
|
@@ -60,7 +63,7 @@ describe SidekiqFieldEncryptor::Client do
|
|
60
63
|
end
|
61
64
|
|
62
65
|
describe SidekiqFieldEncryptor::Server do
|
63
|
-
let(:key) { OpenSSL::Cipher
|
66
|
+
let(:key) { OpenSSL::Cipher.new('aes-256-cbc').random_key }
|
64
67
|
let(:message) do
|
65
68
|
{ 'class' => 'FooJob', 'args' => [1, 2, { 'a' => 'A', 'b' => 'B' }] }
|
66
69
|
end
|
@@ -69,8 +72,9 @@ describe SidekiqFieldEncryptor::Server do
|
|
69
72
|
it "doesn't fail when decryption isn't attempted" do
|
70
73
|
subject.call('FooJob', message, nil) {}
|
71
74
|
end
|
75
|
+
|
72
76
|
it 'fails when decryption is attempted' do
|
73
|
-
server =
|
77
|
+
server = described_class.new(
|
74
78
|
encrypted_fields: { 'FooJob' => { 1 => true } }
|
75
79
|
)
|
76
80
|
expect { server.call('FooJob', message, nil) {} }
|
@@ -80,9 +84,9 @@ describe SidekiqFieldEncryptor::Server do
|
|
80
84
|
|
81
85
|
describe 'with an encryption key' do
|
82
86
|
subject do
|
83
|
-
|
87
|
+
described_class.new(
|
84
88
|
encryption_key: key,
|
85
|
-
encrypted_fields: { 'FooJob' => { 1 => true, 2 => %w
|
89
|
+
encrypted_fields: { 'FooJob' => { 1 => true, 2 => %w[b d] } }
|
86
90
|
)
|
87
91
|
end
|
88
92
|
|
@@ -95,16 +99,16 @@ describe SidekiqFieldEncryptor::Server do
|
|
95
99
|
end
|
96
100
|
|
97
101
|
it 'supports setting the encryption algorithm' do
|
98
|
-
key = OpenSSL::Cipher
|
102
|
+
key = OpenSSL::Cipher.new('aes-128-cbc').random_key
|
99
103
|
fields = { 'FooJob' => { 1 => true } }
|
100
104
|
|
101
|
-
ko =
|
105
|
+
ko = described_class.new(
|
102
106
|
encryption_key: key,
|
103
107
|
encryption_algorithm: 'aes-256-cbc',
|
104
108
|
encrypted_fields: fields
|
105
109
|
)
|
106
110
|
|
107
|
-
ok =
|
111
|
+
ok = described_class.new(
|
108
112
|
encryption_key: key,
|
109
113
|
encryption_algorithm: 'aes-128-cbc',
|
110
114
|
encrypted_fields: fields
|
@@ -119,7 +123,7 @@ describe SidekiqFieldEncryptor::Server do
|
|
119
123
|
end
|
120
124
|
|
121
125
|
it 'fails if the serialization methods are different' do
|
122
|
-
r =
|
126
|
+
r = described_class.new(
|
123
127
|
encryption_key: key,
|
124
128
|
encrypted_fields: { 'FooJob' => { 1 => true } },
|
125
129
|
serialization_method: SidekiqFieldEncryptor::SERIALIZE_JSON
|
@@ -137,7 +141,7 @@ describe SidekiqFieldEncryptor::Server do
|
|
137
141
|
end
|
138
142
|
|
139
143
|
it 'allows compat serialization' do
|
140
|
-
r =
|
144
|
+
r = described_class.new(
|
141
145
|
encryption_key: key,
|
142
146
|
encrypted_fields: { 'FooJob' => { 1 => true } },
|
143
147
|
serialization_method: SidekiqFieldEncryptor::SERIALIZE_JSON,
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-field-encryptor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Pettersson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: encryptor
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,21 +53,21 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '3.12'
|
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: '
|
68
|
+
version: '3.12'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec
|
70
|
+
name: rubocop-rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -87,13 +87,18 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
+
- ".github/CODEOWNERS"
|
91
|
+
- ".github/workflows/test.yml"
|
90
92
|
- ".gitignore"
|
91
93
|
- ".rspec"
|
92
|
-
- ".
|
94
|
+
- ".rubocop-https---raw-githubusercontent-com-aptible-dryer-lint-main--rubocop-base-yml"
|
95
|
+
- ".rubocop.yml"
|
96
|
+
- ".rubocop_ignore.yml"
|
93
97
|
- Gemfile
|
94
98
|
- LICENSE.md
|
95
99
|
- README.md
|
96
100
|
- Rakefile
|
101
|
+
- SECURITY.md
|
97
102
|
- lib/sidekiq-field-encryptor.rb
|
98
103
|
- lib/sidekiq-field-encryptor/encryptor.rb
|
99
104
|
- lib/sidekiq-field-encryptor/version.rb
|
@@ -103,8 +108,9 @@ files:
|
|
103
108
|
homepage: https://github.com/aptible/sidekiq-field-encryptor
|
104
109
|
licenses:
|
105
110
|
- MIT
|
106
|
-
metadata:
|
107
|
-
|
111
|
+
metadata:
|
112
|
+
rubygems_mfa_required: 'true'
|
113
|
+
post_install_message:
|
108
114
|
rdoc_options: []
|
109
115
|
require_paths:
|
110
116
|
- lib
|
@@ -119,11 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
125
|
- !ruby/object:Gem::Version
|
120
126
|
version: '0'
|
121
127
|
requirements: []
|
122
|
-
|
123
|
-
|
124
|
-
signing_key:
|
128
|
+
rubygems_version: 3.5.3
|
129
|
+
signing_key:
|
125
130
|
specification_version: 4
|
126
131
|
summary: Selectively encrypt fields sent into Sidekiq
|
127
|
-
test_files:
|
128
|
-
- spec/sidekiq-field-encryptor/encryptor_spec.rb
|
129
|
-
- spec/spec_helper.rb
|
132
|
+
test_files: []
|
data/.travis.yml
DELETED