Skip to content

Commit

Permalink
[JENKINS-51717] Support for new report formats (#4)
Browse files Browse the repository at this point in the history
* add support for json, yaml and xml reports

* findbug error fixed
  • Loading branch information
irissmann committed Jun 9, 2018
1 parent 3e84e51 commit 527b63c
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -22,7 +22,7 @@
<dependency>
<groupId>de.irissmann</groupId>
<artifactId>arachni-client</artifactId>
<version>1.0.3.1</version>
<version>1.0.4</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
Expand Down
48 changes: 45 additions & 3 deletions src/main/java/org/jenkinsci/plugins/arachni/ArachniScanner.java
Expand Up @@ -8,9 +8,12 @@
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
Expand Down Expand Up @@ -38,20 +41,28 @@
public class ArachniScanner extends Builder implements SimpleBuildStep {
transient private static final Logger log = Logger.getLogger(ArachniScanner.class.getName());

protected static final String FORMAT_HTML = "html";
protected static final String FORMAT_JSON = "json";
protected static final String FORMAT_XML = "xml";
protected static final String FORMAT_YAML = "yaml";

private String url;
private String checks;
private UserConfigProperty userConfig;
private ArachniScopeProperty scope;
private String format;
private Scan scan;
private PrintStream console;
private ArachniClient arachniClient;

@DataBoundConstructor
public ArachniScanner(String url, String checks, ArachniScopeProperty scope, UserConfigProperty userConfig) {
public ArachniScanner(String url, String checks, ArachniScopeProperty scope, UserConfigProperty userConfig,
String format) {
this.url = url;
this.checks = checks;
this.scope = scope;
this.userConfig = userConfig;
this.format = format;
}

public String getUrl() {
Expand All @@ -70,6 +81,13 @@ public UserConfigProperty getUserConfig() {
return userConfig;
}

public String getFormat() {
if (StringUtils.isEmpty(format)) {
return FORMAT_HTML;
}
return format;
}

@Symbol("arachniScanner")
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Builder> {
Expand Down Expand Up @@ -157,14 +175,30 @@ public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskLi
}
}

File reportFile = new File(workspace.getRemote(), "arachni-report-html.zip");
String filename = String.format("arachni-report-%s.zip", getFormat());
File reportFile = new File(workspace.getRemote(), filename);
if (!reportFile.exists()) {
if (!reportFile.createNewFile()) {
throw new AbortException("Could not create file " + reportFile.toString());
}
}
outstream = new FileOutputStream(reportFile);
scan.getReportHtml(outstream);
switch (getFormat()) {
case FORMAT_HTML:
scan.getReportHtml(outstream);
break;
case FORMAT_JSON:
writeZipFile(scan.getReportJson().getBytes(StandardCharsets.UTF_8), "arachni-report.json", outstream);
break;
case FORMAT_XML:
writeZipFile(scan.getReportXml().getBytes(StandardCharsets.UTF_8), "arachni-report.xml", outstream);
break;
case FORMAT_YAML:
writeZipFile(scan.getReportYaml().getBytes(StandardCharsets.UTF_8), "arachni-report.yml", outstream);
break;
default:
throw new AbortException("Report format not supported");
}
} catch (FileNotFoundException exception) {
log.warning("Error when start Arachni Security Scan");
console.println(exception.getMessage());
Expand Down Expand Up @@ -192,6 +226,14 @@ protected void shutdownScan() throws IOException {
arachniClient.close();
}
}

private void writeZipFile(byte[] content, String entryName, OutputStream outstream) throws IOException {
ZipOutputStream zip = (new ZipOutputStream(outstream));
zip.putNextEntry(new ZipEntry(entryName));
zip.write(content);
zip.closeEntry();
zip.close();
}

private ArachniClient getArachniClient(ArachniPluginConfiguration config) {
ArachniRestClientBuilder builder = ArachniRestClientBuilder.create(config.getArachniServerUrl());
Expand Down
Expand Up @@ -12,4 +12,20 @@
<f:optionalProperty title="${%Set scope}" field="scope"/>

<f:optionalProperty field="userConfig" title="${%Use configuration file}"/>

<f:entry title="${%Report format}" field="format">
<f:entry>
<f:radio name="format" title="HTML" value="html" checked="${instance.format == 'html'}"/>
</f:entry>
<f:entry>
<f:radio name="format" title="JSON" value="json" checked="${instance.format == 'json'}"/>
</f:entry>
<f:entry>
<f:radio name="format" title="XML" value="xml" checked="${instance.format == 'xml'}"/>
</f:entry>
<f:entry>
<f:radio name="format" title="YAML" value="yaml" checked="${instance.format == 'yaml'}"/>
</f:entry>
</f:entry>

</j:jelly>
Expand Up @@ -47,7 +47,7 @@ public void setUp() throws Exception {
@Test
public void performScan() throws Exception {
FreeStyleProject project = jenkins.createFreeStyleProject();
project.getBuildersList().add(new ArachniScanner("http://test-site:9090", null, null, null));
project.getBuildersList().add(new ArachniScanner("http://test-site:9090", null, null, null, ArachniScanner.FORMAT_HTML));
ArachniPluginConfiguration config = new ArachniPluginConfiguration();
config.setArachniServerUrl("http://localhost:8877");

Expand Down

0 comments on commit 527b63c

Please sign in to comment.