diff --git a/.rubocop.yml b/.rubocop.yml index 0c2bb47..cc22ec8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -15,3 +15,7 @@ Style/SignalException: Style/SafeNavigation: Enabled: false + +Style/FileName: + Exclude: + - gemfiles/Gemfile.*.rb diff --git a/lib/sensitive_data_filter/middleware.rb b/lib/sensitive_data_filter/middleware.rb index d39348d..340285a 100644 --- a/lib/sensitive_data_filter/middleware.rb +++ b/lib/sensitive_data_filter/middleware.rb @@ -6,7 +6,6 @@ module Middleware require 'sensitive_data_filter/middleware/env_parser' require 'sensitive_data_filter/middleware/parameter_scanner' -require 'sensitive_data_filter/middleware/parameter_masker' require 'sensitive_data_filter/middleware/occurrence' require 'sensitive_data_filter/middleware/env_filter' require 'sensitive_data_filter/middleware/filter' diff --git a/lib/sensitive_data_filter/middleware/env_filter.rb b/lib/sensitive_data_filter/middleware/env_filter.rb index 9e3867f..cf10953 100644 --- a/lib/sensitive_data_filter/middleware/env_filter.rb +++ b/lib/sensitive_data_filter/middleware/env_filter.rb @@ -4,11 +4,14 @@ module SensitiveDataFilter module Middleware class EnvFilter + attr_reader :occurrence + def initialize(env) - @env = env - @original_env_parser = EnvParser.new env + @original_env_parser = EnvParser.new(env) @filtered_env_parser = @original_env_parser.copy - filter! + @scanner = ParameterScanner.new(@original_env_parser) + @filtered_env_parser.mask! if @scanner.sensitive_data? + @occurrence = build_occurrence end def filtered_env @@ -16,23 +19,14 @@ def filtered_env end def occurrence? - occurrence.present? - end - - def occurrence - return nil unless scanner.sensitive_data? - @occurrence ||= Occurrence.new(@original_env_parser, @filtered_env_parser, scanner.matches) + @occurrence.present? end private - def filter! - return unless scanner.sensitive_data? - ParameterMasker.new(@filtered_env_parser).mask! - end - - def scanner - @scanner ||= ParameterScanner.new @original_env_parser + def build_occurrence + return nil unless @scanner.sensitive_data? + Occurrence.new(@original_env_parser, @filtered_env_parser, @scanner.matches) end end end diff --git a/lib/sensitive_data_filter/middleware/env_parser.rb b/lib/sensitive_data_filter/middleware/env_parser.rb index d6bf770..f4266e0 100644 --- a/lib/sensitive_data_filter/middleware/env_parser.rb +++ b/lib/sensitive_data_filter/middleware/env_parser.rb @@ -8,37 +8,37 @@ class EnvParser def initialize(env) @env = env + @request = Rack::Request.new(@env) end def query_params - Rack::Utils.parse_query request.query_string + Rack::Utils.parse_query(@request.query_string) end def body_params - body = request.body.read - request.body.rewind + body = @request.body.read + @request.body.rewind Rack::Utils.parse_query(body) end def query_params=(new_params) - @env['QUERY_STRING'] = Rack::Utils.build_query new_params + @env['QUERY_STRING'] = Rack::Utils.build_query(new_params) end def body_params=(new_params) @env['rack.input'] = StringIO.new Rack::Utils.build_query(new_params) end - def_delegators :request, :ip, :request_method, :url, :params, :session - def copy self.class.new(@env.clone) end - private - - def request - @request ||= Rack::Request.new @env + def mask! + self.query_params = SensitiveDataFilter::Mask.mask_hash(query_params) + self.body_params = SensitiveDataFilter::Mask.mask_hash(body_params) end + + def_delegators :@request, :ip, :request_method, :url, :params, :session end end end diff --git a/lib/sensitive_data_filter/middleware/parameter_masker.rb b/lib/sensitive_data_filter/middleware/parameter_masker.rb deleted file mode 100644 index 7910639..0000000 --- a/lib/sensitive_data_filter/middleware/parameter_masker.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -module SensitiveDataFilter - module Middleware - class ParameterMasker - def initialize(env_parser) - @env_parser = env_parser - end - - def mask! - @env_parser.query_params = SensitiveDataFilter::Mask.mask_hash @env_parser.query_params - @env_parser.body_params = SensitiveDataFilter::Mask.mask_hash @env_parser.body_params - end - end - end -end diff --git a/lib/sensitive_data_filter/middleware/parameter_scanner.rb b/lib/sensitive_data_filter/middleware/parameter_scanner.rb index 683d8db..4f99c7d 100644 --- a/lib/sensitive_data_filter/middleware/parameter_scanner.rb +++ b/lib/sensitive_data_filter/middleware/parameter_scanner.rb @@ -5,22 +5,17 @@ module SensitiveDataFilter module Middleware class ParameterScanner def initialize(env_parser) - @env_parser = env_parser - @original_params = @env_parser.query_params.values + @env_parser.body_params.values + @env_parser = env_parser + @params = @env_parser.query_params.values + @env_parser.body_params.values + @scans = @params.map { |value| SensitiveDataFilter::Scan.new(value) } end def matches - scans.map(&:matches).inject(:collate) + @scans.map(&:matches).inject(:collate) end def sensitive_data? - scans.any?(&:matches?) - end - - private - - def scans - @scans ||= @original_params.map { |value| SensitiveDataFilter::Scan.new(value) } + @scans.any?(&:matches?) end end end diff --git a/spec/sensitive_data/middleware/env_filter_spec.rb b/spec/sensitive_data/middleware/env_filter_spec.rb index e7b56a9..5d82ef1 100644 --- a/spec/sensitive_data/middleware/env_filter_spec.rb +++ b/spec/sensitive_data/middleware/env_filter_spec.rb @@ -28,13 +28,11 @@ allow(env_parser_class).to receive(:new).with(env).and_return env_parser allow(env_parser).to receive(:copy).and_return env_parser_copy + allow(env_parser_copy).to receive(:mask!) + stub_const 'SensitiveDataFilter::Middleware::ParameterScanner', parameter_scanner_class allow(parameter_scanner_class).to receive(:new).with(env_parser).and_return parameter_scanner - stub_const 'SensitiveDataFilter::Middleware::ParameterMasker', parameter_masker_class - allow(parameter_masker_class).to receive(:new).with(env_parser_copy).and_return parameter_masker - allow(parameter_masker).to receive(:mask!) - stub_const 'SensitiveDataFilter::Middleware::Occurrence', occurrence_class allow(occurrence_class) .to receive(:new).with(env_parser, env_parser_copy, scan_matches).and_return occurrence @@ -44,17 +42,15 @@ context 'when sensitive data is detected' do let(:sensitive_data?) { true } - specify { expect(parameter_masker_class).to have_received(:new).with env_parser_copy } - specify { expect(parameter_masker).to have_received :mask! } + specify { expect(env_parser_copy).to have_received :mask! } specify { expect(env_filter.occurrence?).to be true } specify { expect(env_filter.occurrence).to eq occurrence } specify { expect(env_filter.filtered_env).to eq filtered_env } end - context 'when sensitive data is detected' do + context 'when sensitive data is not detected' do let(:sensitive_data?) { false } - specify { expect(parameter_masker_class).not_to have_received(:new) } - specify { expect(parameter_masker).not_to have_received :mask! } + specify { expect(env_parser_copy).not_to have_received :mask! } specify { expect(env_filter.occurrence?).to be false } specify { expect(env_filter.occurrence).to be_nil } specify { expect(env_filter.filtered_env).to eq filtered_env } diff --git a/spec/sensitive_data/middleware/env_parser_spec.rb b/spec/sensitive_data/middleware/env_parser_spec.rb index 9fad4db..97e4eb1 100644 --- a/spec/sensitive_data/middleware/env_parser_spec.rb +++ b/spec/sensitive_data/middleware/env_parser_spec.rb @@ -57,7 +57,7 @@ let(:input) { nil } # :ip, :request_method, :url, :params - context '#ip' do + describe '#ip' do let(:origin_ip) { '127.0.0.1' } before do env['REMOTE_ADDR'] = origin_ip @@ -65,31 +65,31 @@ specify { expect(env_parser.ip).to eq origin_ip } end - context '#request_method' do + describe '#request_method' do specify { expect(env_parser.request_method).to eq method } end - context '#url' do + describe '#url' do specify { expect(env_parser.url).to eq uri } end - context '#params' do + describe '#params' do specify { expect(env_parser.params).to eq 'id' => '42' } end - context '#session' do + describe '#session' do before do env['rack.session'] = { 'session_id' => '01ab02cd' } end specify { expect(env_parser.session).to eq 'session_id' => '01ab02cd' } end - context '#copy' do - let(:copy) { env_parser.copy } + describe '#copy' do + let(:masked_env_parser) { env_parser.copy } before do - copy.query_params = { id: 2 } - copy.body_params = { test: 2 } + masked_env_parser.query_params = { id: 2 } + masked_env_parser.body_params = { test: 2 } env_parser.query_params = { id: 1 } env_parser.body_params = { test: 1 } @@ -98,7 +98,40 @@ specify { expect(env_parser.query_params).to eq 'id' => '1' } specify { expect(env_parser.body_params).to eq 'test' => '1' } - specify { expect(copy.query_params).to eq 'id' => '2' } - specify { expect(copy.body_params).to eq 'test' => '2' } + specify { expect(masked_env_parser.query_params).to eq 'id' => '2' } + specify { expect(masked_env_parser.body_params).to eq 'test' => '2' } + end + + describe '#mask!' do + let(:query_params) { { 'sensitive_query' => 'sensitive_data' } } + let(:body_params) { { 'sensitive_body' => 'sensitive_data' } } + + before do + env_parser.query_params = { sensitive_query: 'sensitive_data' } + env_parser.body_params = { sensitive_body: 'sensitive_data' } + end + + context 'before masking' do + specify { expect(env_parser.query_params).to eq 'sensitive_query' => 'sensitive_data' } + specify { expect(env_parser.body_params).to eq 'sensitive_body' => 'sensitive_data' } + end + + context 'after masking' do + let(:mask) { double } + let(:filtered_query_params) { { 'sensitive_query' => '[FILTERED]' } } + let(:filtered_body_params) { { 'sensitive_body' => '[FILTERED]' } } + + before do + stub_const 'SensitiveDataFilter::Mask', mask + allow(mask).to receive(:mask_hash).with(query_params).and_return filtered_query_params + allow(mask).to receive(:mask_hash).with(body_params).and_return filtered_body_params + env_parser.mask! + end + + specify { expect(mask).to have_received(:mask_hash).with query_params } + specify { expect(mask).to have_received(:mask_hash).with body_params } + specify { expect(env_parser.query_params).to eq filtered_query_params } + specify { expect(env_parser.body_params).to eq filtered_body_params } + end end end diff --git a/spec/sensitive_data/middleware/occurrence_spec.rb b/spec/sensitive_data/middleware/occurrence_spec.rb index 09ba99e..1347235 100644 --- a/spec/sensitive_data/middleware/occurrence_spec.rb +++ b/spec/sensitive_data/middleware/occurrence_spec.rb @@ -70,7 +70,7 @@ "Url: https://test.example.com.au/test\n"\ "Filtered Params: {:credit_cards=>\"[FILTERED] and [FILTERED]\"}\n"\ "Session: {\"session_id\"=>\"01ab02cd\"}\n"\ - "Matches Count: {\"CreditCard\"=>2}" + 'Matches Count: {"CreditCard"=>2}' } specify { expect(occurrence.to_h).to eq expected_to_h } diff --git a/spec/sensitive_data/middleware/parameter_masker_spec.rb b/spec/sensitive_data/middleware/parameter_masker_spec.rb deleted file mode 100644 index cc3504d..0000000 --- a/spec/sensitive_data/middleware/parameter_masker_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true -# rubocop:disable Style/BlockDelimiters -require 'spec_helper' - -require 'sensitive_data_filter/middleware/parameter_masker' - -describe SensitiveDataFilter::Middleware::ParameterMasker do - let(:query_params) { { id: 42 } } - let(:body_params) { { credit_card: '4111 1111 1111 1111' } } - let(:env_parser) { double query_params: query_params, body_params: body_params } - subject(:parameter_masker) { SensitiveDataFilter::Middleware::ParameterMasker.new env_parser } - - describe '#mask!' do - let(:mask) { double } - let(:filtered_body_params) { { credit_card: '[FILTERED]' } } - - before do - stub_const 'SensitiveDataFilter::Mask', mask - allow(mask).to receive(:mask_hash).with(query_params).and_return query_params - allow(mask).to receive(:mask_hash).with(body_params).and_return filtered_body_params - - allow(env_parser).to receive(:query_params=) - allow(env_parser).to receive(:body_params=) - - parameter_masker.mask! - end - - specify { expect(env_parser).to have_received(:query_params=).with query_params } - specify { expect(env_parser).to have_received(:body_params=).with filtered_body_params } - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 37575a3..870d543 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,4 +2,3 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'support/coverage_loader' -require 'sensitive_data_filter' diff --git a/spec/support/coverage_loader.rb b/spec/support/coverage_loader.rb index 4baff4e..455914b 100644 --- a/spec/support/coverage_loader.rb +++ b/spec/support/coverage_loader.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'simplecov-rcov' require 'coveralls' require 'coverage/kit'