Skip to content

Commit 989c44d

Browse files
authored
Merge pull request #11 from PayU/enhancements
feat: add case insensitive configuration support
2 parents b8346da + b7125a3 commit 989c44d

File tree

12 files changed

+132
-103
lines changed

12 files changed

+132
-103
lines changed

.circleci/config.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,9 @@ orbs:
33
ruby: circleci/ruby@0.1.2
44

55
executors:
6-
v2-6-3:
7-
docker:
8-
- image: circleci/ruby:2.6.3-stretch-node
96
v2-5-0:
107
docker:
11-
- image: circleci/ruby:2.5.0-stretch-node
12-
v2-3-8:
13-
docker:
14-
- image: circleci/ruby:2.3.8-stretch-node
8+
- image: circleci/ruby:2.5.0
159

1610
jobs:
1711
tests:
@@ -21,13 +15,15 @@ jobs:
2115
executor: << parameters.ruby-version >>
2216
steps:
2317
- checkout
24-
- run: gem update bundler
18+
- run: gem install bundler
19+
- run: bundle install
20+
- run: ruby -r ./test/*.rb
2521

2622
workflows:
2723
tests:
2824
jobs:
2925
- tests:
3026
matrix:
3127
parameters:
32-
ruby-version: [v2-6-3, v2-5-0, v2-3-8]
28+
ruby-version: [v2-5-0]
3329

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
.bundle/
22
vendor/
33
*.gem
4-
.idea/
4+
.idea/
5+
Gemfile.lock
6+
Rakefile

.travis.yml

Lines changed: 0 additions & 14 deletions
This file was deleted.

Gemfile.lock

Lines changed: 0 additions & 55 deletions
This file was deleted.

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Fluentd filter plugin to mask sensitive or privacy records with `*******` in pla
88
## Requirements
99
| fluent-plugin-masking | fluentd | ruby |
1010
| --------------------- | ---------- | ------ |
11-
| 1.0.x | >= v0.14.0 | >= 2.1 |
11+
| 1.2.x | >= v0.14.0 | >= 2.5 |
1212

1313

1414
## Installation
@@ -35,10 +35,9 @@ Example fields-to-mask-file:
3535
```
3636
name
3737
email
38-
phone
38+
phone/i # the '/i' suffix will make sure phone field will be case insensitive
3939
```
4040

41-
4241
## Quick Guide
4342

4443
### Configuration:
@@ -98,3 +97,11 @@ echo '{ :body => "{\"first_name\":\"mickey\", \"type\":\"puggle\", \"last_name\"
9897
```
9998
2019-12-01 14:25:53.385681000 +0300 maskme: {"message":"{ :body => \"{\\\"first_name\\\":\\\"mickey\\\", \\\"type\\\":\\\"puggle\\\", \\\"last_name\\\":\\\"the-dog\\\", \\\"password\\\":\\\"*******\\\"}\"}"}
10099
```
100+
101+
102+
### Run Unit Tests
103+
```
104+
gem install bundler
105+
bundle install
106+
ruby -r ./test/*.rb
107+
```

Rakefile

Lines changed: 0 additions & 9 deletions
This file was deleted.

fluent-plugin-masking.gemspec

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ Gem::Specification.new do |spec|
1818
spec.require_paths = ["lib"]
1919
spec.license = "Apache-2.0"
2020

21-
spec.required_ruby_version = '>= 2.1'
21+
spec.required_ruby_version = '>= 2.5.0'
2222

2323
spec.add_runtime_dependency "fluentd", ">= 0.14.0"
24-
spec.add_development_dependency "bundler", "1.17.3"
25-
spec.add_development_dependency "rake", "~> 12.0"
2624
spec.add_development_dependency "test-unit", ">= 3.1.0"
2725
spec.add_development_dependency "test-unit-rr"
2826
end

lib/fluent/plugin/filter_masking.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,27 @@ def configure(conf)
7373

7474
File.open(fieldsToMaskFilePath, "r") do |f|
7575
f.each_line do |line|
76-
7776
value = line.to_s # make sure it's string
7877
value = value.gsub(/\s+/, "") # remove spaces
7978
value = value.gsub('\n', '') # remove line breakers
8079

80+
if value.end_with? "/i"
81+
# case insensitive
82+
value = value.delete_suffix('/i')
83+
hashObjectRegex = Regexp.new(/(?::#{value}=>")(.*?)(?:")/mi)
84+
innerJSONStringRegex = Regexp.new(/(\\+)"#{value}\\+"\s*:\s*(\\+|\{).+?((?=(})|,( *|)(\s|\\+)\"(}*))|(?=}"$)|("}(?!\"|\\)))/mi)
85+
else
86+
# case sensitive
87+
hashObjectRegex = Regexp.new(/(?::#{value}=>")(.*?)(?:")/m)
88+
innerJSONStringRegex = Regexp.new(/(\\+)"#{value}\\+"\s*:\s*(\\+|\{).+?((?=(})|,( *|)(\s|\\+)\"(}*))|(?=}"$)|("}(?!\"|\\)))/m)
89+
end
90+
8191
@fields_to_mask.push(value)
8292

83-
hashObjectRegex = Regexp.new(/(?::#{value}=>")(.*?)(?:")/m) # mask element in hash object
8493
hashObjectRegexStringReplacement = ":#{value}=>\"#{MASK_STRING}\""
8594
@fields_to_mask_regex[hashObjectRegex] = hashObjectRegexStringReplacement
8695
@fields_to_mask_keys[hashObjectRegex] = value
8796

88-
innerJSONStringRegex = Regexp.new(/(\\+)"#{value}\\+":\\+.+?((?=(})|,( *|)(\s|\\+)\")|(?=}"$))/m) # mask element in json string using capture groups that count the level of escaping inside the json string
8997
innerJSONStringRegexStringReplacement = "\\1\"#{value}\\1\":\\1\"#{MASK_STRING}\\1\""
9098
@fields_to_mask_regex[innerJSONStringRegex] = innerJSONStringRegexStringReplacement
9199
@fields_to_mask_keys[innerJSONStringRegex] = value

lib/fluent/plugin/version.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module FilterMasking
2-
VERSION = "1.1.2"
3-
end
2+
VERSION = "1.2.0"
3+
end

test/fields-to-mask

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ first_name
33
last_name
44
street
55
number
6-
password
6+
password
7+
json_str_field

test/fields-to-mask-insensitive

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
email/i
2+
first_name
3+
last_name/i
4+
street/i
5+
number

test/test_filter_masking.rb

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# test/plugin/test_filter_your_own.rb
2-
31
require "test-unit"
42
require "fluent/test"
53
require "fluent/test/driver/filter"
@@ -25,6 +23,11 @@ def setup
2523
fieldsToMaskFilePath test/fields-to-mask
2624
]
2725

26+
# configuration for tests with case insensitive fields
27+
CONFIG_CASE_INSENSITIVE = %[
28+
fieldsToMaskFilePath test/fields-to-mask-insensitive
29+
]
30+
2831
def create_driver(conf = CONFIG)
2932
Fluent::Test::Driver::Filter.new(Fluent::Plugin::MaskingFilter).configure(conf)
3033
end
@@ -39,7 +42,7 @@ def filter(config, messages)
3942
d.filtered_records
4043
end
4144

42-
sub_test_case 'plugin will mask all fields that need masking' do
45+
sub_test_case 'plugin will mask all fields that need masking - case sensitive fields' do
4346
test 'mask field in hash object' do
4447
conf = CONFIG_NO_EXCLUDE
4548
messages = [
@@ -121,6 +124,7 @@ def filter(config, messages)
121124
filtered_records = filter(conf, messages)
122125
assert_equal(expected, filtered_records)
123126
end
127+
124128
test 'mask field in hash object with base and nested exclude' do
125129
conf = CONFIG
126130
messages = [
@@ -132,6 +136,7 @@ def filter(config, messages)
132136
filtered_records = filter(conf, messages)
133137
assert_equal(expected, filtered_records)
134138
end
139+
135140
test 'mask field in json string with exclude' do
136141
conf = CONFIG
137142
messages = [
@@ -143,5 +148,90 @@ def filter(config, messages)
143148
filtered_records = filter(conf, messages)
144149
assert_equal(expected, filtered_records)
145150
end
151+
152+
test 'mask field which is inner json string field (should mask the whole object)' do
153+
conf = CONFIG
154+
messages = [
155+
{
156+
:body => {
157+
:action_name => "some_action",
158+
:action_type => "some type",
159+
:request => {
160+
:body_str => "{\"str_field\":\"mickey\",\"json_str_field\": {\"id\":\"ed8a8378-3235-4923-b802-7700167d1870\"},\"not_mask\":\"some_value\"}"
161+
}
162+
},
163+
:timestamp => "2020-06-08T16:00:57.341Z"
164+
}
165+
]
166+
167+
expected = [
168+
{
169+
:body => {
170+
:action_name => "some_action",
171+
:action_type => "some type",
172+
:request => {
173+
:body_str => "{\"str_field\":\"mickey\",\"json_str_field\":\"*******\",\"not_mask\":\"some_value\"}"
174+
}
175+
},
176+
:timestamp => "2020-06-08T16:00:57.341Z"
177+
}
178+
]
179+
180+
filtered_records = filter(conf, messages)
181+
assert_equal(expected, filtered_records)
182+
end
146183
end
184+
185+
sub_test_case 'plugin will mask all fields that need masking - case INSENSITIVE fields' do
186+
187+
test 'mask field in hash object with camel case' do
188+
conf = CONFIG_CASE_INSENSITIVE
189+
messages = [
190+
{:not_masked_field=>"mickey-the-dog", :Email=>"mickey-the-dog@zooz.com"}
191+
]
192+
expected = [
193+
{:not_masked_field=>"mickey-the-dog", :email=>MASK_STRING}
194+
]
195+
filtered_records = filter(conf, messages)
196+
assert_equal(expected, filtered_records)
197+
end
198+
199+
test 'not mask field in hash object since case not match' do
200+
conf = CONFIG_CASE_INSENSITIVE
201+
messages = [
202+
{:not_masked_field=>"mickey-the-dog", :FIRST_NAME=>"mickey-the-dog@zooz.com"}
203+
]
204+
expected = [
205+
{:not_masked_field=>"mickey-the-dog", :FIRST_NAME=>"mickey-the-dog@zooz.com"}
206+
]
207+
filtered_records = filter(conf, messages)
208+
assert_equal(expected, filtered_records)
209+
end
210+
211+
test 'mask field in hash object with snakecase' do
212+
conf = CONFIG_CASE_INSENSITIVE
213+
messages = [
214+
{:not_masked_field=>"mickey-the-dog", :LaSt_NaMe=>"mickey-the-dog@zooz.com"}
215+
]
216+
expected = [
217+
{:not_masked_field=>"mickey-the-dog", :last_name=>MASK_STRING}
218+
]
219+
filtered_records = filter(conf, messages)
220+
assert_equal(expected, filtered_records)
221+
end
222+
223+
test 'mask case insensitive and case sensitive field in nested json escaped string' do
224+
conf = CONFIG_CASE_INSENSITIVE
225+
messages = [
226+
{ :body => "{\"firsT_naMe\":\"mickey\",\"last_name\":\"the-dog\",\"address\":\"{\\\"Street\":\\\"Austin\\\",\\\"number\":\\\"89\\\"}\", \"type\":\"puggle\"}" }
227+
]
228+
expected = [
229+
{ :body => "{\"firsT_naMe\":\"mickey\",\"last_name\":\"*******\",\"address\":\"{\\\"street\\\":\\\"*******\\\",\\\"number\\\":\\\"*******\\\"}\", \"type\":\"puggle\"}" }
230+
]
231+
filtered_records = filter(conf, messages)
232+
assert_equal(expected, filtered_records)
233+
end
234+
235+
end
236+
147237
end

0 commit comments

Comments
 (0)