package org.zaproxy.zap.extension.pscan;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import net.htmlparser.jericho.Source;
import org.apache.commons.configuration.Configuration;
import org.junit.Before;
import org.junit.Test;
import org.parosproxy.paros.core.scanner.Plugin.AlertThreshold;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.control.AddOn;
import org.zaproxy.zap.utils.ZapXmlConfiguration;
import static org.junit.Assert.assertThat;
/**
* Unit test for {@link PluginPassiveScanner}.
*/
public class PluginPassiveScannerUnitTest {
private PluginPassiveScanner scanner;
@Before
public void setUp() throws Exception {
scanner = new TestPluginPassiveScanner();
}
@Test
public void shouldHaveUndefinedPluginIdByDefault() {
assertThat(scanner.getPluginId(), is(equalTo(-1)));
}
@Test
public void shouldHaveUnkownStatusByDefault() {
assertThat(scanner.getStatus(), is(equalTo(AddOn.Status.unknown)));
}
@Test(expected = IllegalArgumentException.class)
public void shouldFailToSetNullStatus() {
// Given
AddOn.Status status = null;
// When
scanner.setStatus(status);
// Then = IllegalArgumentException.
}
@Test
public void shouldSetValidStatus() {
// Given
AddOn.Status status = AddOn.Status.beta;
// When
scanner.setStatus(status);
// Then
assertThat(scanner.getStatus(), is(equalTo(status)));
}
@Test
public void shouldBeEnabledByDefault() {
assertThat(scanner.isEnabled(), is(equalTo(true)));
}
@Test
public void shouldChangeEnabledState() {
// Given
boolean enabled = true;
// When
scanner.setEnabled(enabled);
// Then
assertThat(scanner.isEnabled(), is(equalTo(enabled)));
}
@Test
public void shouldHaveMediumAsDefaultLevel() {
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.MEDIUM)));
}
@Test(expected = IllegalArgumentException.class)
public void shouldFailToSetNullLevel() {
// Given
AlertThreshold level = null;
// When
scanner.setLevel(level);
// Then = IllegalArgumentException.
}
@Test
public void shouldSetValidLevel() {
// Given
AlertThreshold level = AlertThreshold.HIGH;
// When
scanner.setLevel(level);
// Then
assertThat(scanner.getLevel(), is(equalTo(level)));
}
@Test(expected = IllegalArgumentException.class)
public void shouldFailToSetNullDefaultLevel() {
// Given
AlertThreshold level = null;
// When
scanner.setDefaultLevel(level);
// Then = IllegalArgumentException.
}
@Test(expected = IllegalArgumentException.class)
public void shouldFailToSetDefaultToDefaultLevel() {
// Given
AlertThreshold level = AlertThreshold.DEFAULT;
// When
scanner.setDefaultLevel(level);
// Then = IllegalArgumentException.
}
@Test
public void shouldSetValidDefaultLevel() {
// Given
scanner.setLevel(AlertThreshold.DEFAULT);
AlertThreshold level = AlertThreshold.HIGH;
// When
scanner.setDefaultLevel(level);
// Then
assertThat(scanner.getLevel(), is(equalTo(level)));
}
@Test
public void shouldHaveNoConfigurationByDefault() {
assertThat(scanner.getConfig(), is(nullValue()));
}
@Test(expected = IllegalArgumentException.class)
public void shouldFailToSetNullConfiguration() {
// Given
Configuration configuration = null;
// When
scanner.setConfig(configuration);
// Then = IllegalArgumentException.
}
@Test
public void shouldNotChangeEnabledStateOrLevelIfConfigurationSetIsEmpty() {
Configuration configuration = createEmptyConfiguration();
// given
scanner.setEnabled(false);
scanner.setLevel(AlertThreshold.HIGH);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.isEnabled(), is(false));
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.HIGH)));
}
@Test
public void shouldNotChangeEnabledStateOrLevelIfNoApplicableDataIsPresentInConfigurationSet() {
Configuration configuration = createConfiguration(Integer.MIN_VALUE, Boolean.TRUE, AlertThreshold.LOW);
// given
scanner.setEnabled(false);
scanner.setLevel(AlertThreshold.HIGH);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.isEnabled(), is(false));
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.HIGH)));
}
@Test
public void shouldEnableByDefaultIfNotSpecifiedInConfigurationSet() {
// given
Configuration configuration = createConfiguration(TestPluginPassiveScanner.PLUGIN_ID, null, null);
scanner.setEnabled(false);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.isEnabled(), is(true));
}
@Test
public void shouldDisableIfSpecifiedInConfigurationSet() {
// given
Configuration configuration = createConfiguration(TestPluginPassiveScanner.PLUGIN_ID, Boolean.FALSE, null);
scanner.setEnabled(true);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.isEnabled(), is(false));
}
@Test
public void shouldUseDefaultLevelIfNotSpecifiedInConfigurationSet() {
// given
Configuration configuration = createConfiguration(TestPluginPassiveScanner.PLUGIN_ID, Boolean.TRUE, null);
scanner.setDefaultLevel(AlertThreshold.HIGH);
scanner.setLevel(AlertThreshold.LOW);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.HIGH)));
}
@Test
public void shouldUseLevelSpecifiedInConfigurationSet() {
// given
Configuration configuration = createConfiguration(TestPluginPassiveScanner.PLUGIN_ID, null, AlertThreshold.HIGH);
scanner.setLevel(AlertThreshold.LOW);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.HIGH)));
}
@Test
public void shouldUseClassnameToReadConfigurationSet() {
// given
Configuration configuration = createConfiguration(
TestPluginPassiveScanner.class.getCanonicalName(),
Boolean.FALSE,
AlertThreshold.HIGH);
scanner.setEnabled(true);
scanner.setLevel(AlertThreshold.LOW);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.isEnabled(), is(false));
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.HIGH)));
}
@Test
public void shouldReadConfigurationSetEvenIfThereAreMultipleUnrelatedEntries() {
// given
Configuration configuration = createEmptyConfiguration();
addConfiguration(configuration, 0, 10, null, null);
addConfiguration(configuration, 1, "TestClassName", Boolean.TRUE, AlertThreshold.HIGH);
addConfiguration(configuration, 2, TestPluginPassiveScanner.PLUGIN_ID, Boolean.FALSE, AlertThreshold.MEDIUM);
addConfiguration(configuration, 3, 1011, null, AlertThreshold.LOW);
addConfiguration(configuration, 4, "OtherTestClassName", Boolean.FALSE, AlertThreshold.OFF);
scanner.setEnabled(true);
scanner.setLevel(AlertThreshold.LOW);
// when
scanner.setConfig(configuration);
// then
assertThat(scanner.isEnabled(), is(false));
assertThat(scanner.getLevel(), is(equalTo(AlertThreshold.MEDIUM)));
}
@Test(expected = IllegalStateException.class)
public void shouldFailToSaveByDefault() {
// Given / When
scanner.save();
// Then = IllegalStateException.
}
@Test
public void shouldNotPersistEnabledStateOnSaveIfEnabled() {
// given
Configuration configuration = createEmptyConfiguration();
scanner.setConfig(configuration);
scanner.setEnabled(true);
// when
scanner.save();
// then
assertThat(configuration.containsKey("pscans.pscanner(0).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(false));
}
@Test
public void shouldPersistEnabledStateOnSaveIfDisabled() {
// Given
Configuration configuration = createEmptyConfiguration();
scanner.setConfig(configuration);
scanner.setEnabled(false);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).enabled"), is(true));
assertThat(configuration.getBoolean("pscans.pscanner(0).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(0).id"), is(equalTo(TestPluginPassiveScanner.PLUGIN_ID)));
}
@Test
public void shouldNotPersistLevelOnSaveIfDefaultValue() {
// Given
Configuration configuration = createEmptyConfiguration();
scanner.setConfig(configuration);
scanner.setLevel(AlertThreshold.MEDIUM);
scanner.setEnabled(true);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(false));
}
@Test
public void shouldPersistLevelOnSaveIfNotDefaultValue() {
// Given
Configuration configuration = createEmptyConfiguration();
scanner.setConfig(configuration);
scanner.setLevel(AlertThreshold.HIGH);
scanner.setEnabled(true);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).level"), is(true));
assertThat(configuration.getString("pscans.pscanner(0).level"), is(equalTo(AlertThreshold.HIGH.name())));
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(0).id"), is(equalTo(TestPluginPassiveScanner.PLUGIN_ID)));
}
@Test
public void shouldRemoveExistingConfigDataOnSaveIfDefaultValues() {
// Given
Configuration configuration = createConfiguration(
TestPluginPassiveScanner.PLUGIN_ID,
Boolean.FALSE,
AlertThreshold.HIGH);
scanner.setConfig(configuration);
scanner.setEnabled(true);
scanner.setLevel(AlertThreshold.MEDIUM);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(false));
}
@Test
public void shouldRemoveClassnameConfigEntryOnSave() {
// Given
Configuration configuration = createConfiguration(
TestPluginPassiveScanner.class.getCanonicalName(),
Boolean.FALSE,
AlertThreshold.HIGH);
scanner.setConfig(configuration);
scanner.setEnabled(true);
scanner.setLevel(AlertThreshold.MEDIUM);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).classname"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(false));
}
@Test
public void shouldPersistConfigsOnSaveEvenIfThereAreMultipleUnrelatedEntries() {
// Given
Configuration configuration = createEmptyConfiguration();
addConfiguration(configuration, 0, 10, null, null);
addConfiguration(configuration, 1, "TestClassName", Boolean.TRUE, AlertThreshold.HIGH);
addConfiguration(configuration, 2, TestPluginPassiveScanner.PLUGIN_ID, Boolean.FALSE, AlertThreshold.MEDIUM);
addConfiguration(configuration, 3, 1011, null, AlertThreshold.LOW);
scanner.setConfig(configuration);
scanner.setEnabled(false);
scanner.setLevel(AlertThreshold.LOW);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(0).id"), is(equalTo(10)));
assertThat(configuration.containsKey("pscans.pscanner(0).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(1).id"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(1).classname"), is(true));
assertThat(configuration.getString("pscans.pscanner(1).classname"), is(equalTo("TestClassName")));
assertThat(configuration.containsKey("pscans.pscanner(1).enabled"), is(true));
assertThat(configuration.getBoolean("pscans.pscanner(1).enabled"), is(true));
assertThat(configuration.containsKey("pscans.pscanner(1).level"), is(true));
assertThat(configuration.getString("pscans.pscanner(1).level"), is(equalTo(AlertThreshold.HIGH.name())));
assertThat(configuration.containsKey("pscans.pscanner(2).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(2).id"), is(equalTo(1011)));
assertThat(configuration.containsKey("pscans.pscanner(2).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(2).level"), is(true));
assertThat(configuration.getString("pscans.pscanner(2).level"), is(equalTo(AlertThreshold.LOW.name())));
assertThat(configuration.containsKey("pscans.pscanner(3).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(3).id"), is(equalTo(TestPluginPassiveScanner.PLUGIN_ID)));
assertThat(configuration.containsKey("pscans.pscanner(3).enabled"), is(true));
assertThat(configuration.getBoolean("pscans.pscanner(3).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(3).level"), is(true));
assertThat(configuration.getString("pscans.pscanner(3).level"), is(equalTo(AlertThreshold.LOW.name())));
assertThat(configuration.containsKey("pscans.pscanner(4).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(4).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(5).id"), is(false));
}
@Test
public void shouldRemoveExistingConfigDataOnSaveIfDefaultValuesEvenIfThereAreMultipleUnrelatedEntries() {
// Given
Configuration configuration = createEmptyConfiguration();
addConfiguration(configuration, 0, 10, null, null);
addConfiguration(configuration, 1, "TestClassName", Boolean.TRUE, AlertThreshold.HIGH);
addConfiguration(configuration, 2, TestPluginPassiveScanner.PLUGIN_ID, Boolean.FALSE, AlertThreshold.MEDIUM);
addConfiguration(configuration, 3, 1011, null, AlertThreshold.LOW);
scanner.setConfig(configuration);
scanner.setEnabled(true);
scanner.setLevel(AlertThreshold.MEDIUM);
// When
scanner.save();
// Then
assertThat(configuration.containsKey("pscans.pscanner(0).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(0).id"), is(equalTo(10)));
assertThat(configuration.containsKey("pscans.pscanner(0).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(0).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(1).id"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(1).classname"), is(true));
assertThat(configuration.getString("pscans.pscanner(1).classname"), is(equalTo("TestClassName")));
assertThat(configuration.containsKey("pscans.pscanner(1).enabled"), is(true));
assertThat(configuration.getBoolean("pscans.pscanner(1).enabled"), is(true));
assertThat(configuration.containsKey("pscans.pscanner(1).level"), is(true));
assertThat(configuration.getString("pscans.pscanner(1).level"), is(equalTo(AlertThreshold.HIGH.name())));
assertThat(configuration.containsKey("pscans.pscanner(2).id"), is(true));
assertThat(configuration.getInt("pscans.pscanner(2).id"), is(equalTo(1011)));
assertThat(configuration.containsKey("pscans.pscanner(2).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(2).level"), is(true));
assertThat(configuration.getString("pscans.pscanner(2).level"), is(equalTo(AlertThreshold.LOW.name())));
assertThat(configuration.containsKey("pscans.pscanner(3).enabled"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(3).level"), is(false));
assertThat(configuration.containsKey("pscans.pscanner(3).id"), is(false));
}
private static class TestPluginPassiveScanner extends PluginPassiveScanner {
private static final int PLUGIN_ID = -1;
@Override
public void setParent(PassiveScanThread parent) {
}
@Override
public void scanHttpResponseReceive(HttpMessage msg, int id,
Source source) {
}
@Override
public void scanHttpRequestSend(HttpMessage msg, int id) {
}
@Override
public String getName() {
return null;
}
}
private static Configuration createEmptyConfiguration() {
return new ZapXmlConfiguration();
}
private static Configuration createConfiguration(String classname, Boolean enabled, AlertThreshold alertThreshold) {
ZapXmlConfiguration configuration = new ZapXmlConfiguration();
setClassname(configuration, 0, classname);
setProperties(configuration, 0, enabled, alertThreshold);
return configuration;
}
private static void setClassname(Configuration configuration, int index, String classname) {
configuration.setProperty("pscans.pscanner(" + index + ").classname", classname);
}
private static Configuration createConfiguration(int pluginId, Boolean enabled, AlertThreshold alertThreshold) {
ZapXmlConfiguration configuration = new ZapXmlConfiguration();
addConfiguration(configuration, 0, pluginId, enabled, alertThreshold);
return configuration;
}
private static void addConfiguration(
Configuration configuration,
int index,
String classname,
Boolean enabled,
AlertThreshold alertThreshold) {
setClassname(configuration, index, classname);
setProperties(configuration, index, enabled, alertThreshold);
}
private static void addConfiguration(
Configuration configuration,
int index,
int pluginId,
Boolean enabled,
AlertThreshold alertThreshold) {
configuration.setProperty("pscans.pscanner(" + index + ").id", pluginId);
setProperties(configuration, index, enabled, alertThreshold);
}
private static void setProperties(Configuration configuration, int index, Boolean enabled, AlertThreshold alertThreshold) {
if (enabled != null) {
configuration.setProperty("pscans.pscanner(" + index + ").enabled", enabled);
}
if (alertThreshold != null) {
configuration.setProperty("pscans.pscanner(" + index + ").level", alertThreshold.name());
}
}
}