active_record-pgcrypto 0.2.4 → 0.2.5

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: 6225d8f7dd8ecd182236f45d3a9d68884207891563ae550c03f0b3038e3a31d4
4
- data.tar.gz: 21543ff3b8587257c94acd367e4e40dbbbd484c2030e231eaefd03d6bf86e47a
3
+ metadata.gz: 720cc8894659947200a913bee9a2757ddb9b31f993dd5a710d0a4dba781c3f95
4
+ data.tar.gz: e4309d8fe0032d489a205158bd37768cc867aaa8adf8e0999ffbf20ee32082bf
5
5
  SHA512:
6
- metadata.gz: 5a2bcca8231ecc1ebfe00dfdb61ef55311f736de9b6752ab2a6c8e09f4fd2a70b53df4a07c80dd7dd5509f3d32c750c20e506a361a3bbfeade1bbc22362fdad9
7
- data.tar.gz: 0ac5f283a26ebc13f1c601fcafb02b13a6ae8c52d7f0366e33eac32a33a06189b396a6a99e3b4e54ec6bac13be3d1b43183388876e4bf998fdfdf1e3be4d8453
6
+ metadata.gz: 146fbaa31f74481b715ae9dec906bf5f556ad23881a5c0a7d8510cd5869500104ad4d211b0c273499f60aa9d6c9e5a12c24a7e1da1c4a6dd7c7294494b585d9d
7
+ data.tar.gz: 7e534fd989099428241b88f64822c55b75f8e6a2e7a923c03f002c4353dd76b0dfbc34be8d108f29f883911c2598af9074122d87b9002937c717003c3043f231
@@ -2,8 +2,10 @@ module ActiveRecord
2
2
  module PGCrypto
3
3
  # Subscribes to the logger and obfuscates the sensitive queries.
4
4
  module LogSubscriber
5
+ # rubocop:disable Lint/MixedRegexpCaptureTypes
5
6
  REGEXP = \
6
7
  /(\(*)(?<operation>pgp_sym_(decrypt|encrypt)_bytea)(\(+.*\)+)/im.freeze
8
+ # rubocop:enable Lint/MixedRegexpCaptureTypes
7
9
  PLACEHOLDER = '[FILTERED]'.freeze
8
10
 
9
11
  # Scrubs the log event from any sensitive SQL
@@ -11,7 +11,7 @@ module ActiveRecord
11
11
  # can return same decrypted values, we don't check it.
12
12
  #
13
13
  # @return [FalseClass] on our coder values.
14
- def changed_in_place?(*)
14
+ def changed_in_place?(*args, **kwargs)
15
15
  return false if coder == ActiveRecord::PGCrypto::SymmetricCoder
16
16
 
17
17
  super
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module PGCrypto
3
- VERSION = '0.2.4'.freeze
3
+ VERSION = '0.2.5'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'active_record/pgcrypto/log_subscriber'
3
+
4
+ RSpec.describe ActiveRecord::PGCrypto::LogSubscriber do
5
+ let(:pgcrypto_key) { FFaker::Internet.password }
6
+ let(:subscriber) { ActiveRecord::LogSubscriber.new }
7
+ let(:event_payload) do
8
+ { sql: "SELECT PGP_SYM_ENCRYPT_BYTEA('data', '#{pgcrypto_key}')" }
9
+ end
10
+ let(:event) do
11
+ ActiveSupport::Notifications::Event.new(:test, 0, 0, :id, event_payload)
12
+ end
13
+
14
+ before do
15
+ ActiveRecord::PGCrypto.enable_log_subscriber!
16
+ end
17
+
18
+ it do
19
+ subscriber.sql(event)
20
+
21
+ expect(event.payload[:sql]).not_to include(pgcrypto_key)
22
+ expect(event.payload[:sql]).to include(described_class::PLACEHOLDER)
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'active_record/pgcrypto/symmetric_coder'
3
+
4
+ RSpec.describe ActiveRecord::PGCrypto::SymmetricCoder do
5
+ let(:pgcrypto_key) { FFaker::Internet.password }
6
+ let(:text) { '€n©őđ3Đ' }
7
+ let(:numeric) { rand(1.0..5.0) }
8
+
9
+ before do
10
+ described_class.pgcrypto_key = pgcrypto_key
11
+ end
12
+
13
+ it { expect(described_class.pgcrypto_key).to eq(pgcrypto_key) }
14
+
15
+ context 'with encrypted text' do
16
+ it { expect(described_class.dump(text)).not_to eq(text) }
17
+
18
+ it { expect(described_class.dump(text)).not_to be_blank }
19
+
20
+ it do
21
+ expect(described_class.load(described_class.dump(text))).to eq(text)
22
+ end
23
+ end
24
+
25
+ context 'with encrypted numeric' do
26
+ it { expect(described_class.dump(numeric)).not_to eq(numeric.to_s) }
27
+
28
+ it { expect(described_class.dump(numeric)).not_to be_blank }
29
+
30
+ it do
31
+ expect(
32
+ described_class.load(described_class.dump(numeric))
33
+ ).to eq(numeric.to_s)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ require 'active_record'
2
+ require 'logger'
3
+
4
+ ActiveRecord::Base.logger = Logger.new($stdout)
5
+ ActiveRecord::Base.logger.level = ENV['LOG_LEVEL'] || Logger::WARN
6
+ ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
7
+
8
+ ActiveRecord::Schema.define do
9
+ enable_extension 'pgcrypto'
10
+
11
+ create_table :users, force: true do |t|
12
+ t.binary :email
13
+ end
14
+ end
15
+
16
+ # Enable PGCrypto Symmetric encryption support.
17
+ ENV['PGCRYPTO_SYM_KEY'] = SecureRandom.hex(10)
18
+ require 'active_record/pgcrypto'
19
+
20
+ class User < ActiveRecord::Base
21
+ serialize(:email, ActiveRecord::PGCrypto::SymmetricCoder)
22
+
23
+ def self.decrypted_email
24
+ ActiveRecord::PGCrypto::SymmetricCoder
25
+ .decrypted_arel_text(arel_table[:email])
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'securerandom'
3
+
4
+ RSpec.describe User do
5
+ let(:good_user) { User.create!(email: FFaker::Internet.email) }
6
+ let(:bad_user) { User.create!(email: FFaker::Internet.email) }
7
+
8
+ it 'finds the searched user' do
9
+ expect(good_user.email).not_to eq(bad_user.email)
10
+
11
+ filtered = User.where(
12
+ User.decrypted_email.matches("#{good_user.email.first(4)}%")
13
+ )
14
+
15
+ expect(filtered.count).to eq(1)
16
+ expect(filtered.first).to eq(good_user)
17
+ end
18
+
19
+ it 'stays unchanged' do
20
+ good_user.reload
21
+ expect(good_user).not_to be_changed
22
+
23
+ good_user.email = good_user.reload.email
24
+ expect(good_user).not_to be_changed
25
+
26
+ good_user.email = FFaker::Internet.email
27
+ expect(good_user).to be_changed
28
+
29
+ good_user.reload
30
+ expect(good_user).not_to be_changed
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'bundler/setup'
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start do
5
+ add_group 'Lib', 'lib'
6
+ add_group 'Tests', 'spec'
7
+ end
8
+ SimpleCov.minimum_coverage 90
9
+
10
+ require 'dummy'
11
+ require 'ffaker'
12
+ require 'rspec'
13
+
14
+ RSpec.configure do |config|
15
+ config.mock_with :rspec
16
+ config.filter_run_when_matching :focus
17
+ config.disable_monkey_patching!
18
+
19
+ config.expect_with :rspec do |c|
20
+ c.syntax = :expect
21
+ end
22
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record-pgcrypto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stas SUȘCOV
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-04 00:00:00.000000000 Z
11
+ date: 2021-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -157,24 +157,18 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
- - ".github/ISSUE_TEMPLATE.md"
161
- - ".github/PULL_REQUEST_TEMPLATE.md"
162
- - ".github/workflows/ci.yml"
163
- - ".gitignore"
164
- - ".rubocop.yml"
165
- - ".yardstick.yml"
166
- - CODE_OF_CONDUCT.md
167
- - Dockerfile
168
- - Gemfile
169
160
  - LICENSE.txt
170
161
  - README.md
171
- - Rakefile
172
- - active_record-pgcrypto.gemspec
173
162
  - lib/active_record/pgcrypto.rb
174
163
  - lib/active_record/pgcrypto/log_subscriber.rb
175
164
  - lib/active_record/pgcrypto/patches.rb
176
165
  - lib/active_record/pgcrypto/symmetric_coder.rb
177
166
  - lib/active_record/pgcrypto/version.rb
167
+ - spec/active_record/pgcrypto/log_subscriber_spec.rb
168
+ - spec/active_record/pgcrypto/symmetric_coder_spec.rb
169
+ - spec/dummy.rb
170
+ - spec/integration/model_spec.rb
171
+ - spec/spec_helper.rb
178
172
  homepage: https://github.com/stas/active_record-pgcrypto
179
173
  licenses:
180
174
  - MIT
@@ -194,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
188
  - !ruby/object:Gem::Version
195
189
  version: '0'
196
190
  requirements: []
197
- rubygems_version: 3.0.1
191
+ rubygems_version: 3.2.3
198
192
  signing_key:
199
193
  specification_version: 4
200
194
  summary: PGCrypto for ActiveRecord
@@ -1,16 +0,0 @@
1
- ## Expected Behavior
2
-
3
-
4
- ## Actual Behavior
5
-
6
-
7
- ## Steps to Reproduce the Problem
8
-
9
- 1.
10
- 2.
11
- 3.
12
-
13
- ## Specifications
14
-
15
- - Version:
16
- - Ruby version:
@@ -1,17 +0,0 @@
1
- ## What is the current behavior?
2
-
3
- <!-- Please describe the current behavior that you are modifying, or link to a
4
- relevant issue. -->
5
-
6
- ## What is the new behavior?
7
-
8
- <!-- Please describe the behavior or changes that are being added here. -->
9
-
10
- ## Checklist
11
-
12
- Please make sure the following requirements are complete:
13
-
14
- - [ ] Tests for the changes have been added (for bug fixes / features)
15
- - [ ] Docs have been reviewed and added / updated if needed (for bug fixes /
16
- features)
17
- - [ ] All automated checks pass (CI/CD)
@@ -1,47 +0,0 @@
1
- name: CI
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- ruby_rails_matrix:
7
- runs-on: ubuntu-18.04
8
-
9
- services:
10
- postgres:
11
- image: postgres:11.6
12
- env:
13
- POSTGRES_USER: postgres
14
- POSTGRES_PASSWORD: postgres
15
- POSTGRES_DB: postgres
16
- ports:
17
- - 5432/tcp
18
- options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
19
-
20
- strategy:
21
- matrix:
22
- ruby: [2.4, 2.7]
23
- rails: [4, 5, 6]
24
- exclude:
25
- - ruby: 2.4
26
- rails: 6
27
- - ruby: 2.7
28
- rails: 4
29
-
30
- steps:
31
- - uses: actions/checkout@master
32
-
33
- - name: Sets up the environment
34
- uses: actions/setup-ruby@v1
35
- with:
36
- ruby-version: ${{ matrix.ruby }}
37
-
38
- - name: Runs code QA and tests
39
- env:
40
- RAILS_VERSION: ~> ${{ matrix.rails }}
41
- DATABASE_URL: postgresql://postgres:postgres@localhost:${{ job.services.postgres.ports[5432] }}/postgres?pool=5
42
- run: |
43
- rm -rf Gemfile.lock
44
- gem uninstall bundler -a --force
45
- gem install bundler -v '~> 1'
46
- bundle
47
- rake
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
12
- Gemfile.lock
@@ -1,50 +0,0 @@
1
- require:
2
- - rubocop-performance
3
- - rubocop-rspec
4
-
5
- RSpec:
6
- Enabled: true
7
-
8
- RSpec/MultipleExpectations:
9
- Enabled: false
10
-
11
- Performance:
12
- Enabled: true
13
-
14
- Bundler:
15
- Enabled: true
16
-
17
- Gemspec:
18
- Enabled: true
19
-
20
- Style/StringLiterals:
21
- Enabled: true
22
- EnforcedStyle: single_quotes
23
-
24
- Style/FrozenStringLiteralComment:
25
- Enabled: false
26
-
27
- Metrics/LineLength:
28
- Max: 80
29
-
30
- Metrics/BlockLength:
31
- Exclude:
32
- - 'spec/**/*_spec.rb'
33
- - '**/*.gemspec'
34
-
35
- Layout/IndentationConsistency:
36
- EnforcedStyle: normal
37
-
38
- Style/BlockDelimiters:
39
- Enabled: true
40
-
41
- RSpec/FilePath:
42
- Exclude:
43
- - 'spec/**/*_spec.rb'
44
-
45
- RSpec/DescribedClass:
46
- Exclude:
47
- - 'spec/integration/*_spec.rb'
48
-
49
- RSpec/ExampleLength:
50
- Enabled: false
@@ -1,29 +0,0 @@
1
- ---
2
- path: ['lib/**/*.rb']
3
- threshold: 100
4
- rules:
5
- ApiTag::Presence:
6
- enabled: false
7
- ApiTag::Inclusion:
8
- enabled: false
9
- ApiTag::ProtectedMethod:
10
- enabled: false
11
- ApiTag::PrivateMethod:
12
- enabled: false
13
- ExampleTag:
14
- enabled: false
15
- ReturnTag:
16
- enabled: true
17
- exclude: []
18
- Summary::Presence:
19
- enabled: true
20
- exclude: []
21
- Summary::Length:
22
- enabled: true
23
- exclude: []
24
- Summary::Delimiter:
25
- enabled: true
26
- exclude: []
27
- Summary::SingleLine:
28
- enabled: true
29
- exclude: []
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at stas@nerd.ro. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
data/Dockerfile DELETED
@@ -1,17 +0,0 @@
1
- FROM postgres:11.6-alpine
2
-
3
- RUN apk add --no-cache git build-base ruby ruby-full ruby-dev
4
-
5
- RUN gem install -q --no-ri --no-rdoc -v '~> 1' bundler
6
-
7
- RUN mkdir /gem
8
- WORKDIR /gem
9
-
10
- COPY ./ ./
11
- RUN bundle install --no-cache
12
-
13
- ENV DATABASE_URL=postgresql://postgres@localhost/postgres?pool=5
14
-
15
- ENTRYPOINT []
16
-
17
- CMD ["sh", "-c", "(nohup /docker-entrypoint.sh postgres > /dev/null &) && sleep 3 && bundle install && bundle exec rake"]
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
data/Rakefile DELETED
@@ -1,23 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
- require 'rubocop/rake_task'
4
- require 'yaml'
5
- require 'yardstick/rake/verify'
6
-
7
- desc('Documentation stats and measurements')
8
- task('qa:docs') do
9
- yaml = YAML.load_file('.yardstick.yml')
10
- config = Yardstick::Config.coerce(yaml)
11
- measure = Yardstick.measure(config)
12
- measure.puts
13
- coverage = Yardstick.round_percentage(measure.coverage * 100)
14
- exit(1) if coverage < config.threshold
15
- end
16
-
17
- RuboCop::RakeTask.new('qa:code')
18
-
19
- desc('Run QA tasks')
20
- task(qa: ['qa:docs', 'qa:code'])
21
-
22
- RSpec::Core::RakeTask.new(spec: :qa)
23
- task(default: :spec)
@@ -1,35 +0,0 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'active_record/pgcrypto/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'active_record-pgcrypto'
7
- spec.version = ActiveRecord::PGCrypto::VERSION
8
- spec.authors = ['Stas SUȘCOV']
9
- spec.email = ['stas@nerd.ro']
10
-
11
- spec.summary = 'PGCrypto for ActiveRecord'
12
- spec.description = 'PostgreSQL PGCrypto support for ActiveRecord models.'
13
- spec.homepage = 'https://github.com/stas/active_record-pgcrypto'
14
- spec.license = 'MIT'
15
-
16
- # Specify which files should be added to the gem when it is released.
17
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
19
- end
20
- spec.require_paths = ['lib']
21
-
22
- spec.add_dependency 'activerecord', (ENV['RAILS_VERSION'] || '>= 3.2')
23
-
24
- pg_version = '< 1' if ENV['RAILS_VERSION'].to_s.split(' ').last.to_i == 4
25
-
26
- spec.add_development_dependency 'bundler'
27
- spec.add_development_dependency 'ffaker'
28
- spec.add_development_dependency 'pg', pg_version
29
- spec.add_development_dependency 'rake'
30
- spec.add_development_dependency 'rspec'
31
- spec.add_development_dependency 'rubocop-performance'
32
- spec.add_development_dependency 'rubocop-rspec'
33
- spec.add_development_dependency 'simplecov'
34
- spec.add_development_dependency 'yardstick'
35
- end