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

Support scan ASCA command (AST-42348, AST-69533) #373

Merged
merged 20 commits into from
Oct 8, 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
19 changes: 19 additions & 0 deletions src/main/java/com/checkmarx/ast/asca/Error.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.checkmarx.ast.asca;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Value;

@Value
public class Error {
public int code;
public String description;

@JsonCreator
public Error(
@JsonProperty("code") int code,
@JsonProperty("description") String description)
{
this.code = code;
this.description = description;
}
}
53 changes: 53 additions & 0 deletions src/main/java/com/checkmarx/ast/asca/ScanDetail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.checkmarx.ast.asca;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.ToString;
import lombok.Value;

@Value
@ToString(callSuper = true)
@JsonDeserialize()
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ScanDetail {

int ruleID;
String language;
String ruleName;
String severity;
String fileName;
int line;
String problematicLine;
int length;
String remediationAdvise;
String description;

@JsonCreator
public ScanDetail(
@JsonProperty("rule_id") int ruleID,
@JsonProperty("language") String language,
@JsonProperty("rule_name") String ruleName,
@JsonProperty("severity") String severity,
@JsonProperty("file_name") String fileName,
@JsonProperty("line") int line,
@JsonProperty("problematicLine") String problematicLine,
@JsonProperty("length") int length,
@JsonProperty("remediationAdvise") String remediationAdvise,
@JsonProperty("description") String description
) {
this.ruleID = ruleID;
this.language = language;
this.ruleName = ruleName;
this.severity = severity;
this.fileName = fileName;
this.line = line;
this.problematicLine = problematicLine;
this.length = length;
this.remediationAdvise = remediationAdvise;
this.description = description;
}
}
46 changes: 46 additions & 0 deletions src/main/java/com/checkmarx/ast/asca/ScanResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.checkmarx.ast.asca;

import com.checkmarx.ast.utils.JsonParser;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.ToString;
import lombok.Value;

import java.util.List;

@Value
@ToString(callSuper = true)
@JsonDeserialize()
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ScanResult {

String requestId;
boolean status;
String message;
List<ScanDetail> scanDetails;
Error error;

@JsonCreator
public ScanResult(
@JsonProperty("request_id") String requestId,
@JsonProperty("status") boolean status,
@JsonProperty("message") String message,
@JsonProperty("scan_details") List<ScanDetail> scanDetails,
@JsonProperty("error") Error error
) {
this.requestId = requestId;
this.status = status;
this.message = message;
this.scanDetails = scanDetails;
this.error = error;
}

public static <T> T fromLine(String line) {
return JsonParser.parse(line, TypeFactory.defaultInstance().constructType(ScanResult.class));
}
}
5 changes: 3 additions & 2 deletions src/main/java/com/checkmarx/ast/project/Project.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.checkmarx.ast.project;

import com.checkmarx.ast.utils.JsonParser;
import com.checkmarx.ast.wrapper.CxBaseObject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
Expand Down Expand Up @@ -36,10 +37,10 @@ public Project(@JsonProperty("ID") String id,
}

public static <T> T fromLine(String line) {
return parse(line, TypeFactory.defaultInstance().constructType(Project.class));
return JsonParser.parse(line, TypeFactory.defaultInstance().constructType(Project.class));
}

public static <T> List<T> listFromLine(String line) {
return parse(line, TypeFactory.defaultInstance().constructCollectionType(List.class, Project.class));
return JsonParser.parse(line, TypeFactory.defaultInstance().constructCollectionType(List.class, Project.class));
}
}
5 changes: 3 additions & 2 deletions src/main/java/com/checkmarx/ast/scan/Scan.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.checkmarx.ast.scan;

import com.checkmarx.ast.utils.JsonParser;
import com.checkmarx.ast.wrapper.CxBaseObject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
Expand Down Expand Up @@ -43,10 +44,10 @@ public Scan(@JsonProperty("ID") String id, @JsonProperty("ProjectID") String pro
}

public static <T> T fromLine(String line) {
return parse(line, TypeFactory.defaultInstance().constructType(Scan.class));
return JsonParser.parse(line, TypeFactory.defaultInstance().constructType(Scan.class));
}

public static <T> List<T> listFromLine(String line) {
return parse(line, TypeFactory.defaultInstance().constructCollectionType(List.class, Scan.class));
return JsonParser.parse(line, TypeFactory.defaultInstance().constructCollectionType(List.class, Scan.class));
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/checkmarx/ast/tenant/TenantSetting.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.checkmarx.ast.tenant;

import com.checkmarx.ast.utils.JsonParser;
import com.checkmarx.ast.wrapper.CxBaseObject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
Expand Down Expand Up @@ -31,7 +32,7 @@ public TenantSetting(@JsonProperty("key") String key, @JsonProperty("value") Str
}

public static <T> List<T> listFromLine(String line) {
return CxBaseObject.parse(line,
return JsonParser.parse(line,
TypeFactory.defaultInstance()
.constructCollectionType(List.class, TenantSetting.class));
}
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/com/checkmarx/ast/utils/JsonParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.checkmarx.ast.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;

public class JsonParser {
public static <T> T parse(String line, JavaType type) {
T result = null;
if (!StringUtils.isBlank(line) && isValidJSON(line)) {
try {
result = new ObjectMapper().readValue(line, type);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return result;
}

private static boolean isValidJSON(final String json) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(json);
return true;
} catch (IOException e) {
return false;
}
}

}
22 changes: 0 additions & 22 deletions src/main/java/com/checkmarx/ast/wrapper/CxBaseObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,4 @@ protected CxBaseObject(@JsonProperty("ID") String id,
this.updatedAt = updatedAt;
this.tags = tags;
}

public static <T> T parse(String line, JavaType type) {
T result = null;
if (!StringUtils.isBlank(line) && isValidJSON(line)) {
try {
result = new ObjectMapper().readValue(line, type);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return result;
}

public static boolean isValidJSON(final String json) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(json);
return true;
} catch (IOException e) {
return false;
}
}
}
5 changes: 4 additions & 1 deletion src/main/java/com/checkmarx/ast/wrapper/CxConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public final class CxConstants {
static final String SUB_CMD_SHOW = "show";
static final String RESULTS_BFL_SUB_CMD = "bfl";
static final String SUB_CMD_LIST = "list";
static final String SUB_CMD_ASCA = "asca";
static final String SUB_CMD_CREATE = "create";
static final String SUB_CMD_CANCEL = "cancel";
static final String CMD_TRIAGE = "triage";
Expand All @@ -50,7 +51,9 @@ public final class CxConstants {
static final String CWE_ID = "--cwe-id";
static final String LANGUAGE = "--language";
static final String VULNERABILITY_TYPE = "--vulnerability-type";
static final String FILE_SOURCES = "--file";
static final String FILE = "--file";
static final String FILE_SOURCE = "--file-source";
static final String ASCA_LATEST_VERSION = "--asca-latest-version";
static final String ADDITONAL_PARAMS = "--additional-params";
static final String ENGINE = "--engine";
static final String SUB_CMD_KICS_REALTIME = "kics-realtime";
Expand Down
33 changes: 31 additions & 2 deletions src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.checkmarx.ast.wrapper;

import com.checkmarx.ast.asca.ScanResult;
import com.checkmarx.ast.codebashing.CodeBashing;
import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults;
import com.checkmarx.ast.learnMore.LearnMore;
Expand All @@ -12,6 +13,7 @@
import com.checkmarx.ast.results.result.Node;
import com.checkmarx.ast.scan.Scan;
import com.checkmarx.ast.tenant.TenantSetting;
import com.checkmarx.ast.utils.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.TypeFactory;
Expand Down Expand Up @@ -216,6 +218,33 @@ public List<Project> projectList(String filter) throws IOException, InterruptedE
return Execution.executeCommand(withConfigArguments(arguments), logger, Project::listFromLine);
}

public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String agent) throws IOException, InterruptedException, CxException {
this.logger.info("Fetching ASCA scanResult");

List<String> arguments = new ArrayList<>();
arguments.add(CxConstants.CMD_SCAN);
arguments.add(CxConstants.SUB_CMD_ASCA);
arguments.add(CxConstants.FILE_SOURCE);
arguments.add(fileSource);
if (ascaLatestVersion) {
arguments.add(CxConstants.ASCA_LATEST_VERSION);
}

appendAgentToArguments(agent, arguments);

return Execution.executeCommand(withConfigArguments(arguments), logger, ScanResult::fromLine);
}

private static void appendAgentToArguments(String agent, List<String> arguments) {
arguments.add(CxConstants.AGENT);
if (agent != null && !agent.isEmpty()){
arguments.add(agent);
}
else{
arguments.add("CLI-Java-Wrapper");
}
}

public List<String> projectBranches(@NonNull UUID projectId, String filter)
throws CxException, IOException, InterruptedException {
this.logger.info("Fetching the branches for project id {} using the filter: {}", projectId, filter);
Expand All @@ -229,7 +258,7 @@ public List<String> projectBranches(@NonNull UUID projectId, String filter)

return Execution.executeCommand(withConfigArguments(arguments),
logger,
line -> CxBaseObject.parse(line, BRANCHES_TYPE));
line -> JsonParser.parse(line, BRANCHES_TYPE));
}

public List<CodeBashing> codeBashingList(@NonNull String cweId, @NonNull String language, @NonNull String queryName) throws IOException, InterruptedException, CxException {
Expand Down Expand Up @@ -336,7 +365,7 @@ public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String
List<String> arguments = new ArrayList<>();
arguments.add(CxConstants.CMD_SCAN);
arguments.add(CxConstants.SUB_CMD_KICS_REALTIME);
arguments.add(CxConstants.FILE_SOURCES);
arguments.add(CxConstants.FILE);
arguments.add(fileSources);
arguments.add(CxConstants.ADDITONAL_PARAMS);
arguments.add(additionalParams);
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/com/checkmarx/ast/wrapper/Execution.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.checkmarx.ast.wrapper;

import org.slf4j.Logger;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
Expand Down Expand Up @@ -49,7 +50,7 @@ static <T> T executeCommand(List<String> arguments,
stringBuilder.append(line).append(LINE_SEPARATOR);
T parsedLine = lineParser.apply(line);
if (parsedLine != null) {
if (areAllFieldsNotNull(parsedLine)) {
if (areAllFieldsNotNull(parsedLine) || isAscaRequest(arguments)) {
executionResult = parsedLine;
}
}
Expand All @@ -62,6 +63,10 @@ static <T> T executeCommand(List<String> arguments,
}
}

public static boolean isAscaRequest(List<String> arguments) {
return (arguments.size() >= 3 && arguments.get(1).equals("scan") && arguments.get(2).equals("asca"));
}

private static boolean areAllFieldsNotNull(Object obj) {
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
Expand All @@ -75,6 +80,7 @@ private static boolean areAllFieldsNotNull(Object obj) {
}
return true;
}

static String executeCommand(List<String> arguments,
Logger logger,
String directory,
Expand Down
Loading
Loading