Skip to content

Commit

Permalink
Merge pull request #311 from logzio/add-base64-decode-processor
Browse files Browse the repository at this point in the history
  • Loading branch information
ronshay committed Jul 19, 2023
2 parents 3dbe420 + 850c2bb commit 1f31636
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/git-secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
# This workflow contains a single job called "main"
git-secrets:
# The type of runner that the job will run on
runs-on: ubuntu-18.04
runs-on: macos-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
Expand All @@ -22,7 +22,7 @@ jobs:
python-version: 3.8
- name: Installing dependencies
run:
sudo apt-get install git less openssh-server
brew install git less openssh
- name: Installing scanning tool
run: |
brew install git-secrets
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.logz.sawmill.processors;

import io.logz.sawmill.Doc;
import io.logz.sawmill.ProcessResult;
import io.logz.sawmill.Processor;
import io.logz.sawmill.annotations.ProcessorProvider;
import io.logz.sawmill.exceptions.ProcessorConfigurationException;
import io.logz.sawmill.utilities.JsonUtils;

import java.util.Base64;
import java.util.Map;

import static java.util.Objects.requireNonNull;

@ProcessorProvider(type = "base64Decode", factory = Base64DecodeProcessor.Factory.class)
public class Base64DecodeProcessor implements Processor {

private final String sourceField;
private final String targetField;

public Base64DecodeProcessor(String sourceField, String targetField) {
this.sourceField = requireNonNull(sourceField);
this.targetField = requireNonNull(targetField);
}

@Override
public ProcessResult process(Doc doc) {
if(!doc.hasField(sourceField, String.class))
return ProcessResult.failure("field is missing from doc");

String value = doc.getField(sourceField);
String decodedValue = new String(Base64.getDecoder().decode(value));
doc.addField(targetField, decodedValue);
return ProcessResult.success();
}

public static class Factory implements Processor.Factory {
public Factory() {}

@Override
public Base64DecodeProcessor create(Map<String,Object> config) {
Base64DecodeProcessor.Configuration configuration =
JsonUtils.fromJsonMap(Base64DecodeProcessor.Configuration.class, config);
validateConfiguration(configuration);
return new Base64DecodeProcessor(configuration.getSourceField(), configuration.getTargetField());
}

private void validateConfiguration(Configuration configuration) {
if(configuration.getSourceField() == null || configuration.getSourceField().isEmpty()
|| configuration.getTargetField() == null || configuration.getTargetField().isEmpty())
throw new ProcessorConfigurationException("sourceField, targetField can not be null or empty");
}
}

public static class Configuration implements Processor.Configuration {
private String sourceField;
private String targetField;

public Configuration() {}
public Configuration(String sourceField, String targetField) {
this.sourceField = sourceField;
this.targetField = targetField;
}

public String getSourceField() { return sourceField; }
public String getTargetField() { return targetField; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package io.logz.sawmill.processors;

import io.logz.sawmill.Doc;
import io.logz.sawmill.ProcessResult;
import io.logz.sawmill.Processor;
import io.logz.sawmill.exceptions.ProcessorConfigurationException;
import org.junit.Test;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

import static io.logz.sawmill.utils.FactoryUtils.createProcessor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

public class Base64DecodeProcessorTest {

@Test
public void testNullOrEmptyConfigurationFieldsShouldFailCreator() {
Stream.of(
createConfig(null, "target"),
createConfig("", "target"),
createConfig("source", null),
createConfig("source", ""))
.forEach((config) -> assertThatThrownBy(() -> createProcessor(Base64DecodeProcessor.class, config))
.isInstanceOf(ProcessorConfigurationException.class)
.hasMessageContaining("sourceField, targetField can not be null or empty"));
}

@Test
public void testDecode() {
Map<String, Object> config = new HashMap<>();
config.put("sourceField", "message");
config.put("targetField", "message_decoded");

Map<String, Object> map = new HashMap<>();
String encodedMessage = Base64.getEncoder().encodeToString("testEmptyFieldsShouldFail".getBytes());
map.put("message", encodedMessage);
Doc doc = new Doc(map);

ProcessResult result;
Processor processor = createProcessor(Base64DecodeProcessor.class, config);
try {
result = processor.process(doc);
} catch (InterruptedException e) { throw new RuntimeException(e); }

assertThat(result != null && result.isSucceeded()).isTrue();
assertThat(doc.getField(config.get("sourceField").toString()).toString()).isEqualTo(encodedMessage);
assertThat(doc.getField(config.get("targetField").toString()).toString())
.isEqualTo("testEmptyFieldsShouldFail");
}

@Test
public void testNonStringFieldShouldFail() {
Map<String, Object> config = new HashMap<>();
config.put("sourceField", "numberField");
config.put("targetField", "noop");

Map<String, Object> map = new HashMap<>();
map.put("message", "testSingleNonStringFieldShouldFail");
map.put("numberField", 123);
Doc doc = new Doc(map);

Processor processor = createProcessor(Base64DecodeProcessor.class, config);

ProcessResult result;

try {
result = processor.process(doc);
} catch (InterruptedException e) { throw new RuntimeException(e); }
assertThat(result != null && !result.isSucceeded()).isTrue();
assertThat(result.getError().isPresent()).isTrue();
assertThat(result.getError().get().getMessage())
.isEqualTo("field is missing from doc");
assertThat(doc.hasField(config.get("targetField").toString())).isFalse();
assertThat(doc.getField("message").toString()).isEqualTo(map.get("message").toString());
}

@Test
public void testMissingFieldShouldFail() {
Map<String, Object> config = new HashMap<>();
config.put("sourceField", "foo");
config.put("targetField", "foo_decoded");

Map<String, Object> map = new HashMap<>();
map.put("message", "testAllFieldsMissingShouldFail");

Doc doc = new Doc(map);

ProcessResult result;
Processor processor = createProcessor(Base64DecodeProcessor.class, config);
try {
result = processor.process(doc);
} catch (InterruptedException e) { throw new RuntimeException(e); }

assertThat(result != null && !result.isSucceeded()).isTrue();
assertThat(result.getError().get().getMessage())
.isEqualTo("field is missing from doc");
assertThat(doc.hasField(config.get("targetField").toString())).isFalse();
assertThat(doc.getField("message").toString()).isEqualTo(map.get("message").toString());
}

private Map<String, Object> createConfig(String sourceField, String targetField) {
Map<String, Object> config = new HashMap<>();
config.put("sourceField", sourceField);
config.put("targetField", targetField);
return config;
}
}

0 comments on commit 1f31636

Please sign in to comment.