diff --git a/pom.xml b/pom.xml index 066f32cb..159ce26c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ org.whitesource wss-agent-parent - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT pom White Source agent API @@ -29,7 +29,7 @@ scm:git:git@github.com:whitesource/agents.git scm:git:git@github.com:whitesource/agents.git git@github.com:whitesource/agents.git - release-tag-2.9.9.44 + release-tag-2.9.9.86 https://github.com/whitesource/agents/issues @@ -59,7 +59,7 @@ 4.5.13 1.13 2.9.0 - 2.9.0 + 2.10.1 4.13.2 UTF-8 diff --git a/wss-agent-api/pom.xml b/wss-agent-api/pom.xml index 11c985d7..2fbac366 100644 --- a/wss-agent-api/pom.xml +++ b/wss-agent-api/pom.xml @@ -4,7 +4,7 @@ org.whitesource wss-agent-parent - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT wss-agent-api jar @@ -63,4 +63,4 @@ - \ No newline at end of file + diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/APIConstants.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/APIConstants.java index cc6aaf58..e133984f 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/APIConstants.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/APIConstants.java @@ -52,6 +52,7 @@ public final class APIConstants { public static final String EXTRA_PROPERTIES = "extraProperties"; public static final String SCAN_SUMMARY_INFO = "scanSummaryInfo"; public static final String CONTRIBUTIONS = "contributions"; + public static final String IDENTIFIER = "identifier"; public static final int MAX_POST_SIZE = 209715200; //= 200 MegaByte; /* --- Messages --- */ diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AppFlags.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AppFlags.java new file mode 100644 index 00000000..67d370cc --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AppFlags.java @@ -0,0 +1,20 @@ +package org.whitesource.agent.api.dispatch; + +public enum AppFlags { + UPLOAD_SCA_LOGS("UPLOAD_SCA_LOGS"), + ASYNC_CHECK_POLICIES_ENABLED("ASYNC_CHECK_POLICIES_ENABLED"), + SBT_SUPPORT_ENABLED("SBT_SUPPORT_ENABLED"), + AI_BOM_SUPPORT_ENABLED("AI_BOM_SUPPORT_ENABLED"), + SWIFT_SUPPORT_ENABLED("SWIFT_SUPPORT_ENABLED"), + REACHABILITY_SUPPORT_ENABLED("REACHABILITY_SUPPORT_ENABLED"), + REACHABILITY_SUPPORT_LANGUAGES("REACHABILITY_SUPPORT_LANGUAGES"); + private final String value; + + AppFlags(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceRequest.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceRequest.java new file mode 100644 index 00000000..8ed458ed --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceRequest.java @@ -0,0 +1,185 @@ +package org.whitesource.agent.api.dispatch; + +import org.whitesource.agent.api.model.AgentProjectInfo; +import org.whitesource.agent.api.model.ScanSummaryInfo; + +import java.util.Collection; + +public class AsyncCheckPolicyComplianceRequest extends BaseRequest { + + /* --- Static Members --- */ + + private static final long serialVersionUID = 925625972820830788L; + + /* --- Members --- */ + + /** + * When set to true, check that all dependencies sent to WhiteSource comply with organization policies. + * When set to false, check that the added dependencies sent to WhiteSource comply with organization policies. + */ + protected boolean forceCheckAllDependencies; + /** + * When set to true, get vulnerabilities for all dependencies without updating project. + * When set to false, will not get vulnerabilities for all dependencies. + */ + protected boolean populateVulnerabilities; + + /* --- Constructors --- */ + + /** + * Default constructor + */ + public AsyncCheckPolicyComplianceRequest() { + super(RequestType.ASYNC_CHECK_POLICY_COMPLIANCE); + forceCheckAllDependencies = false; + populateVulnerabilities = false; + } + + /** + * Constructor + * + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Check policies for the all the Inventory or just for the new one. + */ + public AsyncCheckPolicyComplianceRequest(Collection projects, boolean forceCheckAllDependencies) { + this(); + this.projects = projects; + this.forceCheckAllDependencies = forceCheckAllDependencies; + } + + /** + * Constructor + * + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Check policies for the all the Inventory or just for the new one. + * @param populateVulnerabilities get vulnerabilities for each dependency without updating project + */ + public AsyncCheckPolicyComplianceRequest(Collection projects, boolean forceCheckAllDependencies, boolean populateVulnerabilities) { + this(); + this.projects = projects; + this.forceCheckAllDependencies = forceCheckAllDependencies; + this.populateVulnerabilities = populateVulnerabilities; + } + + /** + * Constructor + * + * @param orgToken WhiteSource organization token. + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Check policies for the all the Inventory or just for the new one. + * @param populateVulnerabilities get vulnerabilities for each dependency without updating project + */ + public AsyncCheckPolicyComplianceRequest(String orgToken, Collection projects, boolean forceCheckAllDependencies, boolean populateVulnerabilities) { + this(projects, forceCheckAllDependencies, populateVulnerabilities); + this.orgToken = orgToken; + + } + + /** + * Constructor + * + * @param orgToken WhiteSource organization token. + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Check policies for the all the Inventory or just for the new one. + */ + public AsyncCheckPolicyComplianceRequest(String orgToken, Collection projects, boolean forceCheckAllDependencies) { + this(projects, forceCheckAllDependencies); + this.orgToken = orgToken; + } + + /** + * Constructor + * + * @param orgToken Organization token uniquely identifying the account at white source. + * @param product The product name or token to update. + * @param productVersion The product version. + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Boolean to check new data only or not. + * @param userKey user key uniquely identifying the account at white source. + * @param requesterEmail Email of the WhiteSource user that requests to update WhiteSource. + * @param logData list of FSA's log data events + * @param productToken The product token + */ + public AsyncCheckPolicyComplianceRequest(String orgToken, String product, String productVersion, Collection projects, boolean forceCheckAllDependencies, + String userKey, String requesterEmail, String logData, String productToken) { + this(orgToken, projects, forceCheckAllDependencies); + this.product = product; + this.productVersion = productVersion; + this.userKey = userKey; + this.requesterEmail = requesterEmail; + this.logData = logData; + this.productToken = productToken; + } + + /** + * Constructor + * + * @param orgToken Organization token uniquely identifying the account at white source. + * @param product The product name or token to update. + * @param productVersion The product version. + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Boolean to check new data only or not. + * @param userKey user key uniquely identifying the account at white source. + * @param requesterEmail Email of the WhiteSource user that requests to update WhiteSource. + * @param logData list of FSA's log data events + * @param productToken The product token + * @param scanSummaryInfo Summary statistics for each step in Unified Agent + */ + public AsyncCheckPolicyComplianceRequest(String orgToken, String product, String productVersion, Collection projects, boolean forceCheckAllDependencies, + String userKey, String requesterEmail, String logData, String productToken, ScanSummaryInfo scanSummaryInfo) { + this(orgToken, projects, forceCheckAllDependencies); + this.product = product; + this.productVersion = productVersion; + this.userKey = userKey; + this.requesterEmail = requesterEmail; + this.logData = logData; + this.productToken = productToken; + this.scanSummaryInfo = scanSummaryInfo; + } + + /** + * Constructor + * + * @param orgToken Organization token uniquely identifying the account at white source. + * @param product The product name or token to update. + * @param productVersion The product version. + * @param projects Open Source usage statement to check against policies. + * @param forceCheckAllDependencies Boolean to check new data only or not. + * @param userKey user key uniquely identifying the account at white source. + * @param requesterEmail Email of the WhiteSource user that requests to update WhiteSource. + * @param logData list of FSA's log data events + * @param productToken The product token + * @param scanSummaryInfo Summary statistics for each step in Unified Agent + * @param populateVulnerabilities get vulnerabilities for each dependency without updating project + */ + public AsyncCheckPolicyComplianceRequest(String orgToken, String product, String productVersion, Collection projects, boolean forceCheckAllDependencies, + boolean populateVulnerabilities, String userKey, String requesterEmail, String logData, String productToken, ScanSummaryInfo scanSummaryInfo) { + this(orgToken, projects, forceCheckAllDependencies); + this.product = product; + this.productVersion = productVersion; + this.userKey = userKey; + this.requesterEmail = requesterEmail; + this.logData = logData; + this.productToken = productToken; + this.scanSummaryInfo = scanSummaryInfo; + this.populateVulnerabilities = populateVulnerabilities; + } + + /* --- Getters / Setters --- */ + + public boolean isForceCheckAllDependencies() { + return forceCheckAllDependencies; + } + + public void setForceCheckAllDependencies(boolean forceCheckAllDependencies) { + this.forceCheckAllDependencies = forceCheckAllDependencies; + } + + public boolean isPopulateVulnerabilities() { + return populateVulnerabilities; + } + + public void setPopulateVulnerabilities(boolean populateVulnerabilities) { + this.populateVulnerabilities = populateVulnerabilities; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResponseRequest.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResponseRequest.java new file mode 100644 index 00000000..52b0178b --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResponseRequest.java @@ -0,0 +1,30 @@ +package org.whitesource.agent.api.dispatch; + +public class AsyncCheckPolicyComplianceResponseRequest extends BaseRequest { + + /* --- Static Members --- */ + + private static final long serialVersionUID = 7267771318691275351L; + + /* --- Members --- */ + + protected String identifier; + + /** + * Default constructor + */ + public AsyncCheckPolicyComplianceResponseRequest(String identifier) { + super(RequestType.ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE); + this.identifier = identifier; + } + + public AsyncCheckPolicyComplianceResponseRequest() {super(RequestType.ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE);} + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResponseResult.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResponseResult.java new file mode 100644 index 00000000..9f97589f --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResponseResult.java @@ -0,0 +1,17 @@ +package org.whitesource.agent.api.dispatch; + +public class AsyncCheckPolicyComplianceResponseResult extends CheckPolicyComplianceResult { + + /* --- Static Members --- */ + + private static final long serialVersionUID = -9005803185728108040L; + + /* --- Members --- */ + + + /** + * Default constructor + */ + public AsyncCheckPolicyComplianceResponseResult() { + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResult.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResult.java new file mode 100644 index 00000000..aa7f378e --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceResult.java @@ -0,0 +1,28 @@ +package org.whitesource.agent.api.dispatch; + +import java.io.Serializable; + +public class AsyncCheckPolicyComplianceResult extends BaseResult { + + /* --- Static Members --- */ + + private static final long serialVersionUID = 7236121775887105115L; + + /* --- Members --- */ + + private String identifier; + + /** + * Default constructor + */ + public AsyncCheckPolicyComplianceResult() { + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceStatusRequest.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceStatusRequest.java new file mode 100644 index 00000000..1b9caf16 --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceStatusRequest.java @@ -0,0 +1,32 @@ +package org.whitesource.agent.api.dispatch; + +public class AsyncCheckPolicyComplianceStatusRequest extends BaseRequest { + + /* --- Static Members --- */ + + private static final long serialVersionUID = -3011749510680068374L; + + /* --- Members --- */ + + protected String identifier; + + /** + * Default constructor + */ + public AsyncCheckPolicyComplianceStatusRequest(String identifier) { + super(RequestType.ASYNC_CHECK_POLICY_COMPLIANCE_STATUS); + this.identifier = identifier; + } + + public AsyncCheckPolicyComplianceStatusRequest() { + super(RequestType.ASYNC_CHECK_POLICY_COMPLIANCE_STATUS); + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceStatusResult.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceStatusResult.java new file mode 100644 index 00000000..a1053f4a --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/AsyncCheckPolicyComplianceStatusResult.java @@ -0,0 +1,33 @@ +package org.whitesource.agent.api.dispatch; + +import java.io.Serializable; + +public class AsyncCheckPolicyComplianceStatusResult implements Serializable { + + /* --- Static Members --- */ + + private static final long serialVersionUID = -2767549958986147436L; + + /* --- Members --- */ + + // stores the sha1 of the euaDep.json used to calculate the vulnerabilities + private String status; + + /** + * Default constructor + */ + public AsyncCheckPolicyComplianceStatusResult() { + } + + public AsyncCheckPolicyComplianceStatusResult(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/ConfigurationResult.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/ConfigurationResult.java index 5dd95140..9c8f0f1a 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/ConfigurationResult.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/ConfigurationResult.java @@ -1,5 +1,10 @@ package org.whitesource.agent.api.dispatch; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + /** * Created by anna.rozin */ @@ -32,20 +37,37 @@ public class ConfigurationResult extends BaseResult { private FsaConfiguration fsaConfiguration; + private Map flags; + + private Collection entitlements; + /* --- Constructors --- */ - public ConfigurationResult(){ + public ConfigurationResult() { fsaConfiguration = new FsaConfiguration(); + flags = new HashMap<>(); + entitlements = new ArrayList<>(); + } + + public ConfigurationResult(boolean checkPolicies, boolean forceCheckAllDependencies, boolean forceUpdate, String includes, + String excludes) { + this(); + this.checkPolicies = checkPolicies; + this.forceCheckAllDependencies = forceCheckAllDependencies; + this.forceUpdate = forceUpdate; + this.includes = includes; + this.excludes = excludes; } public ConfigurationResult(boolean checkPolicies, boolean forceCheckAllDependencies, boolean forceUpdate, String includes, - String excludes){ + String excludes, Map flags) { this(); this.checkPolicies = checkPolicies; this.forceCheckAllDependencies = forceCheckAllDependencies; this.forceUpdate = forceUpdate; this.includes = includes; this.excludes = excludes; + this.flags = flags; } @@ -154,4 +176,20 @@ public FsaConfiguration getFsaConfiguration() { public void setFsaConfiguration(FsaConfiguration fsaConfiguration) { this.fsaConfiguration = fsaConfiguration; } + + public void setFlags(Map flags) { + this.flags = flags; + } + + public Map getFlags() { + return this.flags; + } + + public Collection getEntitlements() { + return entitlements; + } + + public void setEntitlements(Collection entitlements) { + this.entitlements = entitlements; + } } diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/EntitlementType.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/EntitlementType.java new file mode 100644 index 00000000..a90f09ef --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/EntitlementType.java @@ -0,0 +1,26 @@ +package org.whitesource.agent.api.dispatch; + +public enum EntitlementType { + CORE("CORE"), + API_1("API_1"), + API_2("API_2"), + ESSENTIALS("ESSENTIALS"), + SCA("SCA"), + SAST("SAST"), + CN("CN"), + LLM("LLM"), + IMG("IMG"), + IAC("IAC"), + CONTAINER_SECURITY("CONTAINER_SECURITY"); + + private final String value; + + EntitlementType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} + diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestFactory.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestFactory.java index 7255d8da..2c5e73a8 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestFactory.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestFactory.java @@ -472,6 +472,21 @@ public CheckPolicyComplianceRequest newCheckPolicyComplianceRequest(CheckPolicyC return (CheckPolicyComplianceRequest) prepareRequest(request); } + public AsyncCheckPolicyComplianceRequest newAsyncCheckPolicyComplianceRequest(AsyncCheckPolicyComplianceRequest request) { + return (AsyncCheckPolicyComplianceRequest) prepareRequest(request); + + } + + public AsyncCheckPolicyComplianceStatusRequest newAsyncCheckPolicyComplianceStatusRequest(AsyncCheckPolicyComplianceStatusRequest request) { + return (AsyncCheckPolicyComplianceStatusRequest) prepareRequest(request); + + } + + public AsyncCheckPolicyComplianceResponseRequest newAsyncCheckPolicyComplianceResponseRequest(AsyncCheckPolicyComplianceResponseRequest request) { + return (AsyncCheckPolicyComplianceResponseRequest) prepareRequest(request); + + } + /** * Create new Dependency Data request. * @@ -710,4 +725,5 @@ public String getPluginVersion() { return pluginVersion; } + } diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestType.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestType.java index 891f245b..f4f66f66 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestType.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/RequestType.java @@ -1,12 +1,12 @@ /** * Copyright (C) 2012 White Source Ltd. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,18 +17,23 @@ /** * Enumeration of the service available methods. - * + * * @author Edo.Shor */ public enum RequestType { - UPDATE ("UPDATE"), - CHECK_POLICIES ("CHECK_POLICIES"), - CHECK_POLICY_COMPLIANCE ("CHECK_POLICY_COMPLIANCE"), - CHECK_VULNERABILITIES ("CHECK_VULNERABILITIES"), - GET_CLOUD_NATIVE_VULNERABILITIES ("GET_CLOUD_NATIVE_VULNERABILITIES"), - GET_DEPENDENCY_DATA ("GET_DEPENDENCY_DATA"), - SUMMARY_SCAN ("SUMMARY_SCAN"), - GET_CONFIGURATION ("GET_CONFIGURATION"); + UPDATE("UPDATE"), + CHECK_POLICIES("CHECK_POLICIES"), + CHECK_POLICY_COMPLIANCE("CHECK_POLICY_COMPLIANCE"), + CHECK_VULNERABILITIES("CHECK_VULNERABILITIES"), + GET_CLOUD_NATIVE_VULNERABILITIES("GET_CLOUD_NATIVE_VULNERABILITIES"), + GET_DEPENDENCY_DATA("GET_DEPENDENCY_DATA"), + SUMMARY_SCAN("SUMMARY_SCAN"), + GET_CONFIGURATION("GET_CONFIGURATION"), + ASYNC_CHECK_POLICY_COMPLIANCE ("ASYNC_CHECK_POLICY_COMPLIANCE"), + ASYNC_CHECK_POLICY_COMPLIANCE_STATUS ("ASYNC_CHECK_POLICY_COMPLIANCE_STATUS"), + ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE ("ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE"), + + UPLOAD_SCA_LOGS("UPLOAD_SCA_LOGS"); private final String value; diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/UploadScaLogsRequest.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/UploadScaLogsRequest.java new file mode 100644 index 00000000..cef86007 --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/UploadScaLogsRequest.java @@ -0,0 +1,34 @@ +package org.whitesource.agent.api.dispatch; + +public class UploadScaLogsRequest extends BaseRequest { + + /* --- Static members --- */ + + private static final long serialVersionUID = -6634396300199014567L; + + /* --- Members --- */ + + + /* --- Constructors --- */ + + /** + * Default constructor + */ + public UploadScaLogsRequest() { + super(RequestType.UPLOAD_SCA_LOGS); + } + + /** + * Constructor + * + * @param orgToken Organization token uniquely identifying the account at white source. + * @param userKey user key uniquely identifying the account at white source. + * @param requesterEmail Email of the WhiteSource user that requests to update WhiteSource. + */ + public UploadScaLogsRequest(String orgToken, String userKey, String requesterEmail) { + this(); + this.orgToken = orgToken; + this.userKey = userKey; + this.requesterEmail = requesterEmail; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/UploadScaLogsResult.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/UploadScaLogsResult.java new file mode 100644 index 00000000..353fe847 --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/dispatch/UploadScaLogsResult.java @@ -0,0 +1,16 @@ +package org.whitesource.agent.api.dispatch; + +public class UploadScaLogsResult extends BaseResult { + + /* --- Static members --- */ + private static final long serialVersionUID = -8474225446757628208L; + /* --- Constructors ---*/ + + /*** + * default constructor + */ + public UploadScaLogsResult() { + super(); + } + +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/AgentProjectInfo.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/AgentProjectInfo.java index 82f18077..a4b4fcaa 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/AgentProjectInfo.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/AgentProjectInfo.java @@ -39,6 +39,7 @@ public class AgentProjectInfo implements Serializable { private Coordinates parentCoordinates; private Collection dependencies; + private Collection secretFindings; private String projectToken; @@ -60,6 +61,17 @@ public AgentProjectInfo() { projectTags = new ArrayList<>(); } + public AgentProjectInfo(AgentProjectInfo other) { + this.coordinates = other.coordinates; + this.parentCoordinates = other.parentCoordinates; + this.dependencies = other.dependencies != null ? new ArrayList<>(other.dependencies) : null; + this.secretFindings = other.secretFindings != null ? new ArrayList<>(other.secretFindings) : null; + this.projectToken = other.projectToken; + this.projectSetupStatus = other.projectSetupStatus; + this.projectSetupDescription = other.projectSetupDescription; + this.projectTags = other.projectTags != null ? new ArrayList<>(other.projectTags) : null; + this.viaLanguageName = other.viaLanguageName; + } /* --- Overridden methods --- */ @Override @@ -141,4 +153,13 @@ public String getViaLanguageName() { public void setViaLanguageName(String viaLanguageName) { this.viaLanguageName = viaLanguageName; } + + public Collection getSecretFindings() { + return secretFindings; + } + + public void setSecretFindings(Collection secretFindings) { + this.secretFindings = secretFindings; + } + } diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/Code.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/Code.java new file mode 100644 index 00000000..d2f85107 --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/Code.java @@ -0,0 +1,14 @@ +package org.whitesource.agent.api.model; + +import java.util.List; + +public class Code { + private List lines; + public List getLines() { + return lines; + } + public void setLines(List lines) { + this.lines = lines; + } + +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyInfo.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyInfo.java index b588770a..8989a609 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyInfo.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyInfo.java @@ -1,522 +1,557 @@ -/** - * Copyright (C) 2012 White Source Ltd. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.whitesource.agent.api.model; - -import org.apache.commons.lang.StringUtils; -import org.whitesource.agent.api.APIConstants; -import org.whitesource.agent.via.api.VulnerabilityAnalysisResult; - -import java.io.Serializable; -import java.util.*; - -/** - * WhiteSource Model for a project's dependency - * - * @author tom.shapira - */ -public class DependencyInfo implements Serializable { - - /* --- Static members --- */ - - private static final long serialVersionUID = -6212622409560068635L; - - /* --- Members --- */ - - private String groupId; - private String artifactId; - private String version; - private String type; - private String classifier; - private String scope; - private String sha1; - private String fullHash; - private String commentlessSha1; - private String noNewLinesSha1; - private String otherPlatformSha1; - private String systemPath; - private boolean optional; - private Collection children; - private Date lastModified; - private String filename; - private DependencyType dependencyType; - private DependencyHintsInfo hints; - private Map checksums; - private VulnerabilityAnalysisResult vulnerabilityAnalysisResult; - private String commit; - private String dependencyFile; - private String additionalSha1; - private String architecture; - private String languageVersion; - private boolean deduped; - private OSInfo osInfo; - private AnalysisInputs analysisInputs; - private String sourcePackageName; - private String release; - - /* --- Constructors --- */ - - /** - * Default constructor - */ - public DependencyInfo() { - } - - /** - * Constructor - * - * @param groupId - the dependency groupId - * @param artifactId - the dependency artifactId - * @param version - the dependency version - */ - public DependencyInfo(String groupId, String artifactId, String version) { - this(); - this.groupId = groupId; - this.version = version; - this.artifactId = artifactId; - } - - /** - * Constructor - * - * @param sha1 - the dependency sha1 - */ - public DependencyInfo(String sha1) { - this(); - setSha1(sha1); - } - - /** - * Constructor - * - * @param sha1 - the dependency sha1 - * @param fullHash - the dependency fullHash - */ - public DependencyInfo(String sha1, String fullHash) { - this(sha1); - setFullHash(fullHash); - } - - /* --- Overridden methods --- */ - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("DependencyInfo@").append(Integer.toHexString(hashCode())) - .append("[") - .append("groupId= ").append(groupId).append(",") - .append("artifactId= ").append(artifactId).append(",") - .append("version= ").append(version).append(",") - .append("filename= ").append(filename).append(",") - .append("dependencyType= ").append(dependencyType) - .append(" ]"); - - return sb.toString(); - } - - @Override - public final boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof DependencyInfo)) return false; - - DependencyInfo that = (DependencyInfo) o; - - if (StringUtils.isNotEmpty(sha1)) { - return sha1.equals(that.sha1); - } else if (StringUtils.isNotEmpty(that.sha1)) { - return false; - } - if (optional != that.optional) return false; - if (artifactId != null ? !artifactId.equals(that.artifactId) : that.artifactId != null) return false; - if (classifier != null ? !classifier.equals(that.classifier) : that.classifier != null) return false; - if (groupId != null ? !groupId.equals(that.groupId) : that.groupId != null) return false; - if (scope != null ? !scope.equals(that.scope) : that.scope != null) return false; - if (type != null ? !type.equals(that.type) : that.type != null) return false; - if (version != null ? !version.equals(that.version) : that.version != null) return false; - if (filename != null ? !filename.equals(that.filename) : that.filename != null) return false; - if (commit != null ? !commit.equals(that.commit) : that.commit != null) return false; - if (dependencyType != null ? !dependencyType.equals(that.dependencyType) : that.dependencyType != null) - return false; - if (systemPath != null ? !systemPath.equals(that.systemPath) : that.systemPath != null) return false; - if (dependencyFile != null ? !dependencyFile.equals(that.dependencyFile) : that.dependencyFile != null) - return false; - if (vulnerabilityAnalysisResult != null ? - !vulnerabilityAnalysisResult.equals(that.vulnerabilityAnalysisResult) : - that.vulnerabilityAnalysisResult != null) - return false; - if (sourcePackageName != null ? !sourcePackageName.equals(that.sourcePackageName) : that.sourcePackageName != null) - return false; - if (release != null ? !release.equals(that.release) : that.release != null) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = APIConstants.HASH_CODE_SEED; - result = APIConstants.HASH_CODE_FACTOR * result + (groupId != null ? groupId.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (artifactId != null ? artifactId.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (version != null ? version.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (type != null ? type.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (classifier != null ? classifier.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (scope != null ? scope.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (sha1 != null ? sha1.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (optional ? 1 : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (filename != null ? filename.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (dependencyType != null ? dependencyType.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (systemPath != null ? systemPath.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (dependencyFile != null ? dependencyFile.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (vulnerabilityAnalysisResult != null ? vulnerabilityAnalysisResult.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (commit != null ? commit.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (additionalSha1 != null ? additionalSha1.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (sourcePackageName != null ? sourcePackageName.hashCode() : 0); - result = APIConstants.HASH_CODE_FACTOR * result + (release != null ? release.hashCode() : 0); - return result; - } - - /* --- Public methods --- */ - - - public String getGroupId() { - return groupId; - } - - public void setGroupId(String groupId) { - this.groupId = groupId; - } - - public String getArtifactId() { - return artifactId; - } - - public void setArtifactId(String artifactId) { - this.artifactId = artifactId; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getClassifier() { - return classifier; - } - - public void setClassifier(String classifier) { - this.classifier = classifier; - } - - public String getScope() { - return scope; - } - - public void setScope(String scope) { - this.scope = scope; - } - - public String getSha1() { - return sha1; - } - - public void setSha1(String sha1) { - this.sha1 = sha1; - addChecksum(ChecksumType.SHA1, sha1); - } - - public String getSystemPath() { - return systemPath; - } - - public void setSystemPath(String systemPath) { - this.systemPath = systemPath; - } - - public boolean getOptional() { - return optional; - } - - public boolean isOptional() { - return optional; - } - - public void setOptional(boolean optional) { - this.optional = optional; - } - - public Collection getChildren() { - if (children == null) { - children = new LinkedList<>(); - } - return children; - } - - public void setChildren(Collection children) { - this.children = children; - } - - public void addChild(DependencyInfo child) { - if (children == null) { - children = new LinkedList<>(); - } - children.add(child); - } - - public boolean hasChildren() { - return children != null && children.size() != 0; - } - - public Date getLastModified() { - return lastModified; - } - - public void setLastModified(Date lastModified) { - this.lastModified = lastModified; - } - - public String getCommentlessSha1() { - return commentlessSha1; - } - - public void setCommentlessSha1(String commentlessSha1) { - this.commentlessSha1 = commentlessSha1; - addChecksum(ChecksumType.SHA1_NO_COMMENTS, commentlessSha1); - } - - public String getNoNewLinesSha1() { - return noNewLinesSha1; - } - - public void setNoNewLinesSha1(String noNewLinesSha1) { - this.noNewLinesSha1 = noNewLinesSha1; - } - - public String getOtherPlatformSha1() { - return otherPlatformSha1; - } - - public void setOtherPlatformSha1(String otherPlatformSha1) { - this.otherPlatformSha1 = otherPlatformSha1; - addChecksum(ChecksumType.SHA1_OTHER_PLATFORM, otherPlatformSha1); - } - - public String getFullHash() { - return fullHash; - } - - public void setFullHash(String fullHash) { - this.fullHash = fullHash; - addChecksum(ChecksumType.SHA1_SUPER_HASH, fullHash); - } - - public String getFilename() { - return filename; - } - - public void setFilename(String filename) { - this.filename = filename; - } - - public DependencyType getDependencyType() { - return dependencyType; - } - - public void setDependencyType(DependencyType dependencyType) { - this.dependencyType = dependencyType; - } - - public DependencyHintsInfo getHints() { - return hints; - } - - public void setHints(DependencyHintsInfo hints) { - this.hints = hints; - } - - public Map getChecksums() { - if (checksums == null) { - checksums = new TreeMap<>(); - } - return checksums; - } - - public void setChecksums(Map checksums) { - this.checksums = checksums; - } - - public void addChecksum(ChecksumType checksumType, String checksum) { - if (StringUtils.isNotBlank(checksum)) { - if (checksums == null) { - checksums = new TreeMap<>(); - } - checksums.put(checksumType, checksum); - } - } - - public boolean hasChecksum() { - return checksums != null && checksums.size() != 0; - } - - public VulnerabilityAnalysisResult getVulnerabilityAnalysisResult() { - return vulnerabilityAnalysisResult; - } - - public void setVulnerabilityAnalysisResult(VulnerabilityAnalysisResult vulnerabilityAnalysisResult) { - this.vulnerabilityAnalysisResult = vulnerabilityAnalysisResult; - } - - public String getCommit() { - return commit; - } - - public void setCommit(String commit) { - this.commit = commit; - } - - public String getDependencyFile() { - return dependencyFile; - } - - public void setDependencyFile(String dependencyFile) { - this.dependencyFile = dependencyFile; - } - - public String getAdditionalSha1() { - return additionalSha1; - } - - public void setAdditionalSha1(String additionalSha1) { - this.additionalSha1 = additionalSha1; - addChecksum(ChecksumType.ADDITIONAL_SHA1, additionalSha1); - } - - public String getArchitecture() { - return architecture; - } - - public void setArchitecture(String architecture) { - this.architecture = architecture; - } - - public String getLanguageVersion() { - return languageVersion; - } - - public void setLanguageVersion(String languageVersion) { - this.languageVersion = languageVersion; - } - - public boolean isDeduped() { - return deduped; - } - - public void setDeduped(boolean deduped) { - this.deduped = deduped; - } - - public OSInfo getOsInfo() { - return osInfo; - } - - public void setOsInfo(OSInfo osInfo) { - this.osInfo = osInfo; - } - - public AnalysisInputs getAnalysisInputs() { return analysisInputs; } - - public void setAnalysisInputs(AnalysisInputs analysisInputs) { - this.analysisInputs = analysisInputs; - } - - /* --- Utility methods --- */ - - /** - * This method initializes the analysis inputs only if it's null. - * Otherwise, nothing will happen. - * - * The artifactId is copied to the analysisInputs object. - */ - public void initAnalysisInputs() { - if (analysisInputs == null) { - analysisInputs = new AnalysisInputs(artifactId); - } - } - - /** - * This method initializes the analysisInputs only if it's null. - * Otherwise, nothing will happen. - * - * @param euaArtifactId to be set inside the analysisInputs object - */ - public void initAnalysisInputs(String euaArtifactId) { - if (analysisInputs == null) { - analysisInputs = new AnalysisInputs(euaArtifactId); - } - } - - /** - * This method was created in WSE-5514 task which will help decrease the size of the update-request file, - * by removing all the empty initialized objects. - * This method runs recursively on a dependencyInfo object and its children and reset all the initialized object - * which contains no elements (empty collections) - * In addition the analysisInputs object is set to null, as it is not needed in the update-request. - */ - public void resetUnusedFields() { - analysisInputs = null; - - if (checksums != null && checksums.size() == 0) { - checksums = null; - } - - if (children != null && children.size() == 0) { - children = null; - } - - // recursive call - if (children != null) { - for (DependencyInfo child : children) { - child.resetUnusedFields(); - } - } - } - - public String getSourcePackageName() { - return sourcePackageName; - } - - public void setSourcePackageName(String sourcePackageName) { - this.sourcePackageName = sourcePackageName; - } - - public String getRelease() { - return release; - } - - public void setRelease(String release) { - this.release = release; - } -} +/** + * Copyright (C) 2012 White Source Ltd. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.whitesource.agent.api.model; + +import org.apache.commons.lang.StringUtils; +import org.whitesource.agent.api.APIConstants; +import org.whitesource.agent.via.api.VulnerabilityAnalysisResult; + +import java.io.Serializable; +import java.util.*; + +/** + * WhiteSource Model for a project's dependency + * + * @author tom.shapira + */ +public class DependencyInfo implements Serializable { + + /* --- Static members --- */ + + private static final long serialVersionUID = -6212622409560068635L; + + /* --- Members --- */ + + private String groupId; + private String artifactId; + private String version; + private String type; + private String classifier; + private String scope; + private String sha1; + private String fullHash; + private String commentlessSha1; + private String noNewLinesSha1; + private String otherPlatformSha1; + private String systemPath; + private boolean optional; + private Collection children; + private Date lastModified; + private String filename; + private DependencyType dependencyType; + private DependencyHintsInfo hints; + private Map checksums; + private VulnerabilityAnalysisResult vulnerabilityAnalysisResult; + private String commit; + private String dependencyFile; + private String additionalSha1; + private String architecture; + private String languageVersion; + private boolean deduped; + private OSInfo osInfo; + private AnalysisInputs analysisInputs; + private String sourcePackageName; + private String release; + + /* --- Constructors --- */ + + /** + * Default constructor + */ + public DependencyInfo() { + } + + /** + * Constructor + * + * @param groupId - the dependency groupId + * @param artifactId - the dependency artifactId + * @param version - the dependency version + */ + public DependencyInfo(String groupId, String artifactId, String version) { + this(); + this.groupId = groupId; + this.version = version; + this.artifactId = artifactId; + } + + /** + * Constructor + * + * @param sha1 - the dependency sha1 + */ + public DependencyInfo(String sha1) { + this(); + setSha1(sha1); + } + + /** + * Constructor + * + * @param sha1 - the dependency sha1 + * @param fullHash - the dependency fullHash + */ + public DependencyInfo(String sha1, String fullHash) { + this(sha1); + setFullHash(fullHash); + } + + public DependencyInfo(DependencyInfo dependency) { + this.groupId = dependency.groupId; + this.artifactId = dependency.artifactId; + this.version = dependency.version; + this.type = dependency.type; + this.classifier = dependency.classifier; + this.scope = dependency.scope; + this.sha1 = dependency.sha1; + this.fullHash = dependency.fullHash; + this.commentlessSha1 = dependency.commentlessSha1; + this.noNewLinesSha1 = dependency.noNewLinesSha1; + this.otherPlatformSha1 = dependency.otherPlatformSha1; + this.systemPath = dependency.systemPath; + this.optional = dependency.optional; + this.children = dependency.children != null ? new ArrayList<>(dependency.children) : null; + this.lastModified = dependency.lastModified; + this.filename = dependency.filename; + this.dependencyType = dependency.dependencyType; + this.hints = dependency.hints; + this.checksums = dependency.checksums != null ? new TreeMap<>(dependency.checksums) : null; + this.vulnerabilityAnalysisResult = dependency.vulnerabilityAnalysisResult; + this.commit = dependency.commit; + this.dependencyFile = dependency.dependencyFile; + this.additionalSha1 = dependency.additionalSha1; + this.architecture = dependency.architecture; + this.languageVersion = dependency.languageVersion; + this.deduped = dependency.deduped; + this.osInfo = dependency.osInfo; + this.analysisInputs = dependency.analysisInputs; + this.sourcePackageName = dependency.sourcePackageName; + this.release = dependency.release; + } + + /* --- Overridden methods --- */ + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append("DependencyInfo@").append(Integer.toHexString(hashCode())) + .append("[") + .append("groupId= ").append(groupId).append(",") + .append("artifactId= ").append(artifactId).append(",") + .append("version= ").append(version).append(",") + .append("filename= ").append(filename).append(",") + .append("dependencyType= ").append(dependencyType) + .append(" ]"); + + return sb.toString(); + } + + @Override + public final boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DependencyInfo)) return false; + + DependencyInfo that = (DependencyInfo) o; + + if (StringUtils.isNotEmpty(sha1)) { + return sha1.equals(that.sha1); + } else if (StringUtils.isNotEmpty(that.sha1)) { + return false; + } + if (optional != that.optional) return false; + if (artifactId != null ? !artifactId.equals(that.artifactId) : that.artifactId != null) return false; + if (classifier != null ? !classifier.equals(that.classifier) : that.classifier != null) return false; + if (groupId != null ? !groupId.equals(that.groupId) : that.groupId != null) return false; + if (scope != null ? !scope.equals(that.scope) : that.scope != null) return false; + if (type != null ? !type.equals(that.type) : that.type != null) return false; + if (version != null ? !version.equals(that.version) : that.version != null) return false; + if (filename != null ? !filename.equals(that.filename) : that.filename != null) return false; + if (commit != null ? !commit.equals(that.commit) : that.commit != null) return false; + if (dependencyType != null ? !dependencyType.equals(that.dependencyType) : that.dependencyType != null) + return false; + if (systemPath != null ? !systemPath.equals(that.systemPath) : that.systemPath != null) return false; + if (dependencyFile != null ? !dependencyFile.equals(that.dependencyFile) : that.dependencyFile != null) + return false; + if (vulnerabilityAnalysisResult != null ? + !vulnerabilityAnalysisResult.equals(that.vulnerabilityAnalysisResult) : + that.vulnerabilityAnalysisResult != null) + return false; + if (sourcePackageName != null ? !sourcePackageName.equals(that.sourcePackageName) : that.sourcePackageName != null) + return false; + if (release != null ? !release.equals(that.release) : that.release != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = APIConstants.HASH_CODE_SEED; + result = APIConstants.HASH_CODE_FACTOR * result + (groupId != null ? groupId.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (artifactId != null ? artifactId.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (version != null ? version.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (type != null ? type.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (classifier != null ? classifier.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (scope != null ? scope.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (sha1 != null ? sha1.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (optional ? 1 : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (filename != null ? filename.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (dependencyType != null ? dependencyType.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (systemPath != null ? systemPath.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (dependencyFile != null ? dependencyFile.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (vulnerabilityAnalysisResult != null ? vulnerabilityAnalysisResult.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (commit != null ? commit.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (additionalSha1 != null ? additionalSha1.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (sourcePackageName != null ? sourcePackageName.hashCode() : 0); + result = APIConstants.HASH_CODE_FACTOR * result + (release != null ? release.hashCode() : 0); + return result; + } + + /* --- Public methods --- */ + + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getClassifier() { + return classifier; + } + + public void setClassifier(String classifier) { + this.classifier = classifier; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + addChecksum(ChecksumType.SHA1, sha1); + } + + public String getSystemPath() { + return systemPath; + } + + public void setSystemPath(String systemPath) { + this.systemPath = systemPath; + } + + public boolean getOptional() { + return optional; + } + + public boolean isOptional() { + return optional; + } + + public void setOptional(boolean optional) { + this.optional = optional; + } + + public Collection getChildren() { + if (children == null) { + children = new LinkedList<>(); + } + return children; + } + + public void setChildren(Collection children) { + this.children = children; + } + + public void addChild(DependencyInfo child) { + if (children == null) { + children = new LinkedList<>(); + } + children.add(child); + } + + public boolean hasChildren() { + return children != null && children.size() != 0; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public String getCommentlessSha1() { + return commentlessSha1; + } + + public void setCommentlessSha1(String commentlessSha1) { + this.commentlessSha1 = commentlessSha1; + addChecksum(ChecksumType.SHA1_NO_COMMENTS, commentlessSha1); + } + + public String getNoNewLinesSha1() { + return noNewLinesSha1; + } + + public void setNoNewLinesSha1(String noNewLinesSha1) { + this.noNewLinesSha1 = noNewLinesSha1; + } + + public String getOtherPlatformSha1() { + return otherPlatformSha1; + } + + public void setOtherPlatformSha1(String otherPlatformSha1) { + this.otherPlatformSha1 = otherPlatformSha1; + addChecksum(ChecksumType.SHA1_OTHER_PLATFORM, otherPlatformSha1); + } + + public String getFullHash() { + return fullHash; + } + + public void setFullHash(String fullHash) { + this.fullHash = fullHash; + addChecksum(ChecksumType.SHA1_SUPER_HASH, fullHash); + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public DependencyType getDependencyType() { + return dependencyType; + } + + public void setDependencyType(DependencyType dependencyType) { + this.dependencyType = dependencyType; + } + + public DependencyHintsInfo getHints() { + return hints; + } + + public void setHints(DependencyHintsInfo hints) { + this.hints = hints; + } + + public Map getChecksums() { + if (checksums == null) { + checksums = new TreeMap<>(); + } + return checksums; + } + + public void setChecksums(Map checksums) { + this.checksums = checksums; + } + + public void addChecksum(ChecksumType checksumType, String checksum) { + if (StringUtils.isNotBlank(checksum)) { + if (checksums == null) { + checksums = new TreeMap<>(); + } + checksums.put(checksumType, checksum); + } + } + + public boolean hasChecksum() { + return checksums != null && checksums.size() != 0; + } + + public VulnerabilityAnalysisResult getVulnerabilityAnalysisResult() { + return vulnerabilityAnalysisResult; + } + + public void setVulnerabilityAnalysisResult(VulnerabilityAnalysisResult vulnerabilityAnalysisResult) { + this.vulnerabilityAnalysisResult = vulnerabilityAnalysisResult; + } + + public String getCommit() { + return commit; + } + + public void setCommit(String commit) { + this.commit = commit; + } + + public String getDependencyFile() { + return dependencyFile; + } + + public void setDependencyFile(String dependencyFile) { + this.dependencyFile = dependencyFile; + } + + public String getAdditionalSha1() { + return additionalSha1; + } + + public void setAdditionalSha1(String additionalSha1) { + this.additionalSha1 = additionalSha1; + addChecksum(ChecksumType.ADDITIONAL_SHA1, additionalSha1); + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public String getLanguageVersion() { + return languageVersion; + } + + public void setLanguageVersion(String languageVersion) { + this.languageVersion = languageVersion; + } + + public boolean isDeduped() { + return deduped; + } + + public void setDeduped(boolean deduped) { + this.deduped = deduped; + } + + public OSInfo getOsInfo() { + return osInfo; + } + + public void setOsInfo(OSInfo osInfo) { + this.osInfo = osInfo; + } + + public AnalysisInputs getAnalysisInputs() { + return analysisInputs; + } + + public void setAnalysisInputs(AnalysisInputs analysisInputs) { + this.analysisInputs = analysisInputs; + } + + /* --- Utility methods --- */ + + /** + * This method initializes the analysis inputs only if it's null. + * Otherwise, nothing will happen. + *

+ * The artifactId is copied to the analysisInputs object. + */ + public void initAnalysisInputs() { + if (analysisInputs == null) { + analysisInputs = new AnalysisInputs(artifactId); + } + } + + /** + * This method initializes the analysisInputs only if it's null. + * Otherwise, nothing will happen. + * + * @param euaArtifactId to be set inside the analysisInputs object + */ + public void initAnalysisInputs(String euaArtifactId) { + if (analysisInputs == null) { + analysisInputs = new AnalysisInputs(euaArtifactId); + } + } + + /** + * This method was created in WSE-5514 task which will help decrease the size of the update-request file, + * by removing all the empty initialized objects. + * This method runs recursively on a dependencyInfo object and its children and reset all the initialized object + * which contains no elements (empty collections) + * In addition the analysisInputs object is set to null, as it is not needed in the update-request. + */ + public void resetUnusedFields() { + analysisInputs = null; + + if (checksums != null && checksums.size() == 0) { + checksums = null; + } + + if (children != null && children.size() == 0) { + children = null; + } + + // recursive call + if (children != null) { + for (DependencyInfo child : children) { + child.resetUnusedFields(); + } + } + } + + public String getSourcePackageName() { + return sourcePackageName; + } + + public void setSourcePackageName(String sourcePackageName) { + this.sourcePackageName = sourcePackageName; + } + + public String getRelease() { + return release; + } + + public void setRelease(String release) { + this.release = release; + } +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyType.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyType.java index efefe391..876351ee 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyType.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/DependencyType.java @@ -56,7 +56,9 @@ public enum DependencyType { DOCKER, DOCKER_LAYER, - YOCTO; + YOCTO, + SWIFT, + ML_MODEL; @Override public String toString() { diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/Line.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/Line.java new file mode 100644 index 00000000..9b45c128 --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/Line.java @@ -0,0 +1,80 @@ +package org.whitesource.agent.api.model; + + +public class Line { + private int number; + private String content; + private boolean isCause; + private String annotation; + private boolean truncated; + private String highlighted; + private boolean firstCause; + private boolean lastCause; + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public boolean isCause() { + return isCause; + } + + public void setCause(boolean cause) { + isCause = cause; + } + + public String getAnnotation() { + return annotation; + } + + public void setAnnotation(String annotation) { + this.annotation = annotation; + } + + public boolean isTruncated() { + return truncated; + } + + public void setTruncated(boolean truncated) { + this.truncated = truncated; + } + + public String getHighlighted() { + return highlighted; + } + + public void setHighlighted(String highlighted) { + this.highlighted = highlighted; + } + + public boolean isFirstCause() { + return firstCause; + } + + public void setFirstCause(boolean firstCause) { + this.firstCause = firstCause; + } + + public boolean isLastCause() { + return lastCause; + } + + public void setLastCause(boolean lastCause) { + this.lastCause = lastCause; + } + + + +} diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/ResourceInfo.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/ResourceInfo.java index 8bbf7b16..7821cf18 100644 --- a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/ResourceInfo.java +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/ResourceInfo.java @@ -20,6 +20,7 @@ import java.io.Serializable; import java.util.Collection; +import java.util.HashSet; import java.util.LinkedList; /** @@ -46,6 +47,12 @@ public class ResourceInfo implements Serializable { */ private String sha1; private Collection vulnerabilities; + /** + * + * @since 2.9.9.87 + */ + private Collection ignoredVulnerabilities; + private String homepageUrl; private String description; /** @@ -68,6 +75,7 @@ public class ResourceInfo implements Serializable { public ResourceInfo() { licenses = new LinkedList<>(); vulnerabilities = new LinkedList<>(); + ignoredVulnerabilities = new HashSet<>(); } /** @@ -158,6 +166,14 @@ public void setVulnerabilities(Collection vulnerabilities) { this.vulnerabilities = vulnerabilities; } + public Collection getIgnoredVulnerabilities() { + return ignoredVulnerabilities; + } + + public void setIgnoredVulnerabilities(Collection ignoredVulnerabilities) { + this.ignoredVulnerabilities = ignoredVulnerabilities; + } + public String getHomepageUrl() { return homepageUrl; } diff --git a/wss-agent-api/src/main/java/org/whitesource/agent/api/model/SecretFinding.java b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/SecretFinding.java new file mode 100644 index 00000000..8849a715 --- /dev/null +++ b/wss-agent-api/src/main/java/org/whitesource/agent/api/model/SecretFinding.java @@ -0,0 +1,97 @@ +package org.whitesource.agent.api.model; + + +public class SecretFinding { + + private int layerNumber; + private String ruleId; + private String category; + private String severity; + private String description; + private int startLine; + private int endLine; + private String filePath; + private Code code; + private String match; + + public String getRuleId() { + return ruleId; + } + + public void setRuleId(String ruleId) { + this.ruleId = ruleId; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getStartLine() { + return startLine; + } + + public void setStartLine(int startLine) { + this.startLine = startLine; + } + + public int getEndLine() { + return endLine; + } + + public void setEndLine(int endLine) { + this.endLine = endLine; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public Code getCode() { + return code; + } + + public void setCode(Code code) { + this.code = code; + } + + public String getMatch() { + return match; + } + + public void setMatch(String match) { + this.match = match; + } + + public int getLayerNumber() { + return layerNumber; + } + + public void setLayerNumber(int layerNumber) { + this.layerNumber = layerNumber; + } + +} \ No newline at end of file diff --git a/wss-agent-client/pom.xml b/wss-agent-client/pom.xml index 4ebb7abc..d85566f3 100644 --- a/wss-agent-client/pom.xml +++ b/wss-agent-client/pom.xml @@ -4,7 +4,7 @@ wss-agent-parent org.whitesource - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT wss-agent-api-client @@ -108,4 +108,4 @@ - \ No newline at end of file + diff --git a/wss-agent-client/src/main/java/org/whitesource/agent/client/WhitesourceService.java b/wss-agent-client/src/main/java/org/whitesource/agent/client/WhitesourceService.java index 0abe63fa..f6ff9749 100644 --- a/wss-agent-client/src/main/java/org/whitesource/agent/client/WhitesourceService.java +++ b/wss-agent-client/src/main/java/org/whitesource/agent/client/WhitesourceService.java @@ -73,6 +73,26 @@ public WhitesourceService(final String agent, final String agentVersion, String client = new WssServiceClientImpl(url, setProxy, connectionTimeoutMinutes, ignoreCertificateCheck); } + public WhitesourceService(final String agent, final String agentVersion, String pluginVersion, final String serviceUrl, boolean setProxy, + int connectionTimeoutMinutes, boolean ignoreCertificateCheck, boolean useStreams) { + requestFactory = new RequestFactory(agent, agentVersion, pluginVersion); + + String url = serviceUrl; + if (url == null || url.trim().length() == 0) { + url = System.getProperty(ClientConstants.SERVICE_URL_KEYWORD, ClientConstants.DEFAULT_SERVICE_URL); + } + + if (connectionTimeoutMinutes <= 0) { + connectionTimeoutMinutes = Integer.parseInt(System.getProperty(ClientConstants.CONNECTION_TIMEOUT_KEYWORD, + String.valueOf(ClientConstants.DEFAULT_CONNECTION_TIMEOUT_MINUTES))); + } + if (useStreams) { + client = new WssStreamServiceClientImpl(url, setProxy, connectionTimeoutMinutes, ignoreCertificateCheck); + } else { + client = new WssServiceClientImpl(url, setProxy, connectionTimeoutMinutes, ignoreCertificateCheck); + } + } + // backward compatibility methods (plugin version is not a parameter) public WhitesourceService(final String agent, final String agentVersion, final String serviceUrl, boolean setProxy) { @@ -87,21 +107,21 @@ public WhitesourceService(final String agent, final String agentVersion, final S /* --- Public methods --- */ public WhitesourceService cloneWhitesourceService() { - WssServiceClient client = this.getClient(); - WhitesourceService whitesourceService = new WhitesourceService(requestFactory.getAgent(), - requestFactory.getAgentVersion(), requestFactory.getPluginVersion(), - client.getServiceUrl(), client.isProxy(), client.getConnectionTimeoutMinutes(), - client.getIgnoreCertificateCheck()); + WssServiceClient client = this.getClient(); + WhitesourceService whitesourceService = new WhitesourceService(requestFactory.getAgent(), + requestFactory.getAgentVersion(), requestFactory.getPluginVersion(), + client.getServiceUrl(), client.isProxy(), client.getConnectionTimeoutMinutes(), + client.getIgnoreCertificateCheck()); - whitesourceService.getClient() - .setProxy(client.getProxyHost(), client.getProxyPort(), client.getProxyUsername(), - client.getProxyPassword()); + whitesourceService.getClient() + .setProxy(client.getProxyHost(), client.getProxyPort(), client.getProxyUsername(), + client.getProxyPassword()); - return whitesourceService; + return whitesourceService; } - /** + /** * Updates the White Source organization account with the given OSS information. * * @param orgToken Organization token uniquely identifying the account at white source. @@ -624,6 +644,22 @@ public CheckPolicyComplianceResult checkPolicyCompliance(CheckPolicyComplianceRe requestFactory.newCheckPolicyComplianceRequest(request)); } + public AsyncCheckPolicyComplianceResult asyncCheckPolicyCompliance(AsyncCheckPolicyComplianceRequest request) throws WssServiceException { + return client.asyncCheckPolicyCompliance( + requestFactory.newAsyncCheckPolicyComplianceRequest(request)); + } + + public AsyncCheckPolicyComplianceStatusResult asyncCheckPolicyComplianceStatus(AsyncCheckPolicyComplianceStatusRequest request) throws WssServiceException { + return client.asyncCheckPolicyComplianceStatus( + requestFactory.newAsyncCheckPolicyComplianceStatusRequest(request)); + } + + public AsyncCheckPolicyComplianceResponseResult asyncCheckPolicyRComplianceResponse(AsyncCheckPolicyComplianceResponseRequest request) throws WssServiceException { + return client.asyncCheckPolicyComplianceResponse( + requestFactory.newAsyncCheckPolicyComplianceResponseRequest(request)); + } + + /** * Gets additional data for given dependencies. * diff --git a/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClient.java b/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClient.java index 996fc2ce..a2caff60 100644 --- a/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClient.java +++ b/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClient.java @@ -56,6 +56,12 @@ public interface WssServiceClient { */ CheckPolicyComplianceResult checkPolicyCompliance(CheckPolicyComplianceRequest request) throws WssServiceException; + AsyncCheckPolicyComplianceResult asyncCheckPolicyCompliance(AsyncCheckPolicyComplianceRequest request) throws WssServiceException; + + AsyncCheckPolicyComplianceStatusResult asyncCheckPolicyComplianceStatus(AsyncCheckPolicyComplianceStatusRequest request) throws WssServiceException; + + AsyncCheckPolicyComplianceResponseResult asyncCheckPolicyComplianceResponse(AsyncCheckPolicyComplianceResponseRequest request) throws WssServiceException; + /** * The method call the White Source service for getting additional dependency data. * diff --git a/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClientImpl.java b/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClientImpl.java index 9e577cde..f80aa225 100644 --- a/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClientImpl.java +++ b/wss-agent-client/src/main/java/org/whitesource/agent/client/WssServiceClientImpl.java @@ -209,6 +209,21 @@ public CheckPolicyComplianceResult checkPolicyCompliance(CheckPolicyComplianceRe return service(request); } + @Override + public AsyncCheckPolicyComplianceResult asyncCheckPolicyCompliance(AsyncCheckPolicyComplianceRequest request) throws WssServiceException { + return service(request); + } + + @Override + public AsyncCheckPolicyComplianceStatusResult asyncCheckPolicyComplianceStatus(AsyncCheckPolicyComplianceStatusRequest request) throws WssServiceException { + return service(request); + } + + @Override + public AsyncCheckPolicyComplianceResponseResult asyncCheckPolicyComplianceResponse(AsyncCheckPolicyComplianceResponseRequest request) throws WssServiceException { + return service(request); + } + @Override public GetDependencyDataResult getDependencyData(GetDependencyDataRequest request) throws WssServiceException { return service(request); @@ -349,6 +364,15 @@ protected R service(ServiceRequest request) throws WssServiceException { case CHECK_POLICY_COMPLIANCE: result = (R) gson.fromJson(data, CheckPolicyComplianceResult.class); break; + case ASYNC_CHECK_POLICY_COMPLIANCE: + result = (R) gson.fromJson(data, AsyncCheckPolicyComplianceResult.class); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_STATUS: + result = (R) gson.fromJson(data, AsyncCheckPolicyComplianceStatusResult.class); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE: + result = (R) gson.fromJson(data, AsyncCheckPolicyComplianceResponseResult.class); + break; case CHECK_VULNERABILITIES: result = (R) gson.fromJson(data, CheckVulnerabilitiesResult.class); break; @@ -429,18 +453,16 @@ protected HttpRequestBase createHttpRequest(ServiceRequest request) throw jsonDiff = gson.toJson(((CheckPoliciesRequest) request).getProjects()); break; case CHECK_POLICY_COMPLIANCE: - CheckPolicyComplianceRequest checkPolicyComplianceRequest = (CheckPolicyComplianceRequest) request; - nvps.add(new BasicNameValuePair(APIConstants.SCAN_SUMMARY_INFO, this.gson.toJson(checkPolicyComplianceRequest.getScanSummaryInfo()))); - nvps.add(new BasicNameValuePair(APIConstants.PARAM_FORCE_CHECK_ALL_DEPENDENCIES, - String.valueOf(checkPolicyComplianceRequest.isForceCheckAllDependencies()))); - nvps.add(new BasicNameValuePair(APIConstants.PARAM_POPULATE_VULNERABILITIES, - String.valueOf(checkPolicyComplianceRequest.isPopulateVulnerabilities()))); - nvps.add(new BasicNameValuePair(APIConstants.CONTRIBUTIONS, this.gson.toJson(checkPolicyComplianceRequest.getContributions()))); - /*Gson checkPoliciesGson = new GsonBuilder().setPrettyPrinting() - .addSerializationExclusionStrategy(getExclusionStrategy()) - .registerTypeHierarchyAdapter(Collection.class, new CollectionAdapter()).create(); - jsonDiff = checkPoliciesGson.toJson(checkPolicyComplianceRequest.getProjects());*/ - jsonDiff = gson.toJson(checkPolicyComplianceRequest.getProjects()); + case ASYNC_CHECK_POLICY_COMPLIANCE: + jsonDiff = handleCheckPolicyReq(nvps, request); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_STATUS: + jsonDiff = gson.toJson(((AsyncCheckPolicyComplianceStatusRequest) request).getProjects()); + nvps.add(new BasicNameValuePair(APIConstants.IDENTIFIER, ((AsyncCheckPolicyComplianceStatusRequest) request).getIdentifier())); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE: + jsonDiff = gson.toJson(((AsyncCheckPolicyComplianceResponseRequest) request).getProjects()); + nvps.add(new BasicNameValuePair(APIConstants.IDENTIFIER, ((AsyncCheckPolicyComplianceResponseRequest) request).getIdentifier())); break; case CHECK_VULNERABILITIES: jsonDiff = gson.toJson(((CheckVulnerabilitiesRequest) request).getProjects()); @@ -475,6 +497,26 @@ protected HttpRequestBase createHttpRequest(ServiceRequest request) throw return httpRequest; } + private String handleCheckPolicyReq(List nvps, ServiceRequest request) { + BaseRequest br = (BaseRequest) request; + + nvps.add(new BasicNameValuePair(APIConstants.SCAN_SUMMARY_INFO, this.gson.toJson(br.getScanSummaryInfo()))); + nvps.add(new BasicNameValuePair(APIConstants.CONTRIBUTIONS, this.gson.toJson(br.getContributions()))); + if (request.type() != RequestType.ASYNC_CHECK_POLICY_COMPLIANCE) { + nvps.add(new BasicNameValuePair(APIConstants.PARAM_FORCE_CHECK_ALL_DEPENDENCIES, + String.valueOf(((CheckPolicyComplianceRequest)br).isForceCheckAllDependencies()))); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_POPULATE_VULNERABILITIES, + String.valueOf(((CheckPolicyComplianceRequest)br).isPopulateVulnerabilities()))); + } else { + nvps.add(new BasicNameValuePair(APIConstants.PARAM_FORCE_CHECK_ALL_DEPENDENCIES, + String.valueOf(((AsyncCheckPolicyComplianceRequest)br).isForceCheckAllDependencies()))); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_POPULATE_VULNERABILITIES, + String.valueOf(((AsyncCheckPolicyComplianceRequest)br).isPopulateVulnerabilities()))); + } + + return gson.toJson(br.getProjects()); + } + /** * The method extract the data from the given {@link org.whitesource.agent.api.dispatch.ResultEnvelope}. * diff --git a/wss-agent-client/src/main/java/org/whitesource/agent/client/WssStreamServiceClientImpl.java b/wss-agent-client/src/main/java/org/whitesource/agent/client/WssStreamServiceClientImpl.java new file mode 100644 index 00000000..83bb22c4 --- /dev/null +++ b/wss-agent-client/src/main/java/org/whitesource/agent/client/WssStreamServiceClientImpl.java @@ -0,0 +1,739 @@ +/** + * Copyright (C) 2012 White Source Ltd. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.whitesource.agent.client; + +import com.github.markusbernhardt.proxy.ProxySearch; +import com.google.gson.*; +import com.google.gson.stream.JsonWriter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpHost; +import org.apache.http.HttpVersion; +import org.apache.http.NameValuePair; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.NTCredentials; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.params.HttpClientParams; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.impl.client.*; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.EntityUtils; +import org.whitesource.agent.api.APIConstants; +import org.whitesource.agent.api.dispatch.*; +import org.whitesource.agent.api.model.AgentProjectInfo; +import org.whitesource.agent.api.model.DependencyInfo; +import org.whitesource.agent.utils.ZipUtils; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.security.KeyStore; +import java.util.*; + +/** + * Default Implementation of the interface using Apache's HttpClient. + * + * @author tom.shapira + * @author Edo.Shor + */ +public class WssStreamServiceClientImpl implements WssServiceClient { + + /* --- Static members --- */ + + private static final String HTTP_PROXY_USER = "http.proxyUser"; + private static final String HTTP_PROXY_PASSWORD = "http.proxyPassword"; + public static final String PROXY_HOST = "proxy.host"; + public static final String PROXY_PORT = "proxy.port"; + public static final String PROXY_USER = "proxy.user"; + public static final String PROXY_PASS = "proxy.pass"; + private static final int TO_MILLISECONDS = 60 * 1000; + private static final String UTF_8 = "UTF-8"; + + private static final Log logger = LogFactory.getLog(WssStreamServiceClientImpl.class); + private static final String TLS = "TLS"; + public static final String SOME_PASSWORD = "some password"; + + /* --- Members --- */ + + protected String serviceUrl; + protected CloseableHttpClient httpClient; + protected Gson gson; + protected int connectionTimeout; + + boolean ignoreCertificateCheck; + private String proxyHost; + private int proxyPort; + private String proxyUsername; + private String proxyPassword; + private Map headers; + + private final boolean proxyEnabled; + + /* --- Constructors --- */ + + /** + * Default constructor + */ + public WssStreamServiceClientImpl() { + this(ClientConstants.DEFAULT_SERVICE_URL); + } + + /** + * Constructor + * + * @param serviceUrl WhiteSource service URL to use. + */ + public WssStreamServiceClientImpl(String serviceUrl) { + this(serviceUrl, true); + } + + /** + * Constructor + * + * @param serviceUrl WhiteSource service URL to use. + * @param setProxy WhiteSource set proxy, whether the proxy settings defined or not. + */ + public WssStreamServiceClientImpl(String serviceUrl, boolean setProxy) { + this(serviceUrl, setProxy, ClientConstants.DEFAULT_CONNECTION_TIMEOUT_MINUTES); + } + + public WssStreamServiceClientImpl(String serviceUrl, boolean setProxy, int connectionTimeoutMinutes) { + this(serviceUrl, setProxy, connectionTimeoutMinutes, false); + } + + /** + * Constructor + * + * @param serviceUrl WhiteSource service URL to use. + * @param setProxy WhiteSource set proxy, whether the proxy settings is defined or not. + * @param connectionTimeoutMinutes WhiteSource connection timeout, whether the connection timeout is defined or not (default to 60 minutes). + */ + public WssStreamServiceClientImpl(String serviceUrl, boolean setProxy, int connectionTimeoutMinutes, boolean ignoreCertificateCheck) { + this.proxyEnabled = setProxy; + gson = new Gson(); + + if (serviceUrl == null || serviceUrl.length() == 0) { + this.serviceUrl = ClientConstants.DEFAULT_SERVICE_URL; + } else { + this.serviceUrl = serviceUrl; + } + + if (connectionTimeoutMinutes <= 0) { + this.connectionTimeout = ClientConstants.DEFAULT_CONNECTION_TIMEOUT_MINUTES * TO_MILLISECONDS; + } else { + this.connectionTimeout = connectionTimeoutMinutes * TO_MILLISECONDS; + } + + HttpParams params = new BasicHttpParams(); + HttpClientParams.setRedirecting(params, true); + + httpClient = new DefaultHttpClient(); + + if (ignoreCertificateCheck) { + try { + logger.warn("Security Warning - Trusting all certificates"); + + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + char[] password = SOME_PASSWORD.toCharArray(); + keystore.load(null, password); + + WssSSLSocketFactory sf = new WssSSLSocketFactory(keystore); + sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); + + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("https", sf, 443)); + + ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); + + httpClient = new DefaultHttpClient(ccm, params); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + + setConnectionTimeout(this.connectionTimeout); + + if (this.proxyEnabled) { + findDefaultProxy(); + } + } + + /* --- Interface implementation methods --- */ + + @Override + public UpdateInventoryResult updateInventory(UpdateInventoryRequest request) throws WssServiceException { + return service(request); + } + + @Override + public CheckPoliciesResult checkPolicies(CheckPoliciesRequest request) throws WssServiceException { + return service(request); + } + + @Override + public CheckPolicyComplianceResult checkPolicyCompliance(CheckPolicyComplianceRequest request) throws WssServiceException { + return service(request); + } + + @Override + public AsyncCheckPolicyComplianceResult asyncCheckPolicyCompliance(AsyncCheckPolicyComplianceRequest request) throws WssServiceException { + return service(request); + } + + @Override + public AsyncCheckPolicyComplianceStatusResult asyncCheckPolicyComplianceStatus(AsyncCheckPolicyComplianceStatusRequest request) throws WssServiceException { + return service(request); + } + + @Override + public AsyncCheckPolicyComplianceResponseResult asyncCheckPolicyComplianceResponse(AsyncCheckPolicyComplianceResponseRequest request) throws WssServiceException { + return service(request); + } + + @Override + public GetDependencyDataResult getDependencyData(GetDependencyDataRequest request) throws WssServiceException { + return service(request); + } + + @Override + public SummaryScanResult summaryScan(SummaryScanRequest request) throws WssServiceException { + return service(request); + } + + @Override + public CheckVulnerabilitiesResult checkVulnerabilities(CheckVulnerabilitiesRequest request) throws WssServiceException { + return service(request); + } + + @Override + public ConfigurationResult getConfiguration(ConfigurationRequest request) throws WssServiceException { + return service(request); + } + + @Override + public void shutdown() { + httpClient.getConnectionManager().shutdown(); + } + + @Override + public void setProxy(String host, int port, String username, String password) { + this.proxyHost = host; + this.proxyPort = port; + this.proxyUsername = username; + this.proxyPassword = password; + if (host == null || host.trim().length() == 0) { + return; + } + if (port < 0 || port > 65535) { + return; + } + + HttpHost proxy = new HttpHost(proxyHost, proxyPort); + // httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); + DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); + httpClient = HttpClients.custom().setRoutePlanner(routePlanner).build(); + logger.info("Using proxy: " + proxy.toHostString()); + + if (proxyUsername != null && proxyUsername.trim().length() > 0) { + logger.info("Proxy username: " + proxyUsername); + Credentials credentials; + if (proxyUsername.indexOf('/') >= 0) { + credentials = new NTCredentials(proxyUsername + ":" + proxyPassword); + } else if (proxyUsername.indexOf('\\') >= 0) { + proxyUsername = proxyUsername.replace('\\', '/'); + credentials = new NTCredentials(proxyUsername + ":" + proxyPassword); + } else { + credentials = new UsernamePasswordCredentials(proxyUsername, proxyPassword); + } + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(AuthScope.ANY, credentials); + // TODO check + httpClient = HttpClientBuilder.create().setProxy(proxy) + .setDefaultCredentialsProvider(credsProvider).build(); + + // httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, credentials); + } + } + + @Override + public void setConnectionTimeout(int timeout) { + HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), timeout); + HttpConnectionParams.setSoTimeout(httpClient.getParams(), timeout); + } + + public Map findDefaultProxyDetails(String url) { + Map proxyDetails = new HashMap<>(); + ProxySearch proxySearch = new ProxySearch(); + proxySearch.addStrategy(ProxySearch.Strategy.JAVA); + proxySearch.addStrategy(ProxySearch.Strategy.ENV_VAR); + proxySearch.addStrategy(ProxySearch.Strategy.OS_DEFAULT); + proxySearch.addStrategy(ProxySearch.Strategy.BROWSER); + ProxySelector proxySelector = proxySearch.getProxySelector(); + + if (proxySelector != null) { + ProxySelector.setDefault(proxySelector); + try { + List proxyList = proxySelector.select(new URI(url)); + if (proxyList != null && !proxyList.isEmpty()) { + for (Proxy proxy : proxyList) { + InetSocketAddress address = (InetSocketAddress) proxy.address(); + if (address != null) { + String host = address.getHostName(); + int port = address.getPort(); + String username = System.getProperty(HTTP_PROXY_USER); + String password = System.getProperty(HTTP_PROXY_PASSWORD); + proxyDetails.put(PROXY_HOST, host); + proxyDetails.put(PROXY_PORT, String.valueOf(port)); + proxyDetails.put(PROXY_USER, username); + proxyDetails.put(PROXY_PASS, password); + } + } + } + } catch (URISyntaxException e) { + logger.error("Bad service url: " + serviceUrl, e); + } + } + return proxyDetails; + } + + /* --- Protected methods --- */ + + /** + * The method service the given request. + * + * @param request Request to serve. + * @return Result from WhiteSource service. + * @throws WssServiceException In case of errors while serving the request. + */ + @SuppressWarnings("unchecked") + protected R service(ServiceRequest request) throws WssServiceException { + R result; + String response = ""; + try { + HttpRequestBase httpRequest = createHttpRequest(request); + RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build(); + httpRequest.setConfig(requestConfig); + logger.trace("Calling White Source service: " + request); + try (CloseableHttpResponse resp = httpClient.execute(httpRequest)) { + response = EntityUtils.toString(resp.getEntity()); + logger.trace("Response Code: " + resp.getStatusLine().getStatusCode()); + } catch (Exception e) { + throw new WssServiceException("Unexpected error. err: " + e.getMessage(), e); + } + String data = extractResultData(response); + logger.trace("Result data is: " + data); + + switch (request.type()) { + case UPDATE: + result = (R) gson.fromJson(data, UpdateInventoryResult.class); + break; + case CHECK_POLICIES: + result = (R) gson.fromJson(data, CheckPoliciesResult.class); + break; + case CHECK_POLICY_COMPLIANCE: + result = (R) gson.fromJson(data, CheckPolicyComplianceResult.class); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE: + result = (R) gson.fromJson(data, AsyncCheckPolicyComplianceResult.class); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_STATUS: + result = (R) gson.fromJson(data, AsyncCheckPolicyComplianceStatusResult.class); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE: + result = (R) gson.fromJson(data, AsyncCheckPolicyComplianceResponseResult.class); + break; + case CHECK_VULNERABILITIES: + result = (R) gson.fromJson(data, CheckVulnerabilitiesResult.class); + break; + case GET_CLOUD_NATIVE_VULNERABILITIES: + result = (R) gson.fromJson(data, GetCloudNativeVulnerabilitiesResult.class); + break; + case GET_DEPENDENCY_DATA: + result = (R) gson.fromJson(data, GetDependencyDataResult.class); + break; + case SUMMARY_SCAN: + result = (R) gson.fromJson(data, SummaryScanResult.class); + break; + case GET_CONFIGURATION: + result = (R) gson.fromJson(data, ConfigurationResult.class); + break; + default: + throw new IllegalStateException("Unsupported request type."); + } + } catch (JsonSyntaxException e) { + throw new WssServiceException("JsonSyntax exception. Response data is: " + response + e.getMessage(), e); + } catch (HttpResponseException e) { + throw new WssServiceException("Unexpected error. Response data is: " + response + e.getMessage() + " Error code is " + e.getStatusCode(), e.getCause(), e.getStatusCode()); + } catch (IOException e) { + throw new WssServiceException("Unexpected error. Response data is: " + response + e.getMessage(), e); + } + + return result; + } + + /** + * The method create the HTTP post request to be sent to the remote service. + * + * @param request Request to service. + * @return Newly created HTTP post request. + * @throws IOException In case of error creating the request. + */ + protected HttpRequestBase createHttpRequest(ServiceRequest request) throws IOException, WssServiceException { + HttpPost httpRequest = new HttpPost(serviceUrl); + httpRequest.setHeader("Accept", ClientConstants.APPLICATION_JSON); +// if (((BaseRequest) request).getProjects() == null || ((BaseRequest) request).getProjects().isEmpty() ){ +// appendDummyProject(request); +// } + PipedOutputStream pos = new PipedOutputStream(); + PipedInputStream pis = new PipedInputStream(pos); + + RequestType requestType = request.type(); + List nvps = new ArrayList<>(); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_REQUEST_TYPE, requestType.toString())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_AGENT, request.agent())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_AGENT_VERSION, request.agentVersion())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_TOKEN, request.orgToken())); + nvps.add(new BasicNameValuePair(APIConstants.USER_KEY, request.userKey())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_REQUESTER_EMAIL, request.requesterEmail())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_PRODUCT, request.product())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_PRODUCT_VERSION, request.productVersion())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_TIME_STAMP, String.valueOf(request.timeStamp()))); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_PLUGIN_VERSION, String.valueOf(request.pluginVersion()))); + nvps.add(new BasicNameValuePair(APIConstants.AGGREGATE_MODULES, String.valueOf(request.aggregateModules()))); + nvps.add(new BasicNameValuePair(APIConstants.PRESERVE_MODULE_STRUCTURE, String.valueOf(request.preserveModuleStructure()))); + nvps.add(new BasicNameValuePair(APIConstants.AGGREGATE_PROJECT_NAME, request.aggregateProjectName())); + nvps.add(new BasicNameValuePair(APIConstants.AGGREGATE_PROJECT_TOKEN, request.aggregateProjectToken())); + nvps.add(new BasicNameValuePair(APIConstants.LOG_DATA, request.logData())); + nvps.add(new BasicNameValuePair(APIConstants.SCAN_COMMENT, request.scanComment())); + nvps.add(new BasicNameValuePair(APIConstants.PRODUCT_TOKEN, request.productToken())); + + if (request.extraProperties() != null) { + String strExtraProperties = gson.toJson(request.extraProperties()); + nvps.add(new BasicNameValuePair(APIConstants.EXTRA_PROPERTIES, strExtraProperties)); + } else { + nvps.add(new BasicNameValuePair(APIConstants.EXTRA_PROPERTIES, "{}")); + } + switch (requestType) { + case UPDATE: + UpdateInventoryRequest updateInventoryRequest = (UpdateInventoryRequest) request; + nvps.add(new BasicNameValuePair(APIConstants.SCAN_SUMMARY_INFO, gson.toJson(updateInventoryRequest.getScanSummaryInfo()))); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_UPDATE_TYPE, updateInventoryRequest.getUpdateType().toString())); + nvps.add(new BasicNameValuePair(APIConstants.CONTRIBUTIONS, gson.toJson(updateInventoryRequest.getContributions()))); + break; + case CHECK_POLICY_COMPLIANCE: + case ASYNC_CHECK_POLICY_COMPLIANCE: + handleCheckPolicyReq(nvps, request); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_STATUS: + nvps.add(new BasicNameValuePair(APIConstants.IDENTIFIER, ((AsyncCheckPolicyComplianceStatusRequest) request).getIdentifier())); + break; + case ASYNC_CHECK_POLICY_COMPLIANCE_RESPONSE: + nvps.add(new BasicNameValuePair(APIConstants.IDENTIFIER, ((AsyncCheckPolicyComplianceResponseRequest) request).getIdentifier())); + break; + default: + break; + } + if (requestType == RequestType.UPDATE || requestType == RequestType.CHECK_POLICIES || requestType == RequestType.CHECK_POLICY_COMPLIANCE || requestType == RequestType.ASYNC_CHECK_POLICY_COMPLIANCE) { + new Thread(() -> { + try { + byte[] paramsArray = URLEncodedUtils.format(nvps, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8); + pos.write(paramsArray); + pos.write("&".getBytes()); + pos.write((APIConstants.PARAM_DIFF + "=").getBytes()); + streamProjects(((BaseRequest) request).getProjects(), pos); + ZipUtils.compressOutputStream(pis, pos); + encodediff(pis,pos); + } catch (Exception e) { + throw new RuntimeException("failed processing update", e); + } finally { + try { + pos.close(); + } catch (IOException e) { + throw new RuntimeException("failed closing piped stream: ", e); + } + } + }).start(); + // if (requestType == RequestType.UPDATE) { + InputStreamEntity entity = new InputStreamEntity(pis, ContentType.APPLICATION_FORM_URLENCODED); + entity.setChunked(true); + httpRequest.setEntity(entity); + } else { + String compressedString = ZipUtils.compressString(gson.toJson(((BaseRequest) request).getProjects())); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_DIFF, compressedString)); + + httpRequest.setEntity(new UrlEncodedFormEntity(nvps, UTF_8)); + } + if (headers != null) { + headers.forEach(httpRequest::setHeader); + } + return httpRequest; + } + public static void encodediff(PipedInputStream pis, PipedOutputStream pos) throws Exception { + try (OutputStreamWriter writer = new OutputStreamWriter(pos, StandardCharsets.UTF_8)) { + byte[] buffer = new byte[1024]; + int len; + while ((len = pis.read(buffer)) != -1) { + String encodedString = URLEncoder.encode(new String(buffer, 0, len, StandardCharsets.UTF_8), StandardCharsets.UTF_8.toString()); + writer.write(encodedString); + } + } + } + + private void streamProjects(Collection projects,PipedOutputStream pos) throws IOException { + OutputStreamWriter osw = new OutputStreamWriter(pos, StandardCharsets.UTF_8); + JsonWriter writer = new JsonWriter(osw); + + writer.beginArray(); // Start of projects + + for (AgentProjectInfo project : projects) { + writer.beginObject(); // Start of project + + // Use Java Reflection to iterate over all fields + for (Field field : AgentProjectInfo.class.getDeclaredFields()) { + field.setAccessible(true); // You might want to set this only if your field is private + Object value; + try { + value = field.get(project); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); // This should never happen + } + + // Check if the field value is not null and the field is not "dependencies" + if (value != null && !field.getName().equals("dependencies") && !field.getName().equals("serialVersionUID")) { + writer.name(field.getName()).jsonValue(gson.toJson(value)); + } + } + + // Now handle the "dependencies" field separately + if (project.getDependencies() != null) { + writer.name("dependencies"); + writer.beginArray(); + for (DependencyInfo dependency : project.getDependencies()) { + streamDependencyInfo(dependency, writer); + } + writer.endArray(); + } + + writer.endObject(); // End of project + } + + writer.endArray(); // End of projects + writer.close(); + } + private void streamDependencyInfo(DependencyInfo dependency, JsonWriter writer) throws IOException { + writer.beginObject(); // Start DependencyInfo object + + // Manually write the properties of the DependencyInfo object + // Use Java Reflection to iterate over all fields + for (Field field : DependencyInfo.class.getDeclaredFields()) { + field.setAccessible(true); // You might want to set this only if your field is private + Object value; + try { + value = field.get(dependency); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); // This should never happen + } + + // Check if the field value is not null and the field is not "children" + if (value != null && !field.getName().equals("children") && !field.getName().equals("serialVersionUID")) { + writer.name(field.getName()).jsonValue(gson.toJson(value)); + } + } + + // Now add the "children" property + if (dependency.getChildren() != null) { + writer.name("children"); + writer.beginArray(); + for (DependencyInfo child : dependency.getChildren()) { + streamDependencyInfo(child, writer); + } + writer.endArray(); + } + writer.endObject(); // End DependencyInfo object + } + private void handleCheckPolicyReq(List nvps, ServiceRequest request) { + BaseRequest br = (BaseRequest) request; + + nvps.add(new BasicNameValuePair(APIConstants.SCAN_SUMMARY_INFO, this.gson.toJson(br.getScanSummaryInfo()))); + nvps.add(new BasicNameValuePair(APIConstants.CONTRIBUTIONS, this.gson.toJson(br.getContributions()))); + if (request.type() != RequestType.ASYNC_CHECK_POLICY_COMPLIANCE) { + nvps.add(new BasicNameValuePair(APIConstants.PARAM_FORCE_CHECK_ALL_DEPENDENCIES, + String.valueOf(((CheckPolicyComplianceRequest) br).isForceCheckAllDependencies()))); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_POPULATE_VULNERABILITIES, + String.valueOf(((CheckPolicyComplianceRequest) br).isPopulateVulnerabilities()))); + } else { + nvps.add(new BasicNameValuePair(APIConstants.PARAM_FORCE_CHECK_ALL_DEPENDENCIES, + String.valueOf(((AsyncCheckPolicyComplianceRequest) br).isForceCheckAllDependencies()))); + nvps.add(new BasicNameValuePair(APIConstants.PARAM_POPULATE_VULNERABILITIES, + String.valueOf(((AsyncCheckPolicyComplianceRequest) br).isPopulateVulnerabilities()))); + } + } + + /** + * The method extract the data from the given {@link org.whitesource.agent.api.dispatch.ResultEnvelope}. + * + * @param response HTTP response as string. + * @return String with logical result in JSON format. + * @throws IOException + * @throws WssServiceException + */ + protected String extractResultData(String response) throws IOException, WssServiceException { + // parse response + ResultEnvelope envelope = gson.fromJson(response, ResultEnvelope.class); + if (envelope == null) { + throw new WssServiceException("Empty response, response data is: " + response); + } + + // extract info from envelope + String message = envelope.getMessage(); + String data = envelope.getData(); + String requestToken = envelope.getRequestToken(); + + // service fault ? + if (ResultEnvelope.STATUS_SUCCESS != envelope.getStatus()) { + throw new WssServiceException(message + ": " + data, requestToken); + } + return data; + } + + /* --- Private methods --- */ + + private void findDefaultProxy() { + Map proxyDetails = findDefaultProxyDetails(serviceUrl); + if (proxyDetails.size() > 0) { + setProxy(proxyDetails.get(PROXY_HOST), Integer.parseInt(proxyDetails.get(PROXY_PORT)), + proxyDetails.get(PROXY_USER), proxyDetails.get(PROXY_PASS)); + } + } + + private ExclusionStrategy getExclusionStrategy() { + return new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes fieldAttributes) { + String name = fieldAttributes.getName(); + if (name.equals("optional") || name.equals("checksums") || name.equals("deduped")) { + return true; + } + return false; + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }; + } + + static class CollectionAdapter implements JsonSerializer> { + @Override + public JsonElement serialize(Collection src, Type typeOfSrc, + JsonSerializationContext context) { + if (src == null || src.isEmpty()) + return null; + JsonArray array = new JsonArray(); + for (Object child : src) { + JsonElement element = context.serialize(child); + array.add(element); + } + return array; + } + } + + /* --- Getters --- */ + + public String getServiceUrl() { + return serviceUrl; + } + + public HttpClient getHttpClient() { + return httpClient; + } + + /* --- Getters --- */ + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public int getConnectionTimeoutMinutes() { + return connectionTimeout / TO_MILLISECONDS; + } + + public String getProxyHost() { + return proxyHost; + } + + public int getProxyPort() { + return proxyPort; + } + + public String getProxyUsername() { + return proxyUsername; + } + + public String getProxyPassword() { + return proxyPassword; + } + + public boolean isProxy() { + return proxyEnabled; + } + + @Override + public boolean getIgnoreCertificateCheck() { + return this.ignoreCertificateCheck; + } + + @Override + public Map getHeaders() { + return headers; + } + + @Override + public void setHeaders(Map headers) { + this.headers = headers; + } +} diff --git a/wss-agent-client/src/test/java/org/whitesource/agent/client/WssStreamServiceClientImplTest.java b/wss-agent-client/src/test/java/org/whitesource/agent/client/WssStreamServiceClientImplTest.java new file mode 100644 index 00000000..d8d9df8f --- /dev/null +++ b/wss-agent-client/src/test/java/org/whitesource/agent/client/WssStreamServiceClientImplTest.java @@ -0,0 +1,113 @@ +//package org.whitesource.agent.client; +// +//import org.apache.commons.lang.StringUtils; +//import org.apache.http.client.methods.HttpRequestBase; +//import org.junit.After; +//import org.junit.Before; +//import org.junit.Ignore; +//import org.junit.Test; +//import org.whitesource.agent.api.dispatch.ConfigurationRequest; +//import org.whitesource.agent.api.dispatch.UpdateInventoryRequest; +//import org.whitesource.agent.api.dispatch.UpdateType; +//import org.whitesource.agent.api.model.AgentProjectInfo; +//import org.whitesource.agent.api.model.Coordinates; +//import org.whitesource.agent.api.model.DependencyInfo; +//import org.whitesource.agent.api.model.DependencyType; +// +//import java.util.*; +// +//import static org.junit.Assert.*; +// +//public class WssStreamServiceClientImplTest { +// UpdateInventoryRequest request; +// ConfigurationRequest cRequest; +// Collection projects; +// String url; +// String userKey; +// String apiKey; +// +// @Before +// public void setUp() throws Exception { +// url = StringUtils.isNotBlank(System.getenv("MEND_URL")) ? System.getenv("MEND_URL") : "https://saas.whitesourcesoftware.com/agent"; +// apiKey = StringUtils.isNotBlank(System.getenv("MEND_API_KEY")) ? System.getenv("MEND_API_KEY") : "api-key"; +// userKey = StringUtils.isNotBlank(System.getenv("MEND_USER_KEY")) ? System.getenv("MEND_USER_KEY") : "123"; +// AgentProjectInfo project = new AgentProjectInfo(); +// project.setCoordinates(new Coordinates("streaming-test", "streaming-test", "1.0.0")); +// List dependencies = new ArrayList<>(); +// Collection children = new ArrayList<>(); +// +// for (int i = 0; i < 2; i++) { +// DependencyInfo dependency = new DependencyInfo(); +// dependency.setArtifactId("log4j-core"); +// dependency.setGroupId("org.apache.logging.log4j"); +// dependency.setVersion("2.17.1"); +// dependency.setType("jar"); +// dependency.setFilename("log4j-core-2.17.1.jar"); +// dependency.setDependencyType(DependencyType.GRADLE); +// dependency.setDependencyFile("C:\\\\app\\\\build.gradle.kts"); +// dependency.setAdditionalSha1("b6839ce51b64dfefc120600ecb1dc1589ae3ba19"); +// dependency.setSystemPath("C:\\\\.gradle\\\\caches\\\\modules-2\\\\files-2.1\\\\org.apache.logging.log4j\\\\log4j-core\\\\2.17.1\\\\779f60f3844dadc3ef597976fcb1e5127b1f343d\\\\log4j-core-2.17.1.jar"); +// dependency.setSha1("779f60f3844dadc3ef597976fcb1e5127b1f343d"); +// children.add(dependency); +// } +// for (int i = 0; i < 500000; i++) { +// DependencyInfo dependency = new DependencyInfo(); +// dependency.setArtifactId("guava"); +// dependency.setGroupId("com.google.guava"); +// dependency.setVersion("32.1.2-jre"); +// dependency.setAdditionalSha1("c1613a9c5b54c20bbaa93d5f29e36eb2ab39b1ca"); +// dependency.setType("jar"); +// dependency.setFilename("guava-32.1.2-jre.jar"); +// dependency.setDependencyType(DependencyType.GRADLE); +// dependency.setDependencyFile("C:\\\\app\\\\build.gradle.kts"); +// dependency.setSystemPath("C:\\\\.gradle\\\\caches\\\\modules-2\\\\files-2.1\\\\com.google.guava\\\\guava\\\\32.1.2-jre\\\\5e64ec7e056456bef3a4bc4c6fdaef71e8ab6318\\\\guava-32.1.2-jre.jar"); +// dependency.setSha1("5e64ec7e056456bef3a4bc4c6fdaef71e8ab6318"); +// dependency.setChildren(children); +// dependencies.add(dependency); +// } +// project.setDependencies(dependencies); +// projects = new ArrayList(); +// projects.add(project); +// +// +// request = new UpdateInventoryRequest(projects); +// request.setAgent("fs-agent"); +// request.setAgentVersion("2.9.9.90-SNAPSHOT"); +// request.setOrgToken(apiKey); +// request.setUserKey(userKey); +// request.setProduct("streaming-test"); +// request.setTimeStamp(System.currentTimeMillis()); +// request.setPluginVersion("24.1.2"); +// request.setAggregateModules(false); +// request.setPreserveModuleStructure(false); +// request.setUpdateType(UpdateType.OVERRIDE); +// cRequest = new ConfigurationRequest(apiKey,"streaming-test","",userKey,"muhammad.abu-elula@whitesourcesoftware.com","25d61abeb6a94166932aff211a1d929f258ee9b246ca42c5a245e23920ed1d9f"); +// // cRequest.setProjects(projects); +// cRequest.setAgent("fs-agent"); +// cRequest.setAgentVersion("2.9.9.90-SNAPSHOT"); +// cRequest.setOrgToken(apiKey); +// cRequest.setUserKey(userKey); +// cRequest.setProduct("streaming-test"); +// cRequest.setTimeStamp(System.currentTimeMillis()); +// cRequest.setPluginVersion("24.1.2"); +// +// } +// @After +// public void tearDown() throws Exception { +// } +// +// @Test +// @Ignore +// public void createHttpRequest() { +// +// WssStreamServiceClientImpl streamClient = new WssStreamServiceClientImpl(url, false, 60, true); +// try { +// //streamClient.getConfiguration(cRequest); +// streamClient.updateInventory(request); +// +// } catch (Exception e) { +// fail("Exception thrown"); +// } +// +// } +//} \ No newline at end of file diff --git a/wss-agent-hash-calculator/pom.xml b/wss-agent-hash-calculator/pom.xml index 3fe9918c..ad26cdef 100644 --- a/wss-agent-hash-calculator/pom.xml +++ b/wss-agent-hash-calculator/pom.xml @@ -5,12 +5,12 @@ org.whitesource wss-agent-parent - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT org.whitesource wss-agent-hash-calculator - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT @@ -83,5 +83,5 @@ test - - \ No newline at end of file + + diff --git a/wss-agent-report/pom.xml b/wss-agent-report/pom.xml index e8057be1..a9aabcc0 100644 --- a/wss-agent-report/pom.xml +++ b/wss-agent-report/pom.xml @@ -5,7 +5,7 @@ org.whitesource wss-agent-parent - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT wss-agent-report diff --git a/wss-agent-report/src/main/java/org/whitesource/agent/report/OfflineUpdateRequest.java b/wss-agent-report/src/main/java/org/whitesource/agent/report/OfflineUpdateRequest.java index 50ccb6b6..27ad0603 100644 --- a/wss-agent-report/src/main/java/org/whitesource/agent/report/OfflineUpdateRequest.java +++ b/wss-agent-report/src/main/java/org/whitesource/agent/report/OfflineUpdateRequest.java @@ -1,12 +1,12 @@ /** * Copyright (C) 2014 WhiteSource Ltd. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,10 +25,7 @@ import org.whitesource.agent.api.model.contribution.ContributionInfoCollection; import org.whitesource.agent.utils.ZipUtils; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.OutputStreamWriter; +import java.io.*; import java.lang.reflect.Type; import java.util.Collection; import java.util.Map; @@ -64,11 +61,10 @@ public OfflineUpdateRequest(UpdateInventoryRequest request) { /** * The method generates the update request file. * - * @param outputDir Directory where request file will be created. - * @param zip Whether or not to zip the request. + * @param outputDir Directory where request file will be created. + * @param zip Whether or not to zip the request. * @param prettyJson Whether or not to parse the json before writing to file (only if zip is false). - * @param filePath path to the output file; null by default - * + * @param filePath path to the output file; null by default * @return File reference to the resulting request. * @throws java.io.IOException In case of errors during file generation process. */ @@ -80,9 +76,9 @@ public File generate(File outputDir, boolean zip, boolean prettyJson, String fil // prepare working directory File workDir; File requestFile; - if (filePath != null){ + if (filePath != null) { String fileSeparator = System.getProperty("file.separator"); - if (filePath.contains(fileSeparator)){ + if (filePath.contains(fileSeparator)) { requestFile = new File(filePath); String folderName = filePath.substring(0, filePath.lastIndexOf(fileSeparator)); workDir = new File(folderName); @@ -97,40 +93,15 @@ public File generate(File outputDir, boolean zip, boolean prettyJson, String fil if (!workDir.exists() && !workDir.mkdir()) { throw new IOException("Unable to make output directory: " + workDir); } - - String json; - if (zip) { - json = new Gson().toJson(request); - json = ZipUtils.compressString(json); - } else if (prettyJson) { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - /*Gson gson = new GsonBuilder().setPrettyPrinting() - .addSerializationExclusionStrategy(getExclusionStrategy()) - .registerTypeHierarchyAdapter(Collection.class, new CollectionAdapter()).create();*/ - json = gson.toJson(request); - //json = turnRequestToJson(gson); - } else { - json = new Gson().toJson(request); + try (JsonWriter writer = new JsonWriter(new FileWriter(requestFile))) { + Gson gson = new Gson(); + gson.toJson(request, UpdateInventoryRequest.class, writer); } - - - /*ObjectMapper objectMapper = new ObjectMapper(); - String json = objectMapper.writeValueAsString(request);*/ - - /*byte[] serialize = SerializationUtils.serialize(request); - FileUtils.writeByteArrayToFile(requestFile, serialize);*/ - - /*FileOutputStream fileOut = new FileOutputStream(requestFile.getPath()); - ObjectOutputStream objectOut = new ObjectOutputStream(fileOut); - objectOut.writeObject(request); - objectOut.close();*/ - - FileUtils.writeStringToFile(requestFile, json, UTF_8); return requestFile; } // excluding attributes 'optional', 'checksums' & 'deduped' from the json - private ExclusionStrategy getExclusionStrategy(){ + private ExclusionStrategy getExclusionStrategy() { return new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes fieldAttributes) { @@ -181,7 +152,7 @@ private String turnRequestToJson(Gson gson) throws IOException { gson.toJson(contributions, ContributionInfoCollection.class, writer); } - for (AgentProjectInfo agentProjectInfo : this.request.getProjects()){ + for (AgentProjectInfo agentProjectInfo : this.request.getProjects()) { Coordinates coordinates = agentProjectInfo.getCoordinates(); gson.toJson(coordinates, Coordinates.class, writer); Coordinates parentCoordinates = agentProjectInfo.getParentCoordinates(); @@ -194,7 +165,7 @@ private String turnRequestToJson(Gson gson) throws IOException { gson.toJson(projectTags, Collection.class, writer); String projectToken = agentProjectInfo.getProjectToken(); gson.toJson(projectToken, String.class, writer); - for (DependencyInfo dependencyInfo : agentProjectInfo.getDependencies()){ + for (DependencyInfo dependencyInfo : agentProjectInfo.getDependencies()) { gson.toJson(dependencyInfo, DependencyInfo.class, writer); } } diff --git a/wss-agent-utils/pom.xml b/wss-agent-utils/pom.xml index 44deaf1b..4f0d012e 100644 --- a/wss-agent-utils/pom.xml +++ b/wss-agent-utils/pom.xml @@ -5,12 +5,12 @@ org.whitesource wss-agent-parent - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT org.whitesource wss-agent-utils - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT @@ -45,5 +45,5 @@ test - - \ No newline at end of file + + diff --git a/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ByteArrayOutputStreamToInputStream.java b/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ByteArrayOutputStreamToInputStream.java new file mode 100644 index 00000000..97e8243b --- /dev/null +++ b/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ByteArrayOutputStreamToInputStream.java @@ -0,0 +1,33 @@ +package org.whitesource.agent.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ByteArrayOutputStreamToInputStream extends InputStream { + private final ByteArrayOutputStream outputStream; + private int currentPosition; + + public ByteArrayOutputStreamToInputStream(ByteArrayOutputStream outputStream) { + this.outputStream = outputStream; + this.currentPosition = 0; + } + + @Override + public int read() throws IOException { + synchronized (outputStream) { + byte[] buffer = outputStream.toByteArray(); + if (currentPosition < buffer.length) { + return buffer[currentPosition++]; + } else { + return -1; // Indicates end of stream + } + } + } + + @Override + public void close() throws IOException { + // No need to close the underlying ByteArrayOutputStream + // Closing it may have unintended side effects + } +} diff --git a/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ZipUtils.java b/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ZipUtils.java index fb219133..7c11a931 100644 --- a/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ZipUtils.java +++ b/wss-agent-utils/src/main/java/org/whitesource/agent/utils/ZipUtils.java @@ -17,8 +17,11 @@ */ import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Base64InputStream; +import org.apache.commons.codec.binary.Base64OutputStream; import java.io.*; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -169,6 +172,14 @@ public static String compressString(String text) throws IOException { return getStringFromEncode(exportByteArrayOutputStream.toByteArray()); } } + public static String compressAndEncodeString(String text) throws IOException { + try (ByteArrayOutputStream exportByteArrayOutputStream = new ByteArrayOutputStream()) { + fillExportStreamCompress(text, exportByteArrayOutputStream); + return getStringFromEncode(exportByteArrayOutputStream.toByteArray()); + //String base64Encoded = getStringFromEncode(exportByteArrayOutputStream.toByteArray()); + //return URLEncoder.encode(base64Encoded, "UTF-8"); + } + } /** * The method compresses the big strings using gzip - low memory via Streams @@ -188,6 +199,15 @@ public static void compressString(InputStream inputStream, OutputStream outputSt } } + public static void compressOutputStream(PipedInputStream pis, PipedOutputStream pos) throws IOException { + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + fillExportStreamCompress(pis, byteArrayOutputStream); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + org.apache.commons.codec.binary.Base64OutputStream base64OutputStream = new Base64OutputStream(pos, true, -1, null); + byteArrayOutputStream.writeTo(base64OutputStream); + base64OutputStream.close(); + } + } public static String decompressString(String text) throws IOException { StringBuilder stringBuilder = new StringBuilder(); diff --git a/wss-agent-via-api/pom.xml b/wss-agent-via-api/pom.xml index a3d0d864..f0b9a5f0 100644 --- a/wss-agent-via-api/pom.xml +++ b/wss-agent-via-api/pom.xml @@ -3,9 +3,9 @@ wss-agent-parent org.whitesource - 2.9.9.82-SNAPSHOT + 2.9.9.90-SNAPSHOT 4.0.0 wss-agent-via-api - \ No newline at end of file +