Skip to content

Commit 1f31636

Browse files
authored
Merge pull request #311 from logzio/add-base64-decode-processor
2 parents 3dbe420 + 850c2bb commit 1f31636

File tree

3 files changed

+181
-2
lines changed

3 files changed

+181
-2
lines changed

.github/workflows/git-secrets.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
# This workflow contains a single job called "main"
1010
git-secrets:
1111
# The type of runner that the job will run on
12-
runs-on: ubuntu-18.04
12+
runs-on: macos-latest
1313

1414
# Steps represent a sequence of tasks that will be executed as part of the job
1515
steps:
@@ -22,7 +22,7 @@ jobs:
2222
python-version: 3.8
2323
- name: Installing dependencies
2424
run:
25-
sudo apt-get install git less openssh-server
25+
brew install git less openssh
2626
- name: Installing scanning tool
2727
run: |
2828
brew install git-secrets
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package io.logz.sawmill.processors;
2+
3+
import io.logz.sawmill.Doc;
4+
import io.logz.sawmill.ProcessResult;
5+
import io.logz.sawmill.Processor;
6+
import io.logz.sawmill.annotations.ProcessorProvider;
7+
import io.logz.sawmill.exceptions.ProcessorConfigurationException;
8+
import io.logz.sawmill.utilities.JsonUtils;
9+
10+
import java.util.Base64;
11+
import java.util.Map;
12+
13+
import static java.util.Objects.requireNonNull;
14+
15+
@ProcessorProvider(type = "base64Decode", factory = Base64DecodeProcessor.Factory.class)
16+
public class Base64DecodeProcessor implements Processor {
17+
18+
private final String sourceField;
19+
private final String targetField;
20+
21+
public Base64DecodeProcessor(String sourceField, String targetField) {
22+
this.sourceField = requireNonNull(sourceField);
23+
this.targetField = requireNonNull(targetField);
24+
}
25+
26+
@Override
27+
public ProcessResult process(Doc doc) {
28+
if(!doc.hasField(sourceField, String.class))
29+
return ProcessResult.failure("field is missing from doc");
30+
31+
String value = doc.getField(sourceField);
32+
String decodedValue = new String(Base64.getDecoder().decode(value));
33+
doc.addField(targetField, decodedValue);
34+
return ProcessResult.success();
35+
}
36+
37+
public static class Factory implements Processor.Factory {
38+
public Factory() {}
39+
40+
@Override
41+
public Base64DecodeProcessor create(Map<String,Object> config) {
42+
Base64DecodeProcessor.Configuration configuration =
43+
JsonUtils.fromJsonMap(Base64DecodeProcessor.Configuration.class, config);
44+
validateConfiguration(configuration);
45+
return new Base64DecodeProcessor(configuration.getSourceField(), configuration.getTargetField());
46+
}
47+
48+
private void validateConfiguration(Configuration configuration) {
49+
if(configuration.getSourceField() == null || configuration.getSourceField().isEmpty()
50+
|| configuration.getTargetField() == null || configuration.getTargetField().isEmpty())
51+
throw new ProcessorConfigurationException("sourceField, targetField can not be null or empty");
52+
}
53+
}
54+
55+
public static class Configuration implements Processor.Configuration {
56+
private String sourceField;
57+
private String targetField;
58+
59+
public Configuration() {}
60+
public Configuration(String sourceField, String targetField) {
61+
this.sourceField = sourceField;
62+
this.targetField = targetField;
63+
}
64+
65+
public String getSourceField() { return sourceField; }
66+
public String getTargetField() { return targetField; }
67+
}
68+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package io.logz.sawmill.processors;
2+
3+
import io.logz.sawmill.Doc;
4+
import io.logz.sawmill.ProcessResult;
5+
import io.logz.sawmill.Processor;
6+
import io.logz.sawmill.exceptions.ProcessorConfigurationException;
7+
import org.junit.Test;
8+
9+
import java.util.Base64;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
import java.util.stream.Stream;
13+
14+
import static io.logz.sawmill.utils.FactoryUtils.createProcessor;
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
17+
18+
public class Base64DecodeProcessorTest {
19+
20+
@Test
21+
public void testNullOrEmptyConfigurationFieldsShouldFailCreator() {
22+
Stream.of(
23+
createConfig(null, "target"),
24+
createConfig("", "target"),
25+
createConfig("source", null),
26+
createConfig("source", ""))
27+
.forEach((config) -> assertThatThrownBy(() -> createProcessor(Base64DecodeProcessor.class, config))
28+
.isInstanceOf(ProcessorConfigurationException.class)
29+
.hasMessageContaining("sourceField, targetField can not be null or empty"));
30+
}
31+
32+
@Test
33+
public void testDecode() {
34+
Map<String, Object> config = new HashMap<>();
35+
config.put("sourceField", "message");
36+
config.put("targetField", "message_decoded");
37+
38+
Map<String, Object> map = new HashMap<>();
39+
String encodedMessage = Base64.getEncoder().encodeToString("testEmptyFieldsShouldFail".getBytes());
40+
map.put("message", encodedMessage);
41+
Doc doc = new Doc(map);
42+
43+
ProcessResult result;
44+
Processor processor = createProcessor(Base64DecodeProcessor.class, config);
45+
try {
46+
result = processor.process(doc);
47+
} catch (InterruptedException e) { throw new RuntimeException(e); }
48+
49+
assertThat(result != null && result.isSucceeded()).isTrue();
50+
assertThat(doc.getField(config.get("sourceField").toString()).toString()).isEqualTo(encodedMessage);
51+
assertThat(doc.getField(config.get("targetField").toString()).toString())
52+
.isEqualTo("testEmptyFieldsShouldFail");
53+
}
54+
55+
@Test
56+
public void testNonStringFieldShouldFail() {
57+
Map<String, Object> config = new HashMap<>();
58+
config.put("sourceField", "numberField");
59+
config.put("targetField", "noop");
60+
61+
Map<String, Object> map = new HashMap<>();
62+
map.put("message", "testSingleNonStringFieldShouldFail");
63+
map.put("numberField", 123);
64+
Doc doc = new Doc(map);
65+
66+
Processor processor = createProcessor(Base64DecodeProcessor.class, config);
67+
68+
ProcessResult result;
69+
70+
try {
71+
result = processor.process(doc);
72+
} catch (InterruptedException e) { throw new RuntimeException(e); }
73+
assertThat(result != null && !result.isSucceeded()).isTrue();
74+
assertThat(result.getError().isPresent()).isTrue();
75+
assertThat(result.getError().get().getMessage())
76+
.isEqualTo("field is missing from doc");
77+
assertThat(doc.hasField(config.get("targetField").toString())).isFalse();
78+
assertThat(doc.getField("message").toString()).isEqualTo(map.get("message").toString());
79+
}
80+
81+
@Test
82+
public void testMissingFieldShouldFail() {
83+
Map<String, Object> config = new HashMap<>();
84+
config.put("sourceField", "foo");
85+
config.put("targetField", "foo_decoded");
86+
87+
Map<String, Object> map = new HashMap<>();
88+
map.put("message", "testAllFieldsMissingShouldFail");
89+
90+
Doc doc = new Doc(map);
91+
92+
ProcessResult result;
93+
Processor processor = createProcessor(Base64DecodeProcessor.class, config);
94+
try {
95+
result = processor.process(doc);
96+
} catch (InterruptedException e) { throw new RuntimeException(e); }
97+
98+
assertThat(result != null && !result.isSucceeded()).isTrue();
99+
assertThat(result.getError().get().getMessage())
100+
.isEqualTo("field is missing from doc");
101+
assertThat(doc.hasField(config.get("targetField").toString())).isFalse();
102+
assertThat(doc.getField("message").toString()).isEqualTo(map.get("message").toString());
103+
}
104+
105+
private Map<String, Object> createConfig(String sourceField, String targetField) {
106+
Map<String, Object> config = new HashMap<>();
107+
config.put("sourceField", sourceField);
108+
config.put("targetField", targetField);
109+
return config;
110+
}
111+
}

0 commit comments

Comments
 (0)