Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include-SCA support #165

Merged
merged 7 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/com/hcl/appscan/sdk/CoreConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public interface CoreConstants {
String ITEMS = "Items"; //$NON-NLS-1$

String CREATE_SCAN_SUCCESS = "message.created.scan"; //$NON-NLS-1$
String SCAN_OVERVIEW = "message.scan.overview"; //$NON-NLS-1$
String DOWNLOADING_CLIENT = "message.downloading.client"; //$NON-NLS-1$
String EXECUTING_SCAN = "message.running.scan"; //$NON-NLS-1$
String UPLOADING_FILE = "message.uploading.file"; //$NON-NLS-1$
Expand All @@ -123,6 +124,7 @@ public interface CoreConstants {
String ERROR_AUTHENTICATING = "error.authenticating"; //$NON-NLS-1$
String ERROR_DOWNLOADING_CLIENT = "error.download.client"; //$NON-NLS-1$
String ERROR_GETTING_DETAILS = "error.getting.details"; //$NON-NLS-1$
String ERROR_GETTING_DETAILS_SCAN_ID = "error.getting.details.scan.id"; //$NON-NLS-1$
String ERROR_GETTING_RESULT = "error.getting.result"; //$NON-NLS-1$
String ERROR_GENERATING_REPORT = "error.generating.report"; //$NON-NLS-1$
String ERROR_INVALID_APP = "error.invalid.app"; //$NON-NLS-1$
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/com/hcl/appscan/sdk/messages.properties
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#
# \u00c2\u00a9 Copyright IBM Corporation 2016.
# \u00c2\u00a9 Copyright HCL Technologies Ltd. 2017, 2020, 2024.
# \u00c2\u00a9 Copyright HCL Technologies Ltd. 2017, 2024.
# LICENSE: Apache License, Version 2.0 https://www.apache.org/licenses/LICENSE-2.0
#
# NLS_MESSAGEFORMAT_VAR
# NLS_ENCODING=UNICODE

transfer.progress={0}% transferred

message.created.scan=Successfully submitted scan for analysis.
message.created.scan=Successfully submitted {0} scan for analysis. Scan ID: {1}
message.scan.overview={0} scan overview: {1}
message.running.scan=Creating and executing {0} scan...
message.uploading.file=Uploading {0} to the analysis service...
message.done=Done.
Expand All @@ -25,8 +26,9 @@ message.suspend.job.byuser=Scan has been Suspended by User, {0}
error.authenticating=An error occurred authenticating with the service.
error.download.client=An error occurred downloading the SAClientUtil package. {0}
error.getting.details=An error occurred retrieving the scan details. {0}
error.getting.details.scan.id= An error occurred retrieving the scan details. Scan ID: {0}
error.getting.result=An error occurred retrieving the scan result. {0}
error.generating.report=An error occurred in generating the report. {0}
error.generating.report=An error occurred in generating the report. {0}
error.invalid.app=Application with id {0} does not exist.
error.invalid.job.id=Job ID {0} is invalid or does not exist.
error.loading.apps=An error occurred retrieving the application list. {0}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* © Copyright HCL Technologies Ltd. 2024.
* LICENSE: Apache License, Version 2.0 https://www.apache.org/licenses/LICENSE-2.0
*/

package com.hcl.appscan.sdk.results;

import java.io.File;
import java.io.Serializable;
import java.util.Collection;

import com.hcl.appscan.sdk.CoreConstants;
import com.hcl.appscan.sdk.logging.IProgress;

public class CloudCombinedResultsProvider implements IResultsProvider, Serializable {

private static final long serialVersionUID = 1L;

private IResultsProvider m_resultsProvider1;
private IResultsProvider m_resultsProvider2;
private String m_reportFormat = DEFAULT_REPORT_FORMAT;

public CloudCombinedResultsProvider(IResultsProvider resultsProvider1, IResultsProvider resultsProvider2) {
m_resultsProvider1 = resultsProvider1;
m_resultsProvider2 = resultsProvider2;
}

@Override
public boolean hasResults() {
return m_resultsProvider1.hasResults() || m_resultsProvider2.hasResults();
}

@Override
public String getStatus() {
String combinedStatus = CoreConstants.RUNNING;
String status1 = m_resultsProvider1.getStatus();
String status2 = m_resultsProvider2.getStatus();

if(status1.equalsIgnoreCase(CoreConstants.FAILED) || status2.equalsIgnoreCase(CoreConstants.FAILED)) {
combinedStatus = CoreConstants.FAILED;
}
else if(status1.equalsIgnoreCase(CoreConstants.READY) && status2.equalsIgnoreCase(CoreConstants.READY)) {
combinedStatus = CoreConstants.READY;
}

return combinedStatus;
}

@Override
public Collection<?> getFindings() {
return null;
}

@Override
public int getFindingsCount() {
return m_resultsProvider1.getFindingsCount() + m_resultsProvider2.getFindingsCount();
}

@Override
public int getCriticalCount() {
return m_resultsProvider1.getCriticalCount() + m_resultsProvider2.getCriticalCount();
}

@Override
public int getHighCount() {
return m_resultsProvider1.getHighCount() + m_resultsProvider2.getHighCount();
}

@Override
public int getMediumCount() {
return m_resultsProvider1.getMediumCount() + m_resultsProvider2.getMediumCount();
}

@Override
public int getLowCount() {
return m_resultsProvider1.getLowCount() + m_resultsProvider2.getLowCount();
}

@Override
public int getInfoCount() {
return m_resultsProvider1.getInfoCount() + m_resultsProvider2.getInfoCount();
}

@Override
public String getType() {
return m_resultsProvider1.getType() + "_" + m_resultsProvider2.getType();
}

@Override
public void getResultsFile(File destination, String format) {
//Append the technology type to the end of the file name.
String name = destination.getName();
File directory = destination.getParentFile();
m_resultsProvider1.getResultsFile(new File(directory, name), format);
m_resultsProvider2.getResultsFile(new File(directory, name), format);
}

@Override
public String getResultsFormat() {
return m_reportFormat;
}

@Override
public String getMessage() {
if(m_resultsProvider1.getMessage() != null && m_resultsProvider2.getMessage() != null) {
return m_resultsProvider1.getType() + ": " + m_resultsProvider1.getMessage() + "\n" +
m_resultsProvider2.getType() + ": " + m_resultsProvider2.getMessage();
}
return null;
}

@Override
public void setReportFormat(String format) {
m_reportFormat = format;
m_resultsProvider1.setReportFormat(format);
m_resultsProvider2.setReportFormat(format);
}

@Override
public void setProgress(IProgress progress) {
m_resultsProvider1.setProgress(progress);
m_resultsProvider2.setProgress(progress);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
public class CloudResultsProvider implements IResultsProvider, Serializable, CoreConstants {

private static final long serialVersionUID = 1L;

private static String DEFAULT_REPORT_FORMAT = "html"; //$NON-NLS-1$

protected String m_type;
protected String m_scanId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* © Copyright IBM Corporation 2016.
* © Copyright HCL Technologies Ltd. 2017, 2020.
* © Copyright HCL Technologies Ltd. 2017, 2024.
* LICENSE: Apache License, Version 2.0 https://www.apache.org/licenses/LICENSE-2.0
*/

Expand All @@ -16,6 +16,8 @@
*/
public interface IResultsProvider {

public static String DEFAULT_REPORT_FORMAT = "html"; //$NON-NLS-1$

/**
* Answers whether or not this provider contains any results.
* @return True if the provider has results.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,67 +35,71 @@ public NonCompliantIssuesResultProvider(String scanId, String type, IScanService

@Override
protected void loadResults() {
try {
JSONObject items = m_scanProvider.getScanDetails(m_scanId);
JSONObject obj = items == null ? null : items.getJSONObject(LATEST_EXECUTION);
if (obj == null) {
m_status = FAILED;
return;
} else if (items.has(KEY) && items.get(KEY).equals(UNAUTHORIZED_ACTION)) {
m_status = FAILED;
return;
} else if (obj.has(STATUS) && obj.get(STATUS).equals(UNKNOWN)) {
m_status = UNKNOWN;
return;
}


m_status = obj.getString(STATUS);
if (FAILED.equalsIgnoreCase(m_status) && obj.has(USER_MESSAGE)) {
m_progress.setStatus(new Message(Message.ERROR, obj.getString(USER_MESSAGE)));
m_message = obj.getString(USER_MESSAGE);
} else if (PAUSED.equalsIgnoreCase(m_status)) {
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(SUSPEND_JOB_BYUSER, "Scan Id: " + m_scanId)));
m_message = Messages.getMessage(SUSPEND_JOB_BYUSER, "Scan Id: " + m_scanId);
} else if (m_status != null && !(m_status.equalsIgnoreCase(INQUEUE) || m_status.equalsIgnoreCase(RUNNING) || m_status.equalsIgnoreCase(PAUSING))) {
JSONArray array = m_scanProvider.getNonCompliantIssues(m_scanId);
m_totalFindings = 0;

for (int i = 0; i < array.length(); i++) {
JSONObject jobj = array.getJSONObject(i);
String sev = jobj.getString("Severity");
int count = jobj.getInt("N");

switch (sev.toLowerCase()) {
case "critical":
m_criticalFindings += count;
m_totalFindings += count;
break;
case "high":
m_highFindings += count;
m_totalFindings += count;
break;
case "medium":
m_mediumFindings += count;
m_totalFindings += count;
break;
case "low":
m_lowFindings += count;
m_totalFindings += count;
break;
case "informational":
m_infoFindings += count;
m_totalFindings += count;
break;
default:
m_totalFindings += count;
break;
}
}
setHasResult(true);
m_message = "";
} else if (RUNNING.equalsIgnoreCase(m_status)) m_message = "";
} catch (IOException | JSONException | NullPointerException e) {
try {
if (m_scanId == null) {
m_status = FAILED;
} else {
JSONObject items = m_scanProvider.getScanDetails(m_scanId);
JSONObject obj = items == null ? null : items.getJSONObject(LATEST_EXECUTION);
if (obj == null) {
m_status = FAILED;
return;
} else if (items.has(KEY) && items.get(KEY).equals(UNAUTHORIZED_ACTION)) {
m_status = FAILED;
return;
} else if (obj.has(STATUS) && obj.get(STATUS).equals(UNKNOWN)) {
m_status = UNKNOWN;
return;
}


m_status = obj.getString(STATUS);
if (FAILED.equalsIgnoreCase(m_status) && obj.has(USER_MESSAGE)) {
m_progress.setStatus(new Message(Message.ERROR, obj.getString(USER_MESSAGE)));
m_message = obj.getString(USER_MESSAGE);
} else if (PAUSED.equalsIgnoreCase(m_status)) {
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(SUSPEND_JOB_BYUSER, "Scan Id: " + m_scanId)));
m_message = Messages.getMessage(SUSPEND_JOB_BYUSER, "Scan Id: " + m_scanId);
} else if (m_status != null && !(m_status.equalsIgnoreCase(INQUEUE) || m_status.equalsIgnoreCase(RUNNING) || m_status.equalsIgnoreCase(PAUSING))) {
JSONArray array = m_scanProvider.getNonCompliantIssues(m_scanId);
m_totalFindings = 0;

for (int i = 0; i < array.length(); i++) {
JSONObject jobj = array.getJSONObject(i);
String sev = jobj.getString("Severity");
int count = jobj.getInt("N");

switch (sev.toLowerCase()) {
case "critical":
m_criticalFindings += count;
m_totalFindings += count;
break;
case "high":
m_highFindings += count;
m_totalFindings += count;
break;
case "medium":
m_mediumFindings += count;
m_totalFindings += count;
break;
case "low":
m_lowFindings += count;
m_totalFindings += count;
break;
case "informational":
m_infoFindings += count;
m_totalFindings += count;
break;
default:
m_totalFindings += count;
break;
}
}
setHasResult(true);
m_message = "";
} else if (RUNNING.equalsIgnoreCase(m_status)) m_message = "";
}
} catch (IOException | JSONException | NullPointerException e) {
m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_GETTING_DETAILS, e.getMessage())),
e);
m_status = FAILED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.hcl.appscan.sdk.scanners.dynamic.DASTConstants;
import com.hcl.appscan.sdk.utils.FileUtil;
import com.hcl.appscan.sdk.utils.ServiceUtil;
import org.apache.wink.json4j.JSONArray;
import org.apache.wink.json4j.JSONArtifact;
import org.apache.wink.json4j.JSONException;
Expand Down Expand Up @@ -59,28 +60,21 @@ public String createAndExecuteScan(String type, Map<String, String> params) {
HttpClient client = new HttpClient(m_authProvider.getProxy(), m_authProvider.getacceptInvalidCerts());

try {
HttpResponse response;
request_headers.put("Content-Type", "application/json");
request_headers.put("accept", "application/json");
String request_url;

if(type.equals(SASTConstants.STATIC_ANALYZER) && !params.containsKey(UPLOAD_DIRECT) && params.containsKey(OPEN_SOURCE_ONLY)) {
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(EXECUTING_SCAN, CoreConstants.SOFTWARE_COMPOSITION_ANALYZER)));
request_url = m_authProvider.getServer() + String.format(API_SCANNER, SCA);
} else {
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(EXECUTING_SCAN, params.get(CoreConstants.SCANNER_TYPE))));
request_url = m_authProvider.getServer() + String.format(API_SCANNER, type);
}

response = client.post(request_url,request_headers,params);

String request_url = m_authProvider.getServer() + String.format(API_SCANNER, type);

HttpResponse response = client.post(request_url,request_headers,params);
int status = response.getResponseCode();

JSONObject json = (JSONObject) response.getResponseBodyAsJSON();

if (status == HttpsURLConnection.HTTP_CREATED || status == HttpsURLConnection.HTTP_OK) {
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(CREATE_SCAN_SUCCESS)));
return json.getString(ID);
String scanId = json.getString(ID);
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(CREATE_SCAN_SUCCESS, type.toUpperCase(), scanId)));
String scanOverviewUrl = m_authProvider.getServer() + "/main/myapps/" + params.get(CoreConstants.APP_ID) + "/scans/" + scanId;
m_progress.setStatus(new Message(Message.INFO, Messages.getMessage(SCAN_OVERVIEW, type.toUpperCase(), scanOverviewUrl)));
return scanId;
} else if (json != null && json.has(MESSAGE)) {
String errorResponse = json.getString(MESSAGE);
if(json.has(FORMAT_PARAMS) && !json.isNull(FORMAT_PARAMS)) {
Expand Down Expand Up @@ -151,12 +145,12 @@ public JSONObject getScanDetails(String scanId) throws IOException, JSONExceptio
JSONObject obj = (JSONObject) response.getResponseBodyAsJSON();
JSONArray array = (JSONArray) obj.get(ITEMS);
if(array.isEmpty()) {
m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_GETTING_DETAILS, scanId)));
m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_GETTING_DETAILS_SCAN_ID, scanId)));
} else {
return (JSONObject) array.getJSONObject(0);
}
} else if (response.getResponseCode() == -1) {
m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_GETTING_DETAILS, scanId)));
m_progress.setStatus(new Message(Message.ERROR, Messages.getMessage(ERROR_GETTING_DETAILS_SCAN_ID, scanId)));
} else if (response.getResponseCode() != HttpsURLConnection.HTTP_BAD_REQUEST) {
JSONArtifact json = response.getResponseBodyAsJSON();
if (json != null && ((JSONObject)json).has(MESSAGE))
Expand Down
Loading
Loading