e : build.getBuildVariables().entrySet()) {
+ envVars.put(e.getKey(), e.getValue());
+ System.out.println("KEY: " + e.getKey() + "VALUE: " + e.getValue());
+ }
+
+ System.out.println("INSIDE THE SETTER");
+ AbstractProject, ?> project = build.getProject();
+ //JDK 8u131 test
+ System.out.println("project.getJDK()");
+ JDK jdk = project.getJDK();
+ System.out.println("JDK: " + (jdk == null));
+
+ System.out.println("Jenkins.getInstance().getJDK(\"JDK 8u131 test\")");
+ jdk = Jenkins.getInstance().getJDK("JDK 8u131 test");
+ System.out.println("JDK: " + (jdk == null));
+
+ if (jdk != null) {
+ // System.out.println("JDK: " + jdkToUse.getHome());
+ // System.out.println("JDK: " + jdkToUse.getName());
+ Computer computer = Computer.currentComputer();
+ /* just in case we are not in a build */
+ if (computer != null)
+ jdk = jdk.forNode(computer.getNode(), listener);
+ jdk.buildEnvVars(envVars);
+ }
+ }
+
+ private EnvVars getEnvVars () throws IOException, InterruptedException {
+ return this.envVars;
+ }
+
+
+ static void waitForSuccessfulConnectionToZap(BuildListener listener, int timeout, String evaluatedZapHost, int evaluatedZapPort) {
+ Utils.loggerMessage(listener, 0, "[{0}] Waiting for connection", Utils.ZAP);
+ int timeoutInMs = (int) TimeUnit.SECONDS.toMillis(timeout);
+ int connectionTimeoutInMs = timeoutInMs;
+ int pollingIntervalInMs = (int) TimeUnit.SECONDS.toMillis(1);
+ boolean connectionSuccessful = false;
+ long startTime = System.currentTimeMillis();
+ Socket socket = null;
+ do
+ try {
+ socket = new Socket();
+ socket.connect(new InetSocketAddress(evaluatedZapHost, evaluatedZapPort), connectionTimeoutInMs);
+ connectionSuccessful = true;
+ }
+ catch (SocketTimeoutException ignore) {
+ listener.error(ExceptionUtils.getStackTrace(ignore));
+ throw new BuildException("Unable to connect to ZAP's proxy after " + timeout + " seconds.");
+
+ }
+ catch (IOException ignore) {
+ /* Try again but wait some time first */
+ try {
+ Thread.sleep(pollingIntervalInMs);
+ }
+ catch (InterruptedException e) {
+ listener.error(ExceptionUtils.getStackTrace(ignore));
+ throw new BuildException("The task was interrupted while sleeping between connection polling.", e);
+ }
+
+ long ellapsedTime = System.currentTimeMillis() - startTime;
+ if (ellapsedTime >= timeoutInMs) {
+ listener.error(ExceptionUtils.getStackTrace(ignore));
+ throw new BuildException("Unable to connect to ZAP's proxy after " + timeout + " seconds.");
+ }
+ connectionTimeoutInMs = (int) (timeoutInMs - ellapsedTime);
+ }
+ finally {
+ if (socket != null) try {
+ socket.close();
+ }
+ catch (IOException e) {
+ listener.error(ExceptionUtils.getStackTrace(e));
+ }
+ }
+ while (!connectionSuccessful);
+ Utils.loggerMessage(listener, 0, "[{0}] Connection established", Utils.ZAP);
+ }
+
+ public Proc launch () throws IOException, InterruptedException {
+
+ System.out.println();
+ printMap(getEnvVars());
+ System.out.println();
+
+ setCommand();
+
+ FilePath workDir = new FilePath(getWorkspace().getChannel(), getInstallationDir());
+
+ Utils.loggerMessage(listener, 0, "[{0}] EXECUTE LAUNCH COMMAND", Utils.ZAP);
+
+ return launcher.launch().cmds(getCommand()).envs(envVars).stdout(listener).pwd(workDir).start();
+
+ }
+
+ private void printMap(Map mp) {
+ Iterator it = mp.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pair = (Map.Entry) it.next();
+ System.out.println(pair.getKey() + " = " + pair.getValue());
+ it.remove(); // avoids a ConcurrentModificationException
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/jenkinsci/plugins/zap/ZAPBuilder.java b/src/main/java/org/jenkinsci/plugins/zap/ZAPBuilder.java
index 62b26e7..30264f9 100644
--- a/src/main/java/org/jenkinsci/plugins/zap/ZAPBuilder.java
+++ b/src/main/java/org/jenkinsci/plugins/zap/ZAPBuilder.java
@@ -61,7 +61,8 @@
/**
* The main class of the plugin. This class adds a build step in a Jenkins job that allows you to launch the ZAP security tool and generate reports based on the alerts.
- *
+ *
+ * @author Lenaic Tchokogoue
* @author Goran Sarenkapa
* @author Mostafa AbdelMoez
* @author Tanguy de Lignières
@@ -69,13 +70,13 @@
* @author Thilina Madhusanka
* @author Johann Ollivier-Lapeyre
* @author Ludovic Roucoux
- *
+ *
*/
-public class ZAPBuilder extends Builder {
+public class ZAPBuilder extends Builder {
/**
* The @DataBoundConstructor is a constructor and it's parameter names must match the fields in associated config file {@link "com/github/jenkinsci/zaproxyplugin/ZAPBuilder/config.jelly"} and additional can set the parameter values for the global configurations {@link "com/github/jenkinsci/zaproxyplugin/ZAPBuilder/global.jelly"}.
- *
+ *
* @param startZAPFirst
* of type boolean: start zap as a pre-build step or not.
* @param zapHost
@@ -270,6 +271,7 @@ public boolean prebuild(AbstractBuild, ?> build, BuildListener listener) {
/** Method called when the build is launching */
@Override
public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) {
+ listener.getLogger().println("zaproxy: " + zaproxy);
if (!startZAPFirst) try {
Utils.lineBreak(listener);
Utils.loggerMessage(listener, 0, "[{0}] START BUILD STEP", Utils.ZAP);
@@ -334,6 +336,20 @@ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListen
listener.error(ExceptionUtils.getStackTrace(e));
return false;
}
+
+ build.addAction(new ZAPInterfaceAction());
+ ZAPInterfaceAction zapInterface = build.getAction(ZAPInterfaceAction.class);
+ zapInterface.setBuildStatus(true);
+ zapInterface.setInstallationEnvVar(zaproxy.getZapHome());
+ zapInterface.setHomeDir(zaproxy.getZapSettingsDir());
+ zapInterface.setTimeout(zaproxy.getTimeout());
+ zapInterface.setHost(zaproxy.getEvaluatedZapHost());
+ zapInterface.setPort(zaproxy.getEvaluatedZapPort());
+ zapInterface.setAutoInstall(zaproxy.getAutoInstall());
+ zapInterface.setToolUsed(zaproxy.getToolUsed());
+ zapInterface.setCommandLineArgs(zaproxy.getEvaluatedCmdLinesZap());
+ zapInterface.setSessionFilePath(zaproxy.getSessionFilePath());
+
return res;
}
@@ -362,13 +378,13 @@ public static String applyMacro(AbstractBuild, ?> build, BuildListener listene
/**
* @Extension indicates to Jenkins this is an implementation of an extension point.
- *
+ *
* Descriptor for {@link ZAPBuilder}. Used as a singleton. The class is marked as public so that it can be accessed from views.
*
*
* See src/main/resources/com/github/jenkinsci/zaproxyplugin/ZAPBuilder/*.jelly for the actual HTML fragment for the configuration screen.
*/
- @Extension
+ @Extension
public static final ZAPBuilderDescriptorImpl DESCRIPTOR = new ZAPBuilderDescriptorImpl();
public static final class ZAPBuilderDescriptorImpl extends BuildStepDescriptor {
@@ -497,7 +513,7 @@ private static class CopyFileCallable implements FileCallable {
private File sourceFile;
private String destination;
private String stringForLogger;
-
+
public CopyFileCallable(File sourceFile, String destination, String stringForLogger) {
this.sourceFile = sourceFile;
this.destination = destination;
diff --git a/src/main/java/org/jenkinsci/plugins/zap/ZAPDriver.java b/src/main/java/org/jenkinsci/plugins/zap/ZAPDriver.java
index ff214a5..5d24797 100644
--- a/src/main/java/org/jenkinsci/plugins/zap/ZAPDriver.java
+++ b/src/main/java/org/jenkinsci/plugins/zap/ZAPDriver.java
@@ -86,6 +86,7 @@
import hudson.model.EnvironmentSpecific;
import hudson.model.JDK;
import hudson.model.Node;
+import hudson.model.Result;
import hudson.remoting.VirtualChannel;
import hudson.slaves.NodeSpecific;
import hudson.slaves.SlaveComputer;
@@ -632,7 +633,8 @@ public Proc startZAP(AbstractBuild, ?> build, BuildListener listener, Launcher
cmd.add(CMD_LINE_API_KEY + "=" + API_KEY);
/* Set the default directory used by ZAP if it's defined and if a scan is provided */
- if (this.activeScanURL && this.zapSettingsDir != null && !this.zapSettingsDir.isEmpty()) {
+ //if (this.activeScanURL && this.zapSettingsDir != null && !this.zapSettingsDir.isEmpty()) {
+ if (this.zapSettingsDir != null && !this.zapSettingsDir.isEmpty()) {
cmd.add(CMD_LINE_DIR);
cmd.add(this.zapSettingsDir);
}
@@ -734,49 +736,7 @@ private void addZAPAuthScriptParam(ArrayList authScriptParam
* @see [JAVA] Avoid sleep to wait ZAProxy initialization
*/
private void waitForSuccessfulConnectionToZap(BuildListener listener, int timeout) {
- int timeoutInMs = (int) TimeUnit.SECONDS.toMillis(timeout);
- int connectionTimeoutInMs = timeoutInMs;
- int pollingIntervalInMs = (int) TimeUnit.SECONDS.toMillis(1);
- boolean connectionSuccessful = false;
- long startTime = System.currentTimeMillis();
- Socket socket = null;
- do
- try {
- socket = new Socket();
- socket.connect(new InetSocketAddress(evaluatedZapHost, evaluatedZapPort), connectionTimeoutInMs);
- connectionSuccessful = true;
- }
- catch (SocketTimeoutException ignore) {
- listener.error(ExceptionUtils.getStackTrace(ignore));
- throw new BuildException("Unable to connect to ZAP's proxy after " + timeout + " seconds.");
-
- }
- catch (IOException ignore) {
- /* Try again but wait some time first */
- try {
- Thread.sleep(pollingIntervalInMs);
- }
- catch (InterruptedException e) {
- listener.error(ExceptionUtils.getStackTrace(ignore));
- throw new BuildException("The task was interrupted while sleeping between connection polling.", e);
- }
-
- long ellapsedTime = System.currentTimeMillis() - startTime;
- if (ellapsedTime >= timeoutInMs) {
- listener.error(ExceptionUtils.getStackTrace(ignore));
- throw new BuildException("Unable to connect to ZAP's proxy after " + timeout + " seconds.");
- }
- connectionTimeoutInMs = (int) (timeoutInMs - ellapsedTime);
- }
- finally {
- if (socket != null) try {
- socket.close();
- }
- catch (IOException e) {
- listener.error(ExceptionUtils.getStackTrace(e));
- }
- }
- while (!connectionSuccessful);
+ ZAP.waitForSuccessfulConnectionToZap(listener, timeout, evaluatedZapHost, evaluatedZapPort);
}
/**
@@ -1239,7 +1199,7 @@ else if (this.selectedReportMethod.equals(EXPORT_REPORT)) {
}
finally {
try {
- stopZAP(listener, clientApi);
+ ZAP.stopZAP(listener, clientApi);
}
catch (ClientApiException e) {
listener.error(ExceptionUtils.getStackTrace(e));
@@ -1250,6 +1210,7 @@ else if (this.selectedReportMethod.equals(EXPORT_REPORT)) {
return buildSuccess;
}
+
/**
* Method used to return the checked state inside CREATE JIRA ISSUES.
**/
@@ -2105,34 +2066,6 @@ else if (authMode) {
else Utils.loggerMessage(listener, 1, "SKIP ACTIVE SCAN FOR THE SITE [ {0} ]", targetURL);
}
- /**
- * Stop ZAP if it has been previously started.
- *
- * @param listener
- * of type BuildListener: the display log listener during the Jenkins job execution.
- * @param clientApi
- * of type ClientApi: the ZAP client API to call method.
- * @throws ClientApiException
- */
- private void stopZAP(BuildListener listener, ClientApi clientApi) throws ClientApiException {
- if (clientApi != null) {
- Utils.lineBreak(listener);
- Utils.loggerMessage(listener, 0, "[{0}] SHUTDOWN [ START ]", Utils.ZAP);
- Utils.lineBreak(listener);
- /**
- * @class ApiResponse org.zaproxy.clientapi.gen.Core
- *
- * @method shutdown
- *
- * @param String apikey
- *
- * @throws ClientApiException
- */
- clientApi.core.shutdown();
- }
- else Utils.loggerMessage(listener, 0, "[{0}] SHUTDOWN [ ERROR ]", Utils.ZAP);
- }
-
/**
* Descriptor for {@link ZAPDriver}. Used as a singleton. The class is marked as public so that it can be accessed from views.
*
@@ -2786,11 +2719,11 @@ private void getAvailableFormats(ZAPDriverDescriptorImpl zapDriver) {
private final ArrayList cmdLinesZAP; /* List of all ZAP command lines specified by the user ArrayList because it needs to be Serializable (whereas List is not Serializable). */
- public List getCmdLinesZAP() { return cmdLinesZAP; }
+ public ArrayList getCmdLinesZAP() { return cmdLinesZAP; }
private ArrayList evaluatedCmdLinesZap; /* Todo */
- public List getEvaluatedCmdLinesZap() { return evaluatedCmdLinesZap; }
+ public ArrayList getEvaluatedCmdLinesZap() { return evaluatedCmdLinesZap; }
public void setEvaluatedCmdLinesZap(ArrayList evaluatedCmdLinesZap) { this.evaluatedCmdLinesZap = evaluatedCmdLinesZap; }
@@ -2856,6 +2789,22 @@ private void getAvailableFormats(ZAPDriverDescriptorImpl zapDriver) {
public void setEvaluatedInternalSites(String evaluatedInternalSites) { this.evaluatedInternalSites = evaluatedInternalSites; }
+ private String sessionFilePath ;
+
+ public void setSessionFilePath(String sessionFilePath ){ this.sessionFilePath = sessionFilePath; }
+
+ public String getSessionFilePath(){
+ sessionFilePath = null ;
+ if (this.autoLoadSession) { /* LOAD SESSION */
+ File sessionFile = new File(this.loadSession);
+ sessionFilePath = sessionFile.getAbsolutePath() ;
+ }
+ else { /* PERSIST SESSION */
+ File sessionFile = new File(this.zapHome, this.evaluatedSessionFilename);
+ sessionFilePath = sessionFile.getAbsolutePath() ;
+ }
+ return sessionFilePath;
+ }
/* Session Properties */
private final String contextName; /* Context name to use for the session. */
diff --git a/src/main/java/org/jenkinsci/plugins/zap/ZAPInterfaceAction.java b/src/main/java/org/jenkinsci/plugins/zap/ZAPInterfaceAction.java
new file mode 100644
index 0000000..a51b29e
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/zap/ZAPInterfaceAction.java
@@ -0,0 +1,145 @@
+package org.jenkinsci.plugins.zap;
+
+import java.util.ArrayList;
+import hudson.model.Action;
+
+/**
+ * @author Lenaic Tchokogoue
+ * @author Goran Sarenkapa
+ *
+ */
+
+public class ZAPInterfaceAction implements Action {
+
+ private boolean buildStatus;
+ private int timeout;
+ private String installationEnvVar;
+ private String homeDir;
+ private String host;
+ private int port;
+ private boolean autoInstall;
+ private String toolUsed;
+ public String sessionFilePath;
+ ArrayList commandLineArgs;
+
+ public ZAPInterfaceAction() {
+ this.buildStatus = false;
+
+ this.timeout = -1;
+ this.homeDir = "";
+ this.installationEnvVar = "";
+ this.host = "";
+ this.port = 0;
+ this.commandLineArgs = null;
+ this.autoInstall = false;
+ this.toolUsed= null;
+ this.sessionFilePath=null;
+ }
+
+ public ZAPInterfaceAction(boolean buildStatus, String toolUsed, boolean autoInstall, String sessionFilePath, int timeout, String installationEnvVar, String homeDir, String host, int port, ArrayList commandLineArgs) {
+ this.buildStatus = buildStatus;
+ this.timeout = timeout;
+ this.installationEnvVar = installationEnvVar;
+ this.homeDir = homeDir;
+ this.host = host;
+ this.port = port;
+ this.commandLineArgs = commandLineArgs;
+ this.autoInstall = autoInstall;
+ this.toolUsed= toolUsed;
+ this.sessionFilePath = sessionFilePath;
+
+ }
+ public boolean getBuildStatus() {
+ return this.buildStatus;
+ }
+
+ public void setBuildStatus(boolean buildStatus) {
+ this.buildStatus = buildStatus;
+ }
+
+ public boolean getAutoInstall() {
+ return this.autoInstall;
+ }
+
+ public void setAutoInstall(boolean autoInstall) {
+ this.autoInstall = autoInstall;
+ }
+
+ public String getToolUsed() {
+ return this.toolUsed;
+ }
+
+ public void setToolUsed(String toolUsed) {
+ this.toolUsed = toolUsed;
+ }
+
+ public int getTimeout() {
+ return this.timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public String getInstallationEnvVar() {
+ return this.installationEnvVar;
+ }
+
+ public void setInstallationEnvVar(String installationEnvVar) {
+ this.installationEnvVar = installationEnvVar;
+ }
+
+ public String getHomeDir() {
+ return this.homeDir;
+ }
+
+ public void setHomeDir(String homeDir) {
+ this.homeDir = homeDir;
+ }
+
+ public String getHost() {
+ return this.host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public int getPort() {
+ return this.port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public ArrayList getCommandLineArgs(){
+ return commandLineArgs;
+ }
+
+ public void setCommandLineArgs(ArrayList commandLineArgs){
+ this.commandLineArgs = commandLineArgs;
+ }
+
+ public String getSessionFilePath(){return this.sessionFilePath;}
+
+ public void setSessionFilePath(String sessionFilePath){this.sessionFilePath = sessionFilePath;}
+
+ @Override
+ public String getDisplayName() {
+ return "My Action";
+ }
+
+ @Override
+ public String getIconFileName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getUrlName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/jenkinsci/plugins/zap/ZAPManagement.java b/src/main/java/org/jenkinsci/plugins/zap/ZAPManagement.java
new file mode 100644
index 0000000..7592181
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/zap/ZAPManagement.java
@@ -0,0 +1,550 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Goran Sarenkapa (JordanGS), and a number of other of contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.jenkinsci.plugins.zap;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import hudson.model.*;
+import hudson.remoting.VirtualChannel;
+import hudson.slaves.NodeSpecific;
+import hudson.slaves.SlaveComputer;
+import hudson.tools.ToolDescriptor;
+import hudson.tools.ToolInstallation;
+import jenkins.model.Jenkins;
+
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.zaproxy.clientapi.core.ApiResponseList;
+import org.zaproxy.clientapi.core.ApiResponseSet;
+import org.zaproxy.clientapi.core.ClientApi;
+import org.zaproxy.clientapi.core.ClientApiException;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.tools.ant.BuildException;
+import org.jenkinsci.remoting.RoleChecker;
+
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.Proc;
+import hudson.FilePath.FileCallable;
+
+/**
+ * Contains methods to start and execute ZAPManagement. Members variables are bound to the config.jelly placed to {@link "com/github/jenkinsci/zaproxyplugin/ZAPManagement/config.jelly"}
+ *
+ * @author Lenaic Tchokogoue
+ * @author Goran Sarenkapa
+ * @author Mostafa AbdelMoez
+ * @author Tanguy de Lignières
+ * @author Abdellah Azougarh
+ * @author Thilina Madhusanka
+ * @author Johann Ollivier-Lapeyre
+ * @author Ludovic Roucoux
+ *
+ * @see [JAVA] Client API The pom should show the artifact being from maven central.
+ */
+public class ZAPManagement extends AbstractDescribableImpl implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private static final String API_KEY = "ZAPROXY-PLUGIN";
+
+ /* Command Line Options - Not exposed through the API */
+ private static final String CMD_LINE_DIR = "-dir";
+ private static final String CMD_LINE_HOST = "-host";
+ private static final String CMD_LINE_PORT = "-port";
+ private static final String CMD_LINE_DAEMON = "-daemon";
+ private static final String CMD_LINE_CONFIG = "-config";
+ private static final String CMD_LINE_API_KEY = "api.key";
+
+ // private static final int timeout = 60; /* Time total to wait for ZAP initialization. After this time, the program is stopped. */
+
+ /* ZAP executable files */
+ private static final String ZAP_PROG_NAME_BAT = "zap.bat";
+ private static final String ZAP_PROG_NAME_SH = "zap.sh";
+
+ @DataBoundConstructor
+ public ZAPManagement(boolean buildThresholds, int hThresholdValue, int hSoftValue, int mThresholdValue, int mSoftValue, int lThresholdValue, int lSoftValue, int iThresholdValue, int iSoftValue, int cumulValue) {
+
+ /* Post Build Step*/
+ this.buildThresholds=buildThresholds;
+ this.hThresholdValue= hThresholdValue;
+ this.hSoftValue = hSoftValue;
+ this.mThresholdValue = mThresholdValue;
+ this.mSoftValue = mSoftValue;
+ this.lThresholdValue = lThresholdValue;
+ this.lSoftValue = lSoftValue;
+ this.iThresholdValue = iThresholdValue;
+ this.iSoftValue = iSoftValue;
+ this.cumulValue = cumulValue;
+ System.out.println(this.toString());
+ }
+
+ /**
+ * Evaluated values will return null, this is printed to console on save
+ *
+ * @return
+ */
+
+ @Override
+ public String toString() {
+ String s = "";
+ s += "\n";
+ s += "\n";
+ s += "Post Build action\n";
+ s += "\n";
+ s += "Manage Threshold\n";
+ s += "-------------------------------------------------------\n";
+ s += "high ThresholdValue [" + hThresholdValue + "]\n";
+ s += "high SoftValue [" + hSoftValue + "]\n";
+ s += "medium ThresholdValue [" + mThresholdValue + "]\n";
+ s += "medium SoftValue [" + mSoftValue + "]\n";
+ s += "low ThresholdValue [" + lThresholdValue + "]\n";
+ s += "low SoftValue [" + lSoftValue + "]\n";
+ s += "info ThresholdValue [" + iThresholdValue + "]\n";
+ s += "low SoftValue [" + iSoftValue + "]\n";
+ s += "cumulative Value [" + cumulValue + "]\n";
+ return s;
+ }
+
+ public Proc startZAP(AbstractBuild, ?> build, BuildListener listener, Launcher launcher) throws IllegalArgumentException, IOException, InterruptedException {
+ System.out.println("");
+ System.out.println("INITIATING POST BUILD");
+ System.out.println("");
+ System.out.println("");
+
+ if (!this.buildStatus){
+ Utils.loggerMessage(listener, 0, "[{0}] WE GOT FALSE SO WE BREAK", Utils.ZAP);
+ System.out.println("WE GOT FALSE SO WE BREAK");
+ return null;
+ }
+ System.out.println("WE GOT TRUE SO WE INIT");
+ ZAP zap = new ZAP(build, listener, launcher, this.getTimeout(), this.getInstallationEnvVar(), this.getHomeDir(), this.getToolUsed(),this.getAutoInstall(), this.getHost(), this.getPort(), this.getCommandLineArgs());
+
+ this.zapProgram = zap.getInstallationDir();
+ zap.checkParams(this.zapProgram);
+
+ System.out.println("startZAP list -------------");
+ for(int i = 0; i < this.getCommandLineArgs().size(); i++) {
+ System.out.println(this.getCommandLineArgs().get(i));
+ }
+
+ System.out.println("");
+ System.out.println("BEFORE SETTING JDK");
+ zap.setBuildJDK();
+
+ /*
+ * Launch ZAP process on remote machine (on master if no remote machine)
+ */
+ Proc proc = zap.launch();
+
+
+ /* Call waitForSuccessfulConnectionToZap(int, BuildListener) remotely */
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 0, "[{0}] INITIALIZATION [ START ]", Utils.ZAP);
+ build.getWorkspace().act(new WaitZAPManagementInitCallable(listener, this));
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 0, "[{0}] INITIALIZATION [ SUCCESSFUL ]", Utils.ZAP);
+ Utils.lineBreak(listener);
+
+ return proc;
+ }
+
+ /**
+ * Wait for ZAP's initialization such that it is ready to use at the end of the method, otherwise catch the exception. If there is a remote machine, then this method will be launched there.
+ *
+ * @param listener
+ * of type BuildListener: the display log listener during the Jenkins job execution.
+ * @see [JAVA] Avoid sleep to wait ZAProxy initialization
+ */
+ private void waitForSuccessfulConnectionToZap(BuildListener listener) {
+ ZAP.waitForSuccessfulConnectionToZap(listener, timeout, getHost(), getPort());
+ }
+
+ /**
+ * Execute ZAPDriver method following build's setup and stop ZAP at the end. Note: No param's to executeZAP method since they would also need to be accessible in Builder, somewhat redundant.
+ *
+ * @param listener
+ * of type BuildListener: the display log listener during the Jenkins job execution.
+ * @param workspace
+ * of type FilePath: a {@link FilePath} representing the build's workspace.
+ * @return of type: boolean DESC: true if no exception is caught, false otherwise.
+ */
+ public Result executeZAP(BuildListener listener, FilePath workspace) {
+ listener.getLogger().println("executeZAP");
+ Result buildResult = Result.SUCCESS;
+ boolean buildSuccess = true;
+
+
+ /* Check to make sure that plugin's are installed with ZAP if they are selected in the UI. */
+
+ ClientApi clientApi = new ClientApi(getHost(), getPort(), API_KEY);
+
+
+ try {
+ if (buildSuccess) {
+ /* LOAD SESSION */
+ /*
+ * @class org.zaproxy.clientapi.gen.Core
+ *
+ * @method loadSession
+ *
+ * @param String apikey
+ * @param String name
+ *
+ * @throws ClientApiException
+ */
+ Utils.loggerMessage(listener, 0, "[{0}] Loading session : {1}", Utils.ZAP, this.getSessionFilePath());
+ clientApi.core.loadSession(this.getSessionFilePath());
+
+ /* SETUP THRESHOLDING */
+ Utils.lineBreak(listener);
+ buildResult = manageThreshold( listener, clientApi, this.hThresholdValue, this.hSoftValue, this.mThresholdValue, this.mSoftValue, this.lThresholdValue, this.lSoftValue, this.iThresholdValue, this.iSoftValue, this.cumulValue);
+
+ }
+ }
+ catch (Exception e) {
+ listener.error(ExceptionUtils.getStackTrace(e));
+ buildSuccess = false;
+ buildResult=Result.ABORTED;
+ }
+ finally {
+ try {
+ ZAP.stopZAP(listener, clientApi);
+ }
+ catch (ClientApiException e) {
+ listener.error(ExceptionUtils.getStackTrace(e));
+ buildSuccess = false;
+ buildResult=Result.ABORTED;
+ }
+ }
+ Utils.lineBreak(listener);
+ return buildResult;
+ }
+
+ /**
+ * manageThreshold define build value failed, pass , unstable.
+ *
+ * @param listener
+ * of type BuildListener: the display log listener during the Jenkins job execution.
+ * @param clientApi
+ * of type ClientApi: the ZAP client API to call method.
+ * @param hThresholdValue
+ * of type int: the Weight of the alert severity high.
+ * @param hSoftValue
+ * of type int: the threshold of the alert severity high.
+ * @param mThresholdValue
+ * of type int: the Weight of the alert severity meduim.
+ * @param mSoftValue
+ * of type int: the threshold of the alert severity meduim.
+ * @param lThresholdValue
+ * of type int: the Weight of the alert severity low.
+ * @param lSoftValue
+ * of type int: the threshold of the alert severity low.
+ * @param iThresholdValue
+ * of type int: the Weight of the alert severity informational.
+ * @param iSoftValue
+ * of type int: the threshold of the alert severity informational.
+ * @param cumulValue
+ * of type int: the cumulative threshold of the alerts.
+ *
+ */
+
+ private Result manageThreshold(BuildListener listener,ClientApi clientApi, int hThresholdValue, int hSoftValue, int mThresholdValue, int mSoftValue, int lThresholdValue, int lSoftValue, int iThresholdValue, int iSoftValue, int cumulValue) throws ClientApiException, IOException {
+
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 0, "[{0}] -------------------------------------------------------", Utils.ZAP);
+ Utils.loggerMessage(listener, 0, "[{0}] START : COMPUTE THRESHOLD", Utils.ZAP);
+ Result buildResult = Result.SUCCESS;
+
+ Utils.lineBreak(listener);
+ int nbAlertHigh = countAlertbySeverity(clientApi, "High");
+ Utils.loggerMessage(listener, 1, "[{0}] ALERTS High COUNT [ {1} ]", Utils.ZAP, Integer.toString(nbAlertHigh));
+
+ int nbAlertMedium = countAlertbySeverity(clientApi, "Medium");
+ Utils.loggerMessage(listener, 1, "[{0}] ALERTS Medium COUNT [ {1} ]", Utils.ZAP, Integer.toString(nbAlertMedium));
+
+ int nbAlertLow = countAlertbySeverity(clientApi, "Low");
+ //setLowAlert(nbAlertLow);
+ Utils.loggerMessage(listener, 1, "[{0}] ALERTS Low COUNT [ {1} ]", Utils.ZAP, Integer.toString(nbAlertLow));
+
+ int nbAlertInfo =countAlertbySeverity(clientApi, "Informational");
+ Utils.loggerMessage(listener, 1, "[{0}] ALERTS Informational COUNT [ {1} ]", Utils.ZAP, Integer.toString(nbAlertInfo));
+
+ int hScale = computeProduct(hThresholdValue,nbAlertHigh);
+ int mScale = computeProduct(mThresholdValue,nbAlertMedium);
+ int lScale = computeProduct(lThresholdValue,nbAlertLow);
+ int iScale = computeProduct(iThresholdValue,nbAlertInfo);
+
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 1, "[{0}] ----- COMPUTED / SOFT THRESHOLD -----", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] High [ {1} / {2} ]", Utils.ZAP, Integer.toString(hScale), Integer.toString(hSoftValue));
+ Utils.loggerMessage(listener, 1, "[{0}] Medium [ {1} / {2} ]", Utils.ZAP, Integer.toString(mScale), Integer.toString(mSoftValue));
+ Utils.loggerMessage(listener, 1, "[{0}] Low [ {1} / {2} ]", Utils.ZAP, Integer.toString(lScale), Integer.toString(lSoftValue));
+ Utils.loggerMessage(listener, 1, "[{0}] Informational [ {1} / {2} ]", Utils.ZAP, Integer.toString(iScale), Integer.toString(iSoftValue));
+ Utils.loggerMessage(listener, 1, "[{0}] Cumulative [ {1} / {2} ]", Utils.ZAP, Integer.toString(hScale+mScale+lScale+iScale), Integer.toString(cumulValue));
+ Utils.lineBreak(listener);
+
+
+ if((hScale > hSoftValue) || ((hScale+mScale+lScale+iScale)> cumulValue)) {
+ Utils.loggerMessage(listener, 1, "[{0}] ##################################################", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] # HIGH OR CUMULATIVE SOFT THRESHOLD HAS BEEN HIT #", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] # BUILD IS MARKED AS FAILED #", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] ##################################################", Utils.ZAP);
+ Utils.lineBreak(listener);
+ buildResult = Result.FAILURE;
+ } else if((mScale > mSoftValue) || (lScale > lSoftValue ) || (iScale > iSoftValue)) {
+ Utils.loggerMessage(listener, 1, "[{0}] ###########################################", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] # ONE OR MORE SOFT THRESHOLD HAS BEEN HIT #", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] # BUILD IS MARKED AS UNSTABLE #", Utils.ZAP);
+ Utils.loggerMessage(listener, 1, "[{0}] ###########################################", Utils.ZAP);
+ Utils.lineBreak(listener);
+ buildResult = Result.UNSTABLE;
+ }
+
+
+ Utils.loggerMessage(listener, 0, "[{0}] END : COMPUTING THRESHOLD", Utils.ZAP);
+ Utils.loggerMessage(listener, 0, "[{0}] -------------------------------------------------------", Utils.ZAP);
+
+ return buildResult;
+
+ }
+
+ /**
+ * computeProduct do the product of two Integer.
+ *
+ * @param a
+ * of type Integer.
+ * @param b
+ * of type Integer.
+ */
+ public int computeProduct(int a, int b){
+ return a * b;
+ }
+
+ /**
+ * countAlertbySeverity count the number of alert by severity.
+ *
+ * @param clientApi
+ * of type ClientApi: the ZAP client API to call method.
+ * @param risk
+ * of type string : it's the alert severity.
+ */
+ public int countAlertbySeverity(ClientApi clientApi,String risk)throws ClientApiException{
+ int nbAlert = 0;
+ List tempid = new ArrayList();
+ tempid.add("begin");
+
+ List allAlerts1 = ((ApiResponseList) clientApi.core.alerts("","","")).getItems();
+ for(int i=0;i {
+
+ private static final long serialVersionUID = 1L;
+
+ private BuildListener listener;
+ private ZAPManagement zapManagement;
+
+ public WaitZAPManagementInitCallable(BuildListener listener, ZAPManagement zapManagement) {
+ this.listener = listener;
+ this.zapManagement = zapManagement;
+ }
+
+ @Override
+ public Void invoke(File f, VirtualChannel channel) {
+ zapManagement.waitForSuccessfulConnectionToZap(listener);
+ return null;
+ }
+
+ @Override
+ public void checkRoles(RoleChecker checker) throws SecurityException { /* N/A */ }
+ }
+
+ @Extension
+ public static class ZAPManagementDescriptorImpl extends Descriptor implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * To persist global configuration information, simply store it in a field and call save().
+ *
+ *
+ * If you don't want fields to be persisted, use transient.
+ */
+
+ /** Represents the build's workspace */
+ private FilePath workspace;
+
+ public void setWorkspace(FilePath ws) { this.workspace = ws; }
+
+ @Override
+ public String getDisplayName() { return null; }
+
+ /**
+ * In order to load the persisted global configuration, you have to call load() in the constructor.
+ */
+ public ZAPManagementDescriptorImpl() {
+ load();
+ }
+ }
+
+ /*
+ * Variable Declaration Getters allows to load members variables into UI. Setters
+ */
+ @Override
+ public ZAPManagementDescriptorImpl getDescriptor() { return (ZAPManagementDescriptorImpl) super.getDescriptor(); }
+
+ /* Overridden for better type safety. If your plugin doesn't really define any property on Descriptor, you don't have to do this. */
+
+ private String contextId; /* ID of the created context. */
+
+ private String userId; /* ID of the created user. */
+
+ /* Post Build Step >> Manage Threshold */
+
+ private int nbAlertLow;
+ private void setLowAlert (int a){
+ nbAlertLow = a;
+ }
+ public int getLowAlert(){
+ return nbAlertLow;
+ }
+
+ // private final String jdk; /* The IDK to use to start ZAP. */
+//
+// public String getJdk() { return jdk; }
+//
+// /* Gets the JDK that this Sonar builder is configured with, or null. */
+// public JDK getJDK() { return Jenkins.getInstance().getJDK(jdk); }
+//***********
+ private static String zapHost;
+ private static int zapPort;
+
+ //*************/
+ private String zapProgram; /* Path to the ZAP security tool. */
+
+ private final boolean buildThresholds;
+ public boolean isbuildThresholds() {return buildThresholds;}
+
+ private final int hThresholdValue;
+ public int gethThresholdValue() {return hThresholdValue;}
+
+ private final int hSoftValue;
+ public int gethSoftValue() {return hSoftValue;}
+
+ private final int mThresholdValue;
+ public int getmThresholdValue() {return mThresholdValue;}
+
+ private final int mSoftValue;
+ public int getmSoftValue() {return mSoftValue;}
+
+ private final int lThresholdValue;
+ public int getlThresholdValue() {return lThresholdValue;}
+
+ private final int lSoftValue;
+ public int getlSoftValue() {return lSoftValue;}
+
+ private final int iThresholdValue;
+ public int getiThresholdValue() {return iThresholdValue;}
+
+ private final int iSoftValue;
+ public int getiSoftValue() {return iSoftValue;}
+
+ private final int cumulValue;
+
+ public Boolean execute;
+ public int getcumulValue() {return cumulValue;}
+
+ /*****************************/
+
+ private boolean buildStatus;
+ private boolean autoInstall;
+ private int timeout;
+ private String installationEnvVar;
+ private String homeDir;
+ private String host;
+ private int port;
+ private String toolUsed;
+ public String sessionFilePath;
+
+ public void setBuildStatus(boolean buildStatus) {this.buildStatus = buildStatus;}
+
+ public boolean getAutoInstall(){return this.autoInstall;}
+
+ public void setAutoInstall(boolean autoInstall) {this.autoInstall = autoInstall;}
+
+ private String getToolUsed(){return this.toolUsed;}
+
+ public void setToolUsed(String toolUsed) {this.toolUsed = toolUsed;}
+
+ private int getTimeout() {return this.timeout;}
+
+ public void setTimeout(int timeout) {this.timeout = timeout;}
+
+ private String getInstallationEnvVar() {return this.installationEnvVar;}
+
+ public void setInstallationEnvVar(String installationEnvVar) {this.installationEnvVar = installationEnvVar;}
+
+ private String getHomeDir() {return this.homeDir;}
+
+ public void setHomeDir(String homeDir) {this.homeDir = homeDir;}
+
+ public String getHost() {return this.host;}
+
+ public void setHost(String host) {this.host = host;}
+
+ public int getPort() {return this.port;}
+
+ public void setPort(int port) {this.port = port;}
+
+ public String getSessionFilePath(){return this.sessionFilePath;}
+
+ public void setSessionFilePath(String sessionFilePath){this.sessionFilePath = sessionFilePath;}
+
+ private ArrayList commandLineArgs; /* List of all ZAP command lines specified by the user ArrayList because it needs to be Serializable (whereas List is not Serializable). */
+
+ public ArrayList getCommandLineArgs() { return commandLineArgs; }
+
+ public void setCommandLineArgs(ArrayList commandLineArgs) { this.commandLineArgs = commandLineArgs; }
+}
diff --git a/src/main/java/org/jenkinsci/plugins/zap/ZAPManagementBuilder.java b/src/main/java/org/jenkinsci/plugins/zap/ZAPManagementBuilder.java
new file mode 100644
index 0000000..beee3b2
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/zap/ZAPManagementBuilder.java
@@ -0,0 +1,217 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Goran Sarenkapa (JordanGS), and a number of other of contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.jenkinsci.plugins.zap;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.jenkinsci.remoting.RoleChecker;
+import org.kohsuke.stapler.DataBoundConstructor;
+
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.FilePath.FileCallable;
+import hudson.Launcher;
+import hudson.Proc;
+import hudson.model.AbstractBuild;
+import hudson.model.AbstractProject;
+import hudson.model.BuildListener;
+import hudson.model.Result;
+import hudson.remoting.VirtualChannel;
+import hudson.tasks.BuildStepDescriptor;
+import hudson.tasks.BuildStepMonitor;
+import hudson.tasks.Publisher;
+import hudson.tasks.Recorder;
+
+/**
+ * @author Lenaic Tchokogoue
+ * @author Goran Sarenkapa
+ *
+ */
+public class ZAPManagementBuilder extends Recorder {
+
+
+ @DataBoundConstructor
+ public ZAPManagementBuilder(ZAPManagement management) {
+ this.management = management;
+
+ /* Call the set methods of ZAPDriver to set the values */
+ // this.zaproxy.setJiraUsername(ZAPBuilder.DESCRIPTOR.getJiraUsername());
+ // this.zaproxy.setJiraPassword(ZAPBuilder.DESCRIPTOR.getJiraPassword());
+ // ZAPInterfaceAction zapInterface =
+ // build.getAction(ZAPInterfaceAction.class);
+ //
+ // System.out.println("my action timeout: " +
+ // zapInterface.getTimeout());
+ // System.out.println("my action install dir: " +
+ // zapInterface.getInstallationDir());
+ // System.out.println("my action home dir: " +
+ // zapInterface.getHomeDir());
+ }
+
+ private ZAPManagement management;
+
+ public ZAPManagement getManagement() { return management; }
+
+ private Proc proc = null;
+
+ @Override
+ public BuildStepMonitor getRequiredMonitorService() {
+ return BuildStepMonitor.NONE;
+ }
+
+ @Override /* @Override for better type safety, not needed if plugin doesn't define any property on Descriptor */
+ public ZAPManagementBuilderDescriptorImpl getDescriptor() { return (ZAPManagementBuilderDescriptorImpl) super.getDescriptor(); }
+
+ /** Method called when the build is launching
+ * @throws InterruptedException
+ * @throws IOException */
+ @Override
+ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
+ listener.getLogger().println("[ZAP Jenkins Plugin] POST-BUILD MANAGEMENT");
+ ZAPInterfaceAction zapInterface = build.getAction(ZAPInterfaceAction.class);
+ if (zapInterface != null) {
+ if (zapInterface.getBuildStatus()) {
+ System.out.println("----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ");
+ System.out.println("my action timeout: " + zapInterface.getTimeout());
+ System.out.println("my action install dir: " + zapInterface.getInstallationEnvVar());
+ System.out.println("my action home dir: " + zapInterface.getHomeDir());
+ System.out.println("my action host: " + zapInterface.getHost());
+ System.out.println("my action port: " + zapInterface.getPort());
+ System.out.println("my action command line args extra: " + zapInterface.getCommandLineArgs().size());
+ System.out.println("my action autoinstall: " + zapInterface.getAutoInstall());
+ System.out.println("my action tool used: " + zapInterface.getToolUsed());
+ System.out.println("my action session path: " + zapInterface.getSessionFilePath());
+ System.out.println("----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ");
+ for (int i = 0; i < zapInterface.getCommandLineArgs().size(); i++) {
+ System.out.println(zapInterface.getCommandLineArgs().get(i));
+ }
+ this.management.setBuildStatus(zapInterface.getBuildStatus());
+ this.management.setTimeout(zapInterface.getTimeout());
+ this.management.setInstallationEnvVar(zapInterface.getInstallationEnvVar());
+ this.management.setHomeDir(zapInterface.getHomeDir());
+ this.management.setHost(zapInterface.getHost());
+ this.management.setPort(zapInterface.getPort());
+ this.management.setCommandLineArgs(zapInterface.getCommandLineArgs());
+ this.management.setAutoInstall(zapInterface.getAutoInstall());
+ this.management.setToolUsed(zapInterface.getToolUsed());
+ this.management.setSessionFilePath(zapInterface.getSessionFilePath());
+ }
+ }
+ else {
+ /* THE DEFAULT CONSTRUCTOR IS NEVER TRIGGER, DERP DERP */
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 0, "[{0}] THERE IS NO BUILD STEP, MARKED AS FAILURE", Utils.ZAP);
+ Utils.lineBreak(listener);
+ return false;
+ }
+ try {
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 0, "[{0}] START BUILD STEP", Utils.ZAP);
+ Utils.lineBreak(listener);
+ listener.getLogger().println("management: " + management);
+ listener.getLogger().println("build: " + build);
+ listener.getLogger().println("listener: " + listener);
+ listener.getLogger().println("launcher: " + launcher);
+
+ proc = management.startZAP(build, listener, launcher);
+ listener.getLogger().println("after proc assignment");
+ }
+ catch (Exception e) {
+ listener.getLogger().println("we failed");
+ e.printStackTrace();
+ listener.error(ExceptionUtils.getStackTrace(e));
+ return false;
+ }
+
+ Result res;
+ try {
+ res = build.getWorkspace().act(new ZAPManagementCallable(listener, this.management));
+ build.setResult(res);
+ proc.joinWithTimeout(60L, TimeUnit.MINUTES, listener);
+ Utils.lineBreak(listener);
+ Utils.lineBreak(listener);
+ Utils.loggerMessage(listener, 0, "[{0}] SHUTDOWN [ SUCCESSFUL ]", Utils.ZAP);
+ Utils.lineBreak(listener);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ listener.error(ExceptionUtils.getStackTrace(e));
+ return false;
+ }
+ // EnvVars abc = build.getEnvironment(listener);
+ // printMap(abc);
+ return res.completeBuild;
+ }
+ private void printMap(Map mp) {
+ Iterator it = mp.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pair = (Map.Entry) it.next();
+ System.out.println(pair.getKey() + " = " + pair.getValue());
+ it.remove(); // avoids a ConcurrentModificationException
+ }
+ }
+ @Extension
+ public static final class ZAPManagementBuilderDescriptorImpl extends BuildStepDescriptor {
+
+ /* In order to load the persisted global configuration, you have to call load() in the constructor. */
+ public ZAPManagementBuilderDescriptorImpl() { load(); }
+
+ /* Indicates that this builder can be used with all kinds of project types */
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean isApplicable(Class extends AbstractProject> aClass) { return true; }
+
+ /* This human readable name is used in the configuration screen. */
+ @Override
+ public String getDisplayName() { return Messages.jenkins_jobconfig_addpostbuild_zap(); }
+ }
+
+ /**
+ * Used to execute ZAP remotely.
+ */
+ private static class ZAPManagementCallable implements FileCallable {
+
+ private static final long serialVersionUID = 1L;
+ private BuildListener listener;
+ private ZAPManagement management;
+
+ public ZAPManagementCallable(BuildListener listener, ZAPManagement management) {
+ this.listener = listener;
+ this.management = management;
+ }
+
+ @Override
+ public Result invoke(File f, VirtualChannel channel) { return management.executeZAP(listener, new FilePath(f)); }
+
+ @Override
+ public void checkRoles(RoleChecker checker) throws SecurityException { /* N/A */ }
+ }
+}
diff --git a/src/main/resources/org/jenkinsci/plugins/zap/Messages.properties b/src/main/resources/org/jenkinsci/plugins/zap/Messages.properties
index 582bd46..fb18af9 100644
--- a/src/main/resources/org/jenkinsci/plugins/zap/Messages.properties
+++ b/src/main/resources/org/jenkinsci/plugins/zap/Messages.properties
@@ -1 +1,2 @@
-jenkins.jobconfig.addbuildstep.zap=Execute ZAP
\ No newline at end of file
+jenkins.jobconfig.addbuildstep.zap=ZAP Executor
+jenkins.jobconfig.addpostbuild.zap=ZAP Management
diff --git a/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagement/config.jelly b/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagement/config.jelly
new file mode 100644
index 0000000..8f48371
--- /dev/null
+++ b/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagement/config.jelly
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+ |
+ ${%Threshold Value} |
+ ${%Soft Threshold } |
+
+
+ | High |
+ |
+ |
+
+
+ | Medium |
+ |
+ |
+
+
+ | Low |
+ |
+ |
+
+
+ | Info |
+ |
+ |
+
+
+
+
+ | Cumulative Threshold |
+ |
+
+
+
+
+
+
+
diff --git a/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagementBuilder/config.jelly b/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagementBuilder/config.jelly
new file mode 100644
index 0000000..dd7fdac
--- /dev/null
+++ b/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagementBuilder/config.jelly
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagementBuilder/help-buildThresholds.html b/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagementBuilder/help-buildThresholds.html
new file mode 100644
index 0000000..b86ad1c
--- /dev/null
+++ b/src/main/resources/org/jenkinsci/plugins/zap/ZAPManagementBuilder/help-buildThresholds.html
@@ -0,0 +1,6 @@
+Post Build Management Threshold, allows zap to define if a build is flagged as passed, failed or unstable.
+Threshold value stand for the weight of each alert severity
+Soft value is threshold of each alert severity
+Cumulative value is the threshold of the all build
+The build goes unstable when we are under the soft or cumulative value
+The build goes failed when we are under the soft and cumulative value