Skip to content

Commit

Permalink
Merge pull request #7 from bdurand/fix-double-encryption
Browse files Browse the repository at this point in the history
Fix double encryption on job retry
  • Loading branch information
bdurand authored Apr 3, 2023
2 parents 6613b58 + c4cf19c commit 1c354b6
Show file tree
Hide file tree
Showing 18 changed files with 184 additions and 156 deletions.
59 changes: 31 additions & 28 deletions .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ on:
push:
branches:
- master
- actions-*
tags:
- v*
pull_request:
Expand All @@ -14,41 +13,45 @@ env:
BUNDLE_RETRY: 3
jobs:
specs:
name: ${{ matrix.job }} ruby-${{ matrix.ruby }} ${{ matrix.sidekiq && format('sidekiq-{0}', matrix.sidekiq) }}
name: ruby-${{ matrix.ruby }} ${{ matrix.appraisal }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: [ 2.4, 2.5, 2.6, 2.7 ]
sidekiq: [4, 5, 6]
job: [ rspec ]
exclude:
- ruby: 2.4
sidekiq: 6
include:
- ruby: 2.7
sidekiq: original
job: rspec
- ruby: 2.7
job: standardrb
- ruby: "ruby"
standardrb: true
coverage: true
- ruby: "3.1"
appraisal: "sidekiq_7"
- ruby: "3.0"
appraisal: "sidekiq_6"
- ruby: "2.7"
appraisal: "sidekiq_5"
- ruby: "2.4"
appraisal: "sidekiq_4"
steps:
- name: checkout
uses: actions/checkout@v2
- name: set up Ruby
- name: Checkout
uses: actions/checkout@v3
- name: Set up Ruby ${{ matrix.ruby }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- name: inject sidekiq ${{ matrix.sidekiq }}
if: matrix.sidekiq != 'original' && matrix.sidekiq != null
run: | # inject a specific version of sidekiq into the Gemfile
- name: Setup bundler
if: matrix.bundler != ''
run: |
gem uninstall bundler --all
gem install bundler --no-document --version ${{ matrix.bundler }}
- name: Set Appraisal bundle
if: matrix.appraisal != ''
run: |
echo "using gemfile gemfiles/${{ matrix.appraisal }}.gemfile"
bundle config set gemfile "gemfiles/${{ matrix.appraisal }}.gemfile"
- name: Install bundle
run: |
bundle update
bundle exec appraisal generate
bundle config set gemfile "gemfiles/sidekiq_${{ matrix.sidekiq }}.gemfile"
- name: install dependencies
run: bundle install
- name: specs
if: matrix.job == 'rspec'
- name: Run specs
run: bundle exec rake spec
- name: standardrb
if: matrix.job == 'standardrb'
run: bundle exec rake standard
- name: Run standardrb
if: matrix.standardrb == true
run: bundle exec standardrb
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.tm_properties
.bundle
Gemfile.lock
/gemfiles/*.lock
.yardoc
/_yardoc/
Expand Down
6 changes: 3 additions & 3 deletions .standard.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# I really just have issues with the automatic "semantic blocks"

ruby_version: 2.4

format: progress

ignore:
- '**/*':
- Standard/SemanticBlocks
- Style/RedundantBegin
- 'spec/**/*':
- Lint/UselessAssignment
2 changes: 1 addition & 1 deletion Appraisals
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

SIDEKIQ_MAJOR_RELEASES = ["6", "5", "4"].freeze
SIDEKIQ_MAJOR_RELEASES = ["7", "6", "5", "4"].freeze

SIDEKIQ_MAJOR_RELEASES.each do |version|
appraise "sidekiq_#{version}" do
Expand Down
43 changes: 31 additions & 12 deletions CHANGE_LOG.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,43 @@
# Change Log
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.1.1

### Fixed
- Client middleware will no longer encrypt already encrypted arguments when a job is retried.

## 1.1.0

* Use `to_json` if it is defined when serializing encrypted args to JSON.
* Add client middleware to the server default configuration. This ensures that arguments will be encrypted if a worker enqueues a job with encrypted arguments.
* Client middleware now reads sidekiq options from the job hash instead of from the worker class so that the list of encrypted arguments is always in sync on the job payload.
* Don't blow up if class name that is not defined is passed to client middleware.
* Added additional option to specify encrypted args with array of argument indexes.
* Deprecated setting encrypted args as hash or array of booleans.
* Client middleware is prepended while server middleware is appended.
### Added
- Use `to_json` if it is defined when serializing encrypted args to JSON.
- Add client middleware to the server default configuration. This ensures that arguments will be encrypted if a worker enqueues a job with encrypted arguments.
- Client middleware now reads sidekiq options from the job hash instead of from the worker class so that the list of encrypted arguments is always in sync on the job payload.
- Added additional option to specify encrypted args with array of argument indexes.

### Changed
- Client middleware is now prepended while server middleware is appended.

### Fixed
- Don't raise error if undefined class name is passed to client middleware as a string.

### Deprecated
- Deprecated setting encrypted args as hash or array of booleans.

## 1.0.2

* Remove overly noisy log warning when running without the secret set
### Changed
- Remove overly noisy log warning when running without the secret set

## 1.0.1

* Now works with scheduled jobs
* Scheduled jobs dispatch by class name instead of `Class`, requiring a constant lookup
### Added

### Fixed
- Added support for scheduled jobs

## 1.0.0

* Initial release
- Initial release
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ end
group :development, :test do
gem "rake"
gem "rspec", "~> 3.9"
gem "climate_control"
gem "appraisal"

# Lock standard to a particular version, esp. cause it's still 0.x.x according to Semver
gem "standard", "0.4.6"
gem "standard", "~> 1.0"
end

group :doc do
Expand Down
79 changes: 0 additions & 79 deletions Gemfile.lock

This file was deleted.

29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Sidekiq Encrypted Args

[![Continuous Integration](https://github.com/bdurand/sidekiq-encrypted_args/workflows/Continuous%20Integration/badge.svg?branch=master)](https://github.com/bdurand/sidekiq-encrypted_args/actions?query=workflow%3A%22Continuous+Integration%22)
[![Maintainability](https://api.codeclimate.com/v1/badges/70ab3782e4d5285eb173/maintainability)](https://codeclimate.com/github/bdurand/sidekiq-encrypted_args/maintainability)
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)

Support for encrypting arguments for [Sidekiq](https://github.com/mperham/sidekiq).
Expand Down Expand Up @@ -106,3 +105,31 @@ You can also safely add encryption to an existing worker. Any jobs that are alre
## Encryption

Encrypted arguments are stored using AES-256-GCM with a key derived from your secret using PBKDF2. For more info on the underlying encryption, refer to the [SecretKeys](https://github.com/bdurand/secret_keys) gem.

## Installation

Add this line to your application's Gemfile:

```ruby
gem "sidekiq-encrypted_args"
```

And then execute:
```bash
$ bundle
```

Or install it yourself as:
```bash
$ gem install sidekiq-encrypted_args
```

## Contributing

Open a pull request on GitHub.

Please use the [standardrb](https://github.com/testdouble/standard) syntax and lint your code with `standardrb --fix` before submitting.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.0
1.1.1
3 changes: 1 addition & 2 deletions gemfiles/sidekiq_4.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ end
group :development, :test do
gem "rake"
gem "rspec", "~> 3.9"
gem "climate_control"
gem "appraisal"
gem "standard", "0.4.6"
gem "standard", "~> 1.0"
end

group :doc do
Expand Down
3 changes: 1 addition & 2 deletions gemfiles/sidekiq_5.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ end
group :development, :test do
gem "rake"
gem "rspec", "~> 3.9"
gem "climate_control"
gem "appraisal"
gem "standard", "0.4.6"
gem "standard", "~> 1.0"
end

group :doc do
Expand Down
3 changes: 1 addition & 2 deletions gemfiles/sidekiq_6.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ end
group :development, :test do
gem "rake"
gem "rspec", "~> 3.9"
gem "climate_control"
gem "appraisal"
gem "standard", "0.4.6"
gem "standard", "~> 1.0"
end

group :doc do
Expand Down
20 changes: 20 additions & 0 deletions gemfiles/sidekiq_7.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "sidekiq", "~> 7.0"

group :runtime do
gemspec path: "../"
end

group :development, :test do
gem "rake"
gem "rspec", "~> 3.9"
gem "appraisal"
gem "standard", "~> 1.0"
end

group :doc do
gem "yard"
end
10 changes: 9 additions & 1 deletion lib/sidekiq/encrypted_args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def secret=(value)
@encryptors = make_encryptors(value)
end

# Add the client and server middleware to the Sidekiq
# Add the client and server middleware to the default Sidekiq
# middleware chains. If you need to ensure the order of where the middleware is
# added, you can forgo this method and add it yourself.
#
Expand Down Expand Up @@ -64,6 +64,7 @@ def configure!(secret: nil)
# @return [String]
def encrypt(data)
return nil if data.nil?

json = (data.respond_to?(:to_json) ? data.to_json : JSON.generate(data))
encrypted = encrypt_string(json)
if encrypted == json
Expand All @@ -85,6 +86,13 @@ def decrypt(encrypted_data)
JSON.parse(json)
end

# Check if a value is encrypted.
#
# @return [Boolean]
def encrypted?(value)
SecretKeys::Encryptor.encrypted?(value)
end

# Private helper method to get the encrypted args option from an options hash. The value of this option
# can be `true` or an array indicating if each positional argument should be encrypted, or a hash
# with keys for the argument position and true as the value.
Expand Down
2 changes: 1 addition & 1 deletion lib/sidekiq/encrypted_args/client_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def encrypt_job_arguments!(job, encrypted_args)
if encrypted_args
job_args = job["args"]
job_args.each_with_index do |value, position|
if encrypted_args.include?(position)
if encrypted_args.include?(position) && !EncryptedArgs.encrypted?(value)
job_args[position] = EncryptedArgs.encrypt(value)
end
end
Expand Down
Loading

0 comments on commit 1c354b6

Please sign in to comment.