Skip to content

Commit b7a1e06

Browse files
authored
Merge pull request #6569 from psiinon/automation/alwaysrun
automation: add alwaysRun option for all jobs
2 parents fcc8f9c + 9c8b844 commit b7a1e06

File tree

17 files changed

+182
-18
lines changed

17 files changed

+182
-18
lines changed

addOns/automation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66
## Unreleased
77
### Added
88
- Support for exclude regexes to active scan config job.
9+
- Always run option for all jobs.
910

1011
### Changed
1112
- Job remains selected when moved in the GUI.

addOns/automation/src/main/java/org/zaproxy/addon/automation/AutomationJob.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public enum Status {
6464
private long timeStarted;
6565
private long timeFinished;
6666
private boolean enabled = true;
67+
private boolean alwaysRun = false;
6768

6869
public enum Order {
6970
RUN_FIRST,
@@ -133,6 +134,14 @@ public void setEnabled(boolean enabled) {
133134
this.enabled = enabled;
134135
}
135136

137+
public boolean isAlwaysRun() {
138+
return alwaysRun;
139+
}
140+
141+
public void setAlwaysRun(boolean alwaysRun) {
142+
this.alwaysRun = alwaysRun;
143+
}
144+
136145
public int addDefaultTests(AutomationProgress progress) {
137146
return ZERO_TESTS;
138147
}

addOns/automation/src/main/java/org/zaproxy/addon/automation/AutomationPlan.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,26 @@ public AutomationPlan(ExtensionAutomation ext, File file) throws IOException {
134134

135135
Object jobEnabled = jobData.get("enabled");
136136
if (jobEnabled != null) {
137-
if (jobEnabled instanceof Boolean) {
138-
job.setEnabled((Boolean) jobEnabled);
137+
if (jobEnabled instanceof Boolean enableBool) {
138+
job.setEnabled(enableBool);
139139
} else {
140140
progress.warn(
141141
Constant.messages.getString(
142142
"automation.error.job.enabled", jobEnabled));
143143
}
144144
}
145145

146+
Object alwaysRun = jobData.get("alwaysRun");
147+
if (alwaysRun != null) {
148+
if (alwaysRun instanceof Boolean jobBool) {
149+
job.setAlwaysRun(jobBool);
150+
} else {
151+
progress.warn(
152+
Constant.messages.getString(
153+
"automation.error.job.alwaysrun", alwaysRun));
154+
}
155+
}
156+
146157
job.setEnv(env);
147158
job.setJobData(jobData);
148159
job.verifyParameters(progress);

addOns/automation/src/main/java/org/zaproxy/addon/automation/ExtensionAutomation.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ public AutomationProgress runPlan(AutomationPlan plan, boolean resetProgress) {
384384

385385
for (AutomationJob job : jobsToRun) {
386386

387+
if (env.isTimeToQuit() && !job.isAlwaysRun()) {
388+
continue;
389+
}
390+
387391
if (!job.isEnabled()) {
388392
progress.info(
389393
Constant.messages.getString("automation.info.jobdisabled", job.getType()));
@@ -425,9 +429,6 @@ public AutomationProgress runPlan(AutomationPlan plan, boolean resetProgress) {
425429
Constant.messages.getString(
426430
"automation.info.jobend", job.getType(), job.getFormattedTimeTaken()));
427431
progress.addRunJob(job);
428-
if (env.isTimeToQuit()) {
429-
break;
430-
}
431432
}
432433
setPlanFinished(plan);
433434
return progress;

addOns/automation/src/main/java/org/zaproxy/addon/automation/gui/PlanTreeTableModel.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,19 @@ public PlanTreeTableModel(DefaultMutableTreeNode root) {
4747

4848
protected static final int HIERARCHY_INDEX = 0;
4949
protected static final int ENABLED_INDEX = 1;
50-
protected static final int STATUS_INDEX = 2;
51-
protected static final int TIME_INDEX = 3;
52-
protected static final int TYPE_INDEX = 4;
53-
protected static final int NAME_INDEX = 5;
54-
protected static final int INFO_INDEX = 6;
50+
protected static final int ALWAYS_RUN_INDEX = 2;
51+
protected static final int STATUS_INDEX = 3;
52+
protected static final int TIME_INDEX = 4;
53+
protected static final int TYPE_INDEX = 5;
54+
protected static final int NAME_INDEX = 6;
55+
protected static final int INFO_INDEX = 7;
5556

5657
private static final String INDENT = " ";
5758

5859
private static final String[] COLUMN_NAMES = {
5960
"", // The tree control
6061
Constant.messages.getString("automation.panel.table.header.enabled"),
62+
Constant.messages.getString("automation.panel.table.header.alwaysrun"),
6163
Constant.messages.getString("automation.panel.table.header.status"),
6264
Constant.messages.getString("automation.panel.table.header.time"),
6365
Constant.messages.getString("automation.panel.table.header.type"),
@@ -117,6 +119,8 @@ public Object getValueAt(Object node, int columnIndex) {
117119
return "";
118120
case ENABLED_INDEX:
119121
return true;
122+
case ALWAYS_RUN_INDEX:
123+
return false;
120124
case STATUS_INDEX:
121125
if (!env.isCreated()) {
122126
return Constant.messages.getString(
@@ -156,6 +160,8 @@ public Object getValueAt(Object node, int columnIndex) {
156160
switch (columnIndex) {
157161
case ENABLED_INDEX:
158162
return job.isEnabled();
163+
case ALWAYS_RUN_INDEX:
164+
return job.isAlwaysRun();
159165
case STATUS_INDEX:
160166
switch (job.getStatus()) {
161167
case COMPLETED:
@@ -215,6 +221,8 @@ public Object getValueAt(Object node, int columnIndex) {
215221
switch (columnIndex) {
216222
case ENABLED_INDEX:
217223
return true;
224+
case ALWAYS_RUN_INDEX:
225+
return false;
218226
case STATUS_INDEX:
219227
if (!test.hasRun()) {
220228
return "";
@@ -262,6 +270,7 @@ public Object getValueAt(Object node, int columnIndex) {
262270
public Class<?> getColumnClass(int columnIndex) {
263271
switch (columnIndex) {
264272
case ENABLED_INDEX:
273+
case ALWAYS_RUN_INDEX:
265274
return Boolean.class;
266275
default:
267276
return String.class;
@@ -275,7 +284,7 @@ public int getHierarchicalColumn() {
275284

276285
@Override
277286
public boolean isCellEditable(Object node, int column) {
278-
if (column == ENABLED_INDEX) {
287+
if (column == ENABLED_INDEX || column == ALWAYS_RUN_INDEX) {
279288
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
280289
if (!treeNode.isRoot()) {
281290
Object obj = treeNode.getUserObject();
@@ -288,15 +297,18 @@ public boolean isCellEditable(Object node, int column) {
288297

289298
@Override
290299
public void setValueAt(Object value, Object node, int column) {
291-
if (column == ENABLED_INDEX) {
292-
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
293-
if (!treeNode.isRoot()) {
294-
Object obj = treeNode.getUserObject();
295-
if (obj instanceof AutomationJob) {
296-
AutomationJob job = (AutomationJob) obj;
300+
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
301+
if (!treeNode.isRoot()) {
302+
Object obj = treeNode.getUserObject();
303+
if (obj instanceof AutomationJob job) {
304+
if (column == ENABLED_INDEX) {
297305
job.setEnabled(((Boolean) value).booleanValue());
298306
job.setChanged();
299307
jobChanged(job);
308+
} else if (column == ALWAYS_RUN_INDEX) {
309+
job.setAlwaysRun(((Boolean) value).booleanValue());
310+
job.setChanged();
311+
jobChanged(job);
300312
}
301313
}
302314
}

addOns/automation/src/main/java/org/zaproxy/addon/automation/jobs/JobData.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public void setEnabled(boolean enabled) {
6767
this.job.setEnabled(enabled);
6868
}
6969

70+
public boolean isAlwaysRun() {
71+
return this.job.isAlwaysRun();
72+
}
73+
7074
public List<AutomationData> getTests() {
7175
List<AbstractAutomationTest> tests = this.job.getTests();
7276
if (tests.isEmpty()) {

addOns/automation/src/main/javahelp/org/zaproxy/addon/automation/resources/help/contents/automation.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ <H2><a name="file-paths">File Paths</a></H2>
6868
Relative paths are recommended for portability.
6969

7070
<H2><a name="jobs">Jobs</a></H2>
71-
The jobs can be enabled/disabled through the GUI and the automation plan, with the <code>enabled</code> flag. Jobs are enabled by default.
7271
<p>
7372
The following automation jobs are supported by this add-on:
7473
<ul>
@@ -81,6 +80,15 @@ <H2><a name="jobs">Jobs</a></H2>
8180
<li><a href="job-exitstatus.html">exitStatus</a> - sets ZAP's exit code based on scan results</li>
8281
</ul>
8382

83+
<H3><a name="gen-options">General Job Options</a></H3>
84+
85+
The following options can be applied to all jobs, via the automation plan or the <a href="gui.html">GUI</a>:
86+
87+
<ul>
88+
<li><code>enabled</code> - only jobs that are enabled will run.
89+
<li><code>alwaysRun</code> - enabled jobs with this option will run even if the plan exits early.
90+
</ul>
91+
8492
<H3>Importance of Job Order</H3>
8593
The order of jobs is relevant and important. For example:
8694
<ul>

addOns/automation/src/main/javahelp/org/zaproxy/addon/automation/resources/help/contents/gui.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ <H3>Plan sub-tab</H3>
3333

3434
A graphical representation of the plan which also shows the state of the plan when it is run.<br>
3535
You can edit any of the elements of the plan by double clicking on them.
36+
<p>
37+
You can also change the following general job options via the plan table:
38+
39+
<ul>
40+
<li>Enabled - only jobs that are enabled will run.
41+
<li>Always Run - enabled jobs with this option will run even if the plan exits early.
42+
</ul>
3643

3744
<H3>Output sub-tab</H3>
3845

addOns/automation/src/main/javahelp/org/zaproxy/addon/automation/resources/help/contents/job-ascan.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ <H2>YAML</H2>
4242
name: # String: The name of the rule for documentation purposes - this is not required or actually used
4343
strength: # String: The Attack Strength for this rule, one of Low, Medium, High, Insane, default: Medium
4444
threshold: # String: The Alert Threshold for this rule, one of Off, Low, Medium, High, default: Medium
45+
enabled: # Bool: If set to false the job will not be run, default: true
46+
alwaysRun: # Bool: If set and the job is enabled then it will run even if the plan exits early, default: false
4547
</pre>
4648

4749
<strong>Note</strong>: Unless the <code>defaultThreshold</code> of the <code>policyDefinition</code> is <code>OFF</code> all rules will be enabled to start with.

addOns/automation/src/main/javahelp/org/zaproxy/addon/automation/resources/help/contents/job-ascanconfig.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ <H2>YAML</H2>
4545
encodeCookieValues: # Bool: If cookie values should be encoded. Default: false
4646
scripts: # Bool: If Input Vector scripts should be used. Default: true
4747
excludePaths: # An optional list of regexes to exclude
48+
enabled: # Bool: If set to false the job will not be run, default: true
49+
alwaysRun: # Bool: If set and the job is enabled then it will run even if the plan exits early, default: false
4850
</pre>
4951

5052
Note that the 'excludePaths' will overwrite any existing session "Exclude from Scanner" paths.

0 commit comments

Comments
 (0)