diff --git a/resources/default_pipeline_environment.yml b/resources/default_pipeline_environment.yml index c81e2f407..c478181e5 100644 --- a/resources/default_pipeline_environment.yml +++ b/resources/default_pipeline_environment.yml @@ -23,7 +23,8 @@ general: jnlpAgent: 's4sdk/jenkins-agent-k8s:latest' manualConfirmation: true productiveBranch: 'master' - serviceUrl: 'https://saas.whitesourcesoftware.com/api' + whitesource: + serviceUrl: 'https://saas.whitesourcesoftware.com/api' #Steps Specific Configuration steps: diff --git a/src/com/sap/piper/integration/WhitesourceOrgAdminRepository.groovy b/src/com/sap/piper/integration/WhitesourceOrgAdminRepository.groovy index eb1593d44..b8c3a309c 100644 --- a/src/com/sap/piper/integration/WhitesourceOrgAdminRepository.groovy +++ b/src/com/sap/piper/integration/WhitesourceOrgAdminRepository.groovy @@ -95,7 +95,7 @@ class WhitesourceOrgAdminRepository implements Serializable { timeout : config.timeout ] - if (script.env.HTTP_PROXY && !config.serviceUrl.matches('http(s)*://.*\\.sap\\.corp.*')) + if (script.env.HTTP_PROXY) params["httpProxy"] = script.env.HTTP_PROXY if (config.verbose) diff --git a/src/com/sap/piper/integration/WhitesourceRepository.groovy b/src/com/sap/piper/integration/WhitesourceRepository.groovy index b128f7f9b..b7f8569b0 100644 --- a/src/com/sap/piper/integration/WhitesourceRepository.groovy +++ b/src/com/sap/piper/integration/WhitesourceRepository.groovy @@ -218,7 +218,7 @@ class WhitesourceRepository implements Serializable { timeout : config.timeout ] - if (script.env.HTTP_PROXY && !config.serviceUrl.matches('http(s)*://.*\\.sap\\.corp.*')) + if (script.env.HTTP_PROXY) params["httpProxy"] = script.env.HTTP_PROXY if(config.verbose) diff --git a/test/groovy/WhitesourceExecuteScanTest.groovy b/test/groovy/WhitesourceExecuteScanTest.groovy index 73db25fd9..987119bbb 100644 --- a/test/groovy/WhitesourceExecuteScanTest.groovy +++ b/test/groovy/WhitesourceExecuteScanTest.groovy @@ -760,7 +760,7 @@ class WhitesourceExecuteScanTest extends BasePiperTest { } @Test - void testCheckFindingBelowSeven() { + void testCheckFindingBelowThreshold() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ @@ -790,13 +790,55 @@ class WhitesourceExecuteScanTest extends BasePiperTest { securityVulnerabilities : true, orgToken : 'testOrgToken', productName : 'SHC - Piper', - projectNames : [ 'piper-demo - 0.0.1' ] + projectNames : [ 'piper-demo - 0.0.1' ], + cvssSeverityLimit : 7 ]) - assertThat(loggingRule.log, containsString('WARNING: 1 Open Source Software Security vulnerabilities with CVSS score below 7.0 detected.')) + assertThat(loggingRule.log, containsString('WARNING: 1 Open Source Software Security vulnerabilities with CVSS score below 7 detected.')) assertThat(writeFileRule.files['piper_whitesource_vulnerability_report.json'], not(isEmptyOrNullString())) } + @Test + void testCheckFindingAbove() { + helper.registerAllowedMethod("readProperties", [Map], { + def result = new Properties() + result.putAll([ + "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", + "productName": "SHC - Piper", + "checkPolicies": "true", + "projectName": "pipeline-test-node", + "projectVersion": "1.0.0" + ]) + return result + }) + helper.registerAllowedMethod("fetchVulnerabilities", [List], { + return new JsonUtils().parseJsonSerializable("{ \"alerts\": [ { \"vulnerability\": { \"name\": \"CVE-2017-15095\", \"type\": \"CVE\", \"severity\": \"high\", \"score\": 2.1, \"cvss3_severity\": \"high\", \"cvss3_score\": 5.3, \"scoreMetadataVector\": \"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\", \"publishDate\": \"2018-02-06\", \"url\": \"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15095\", \"description\": \"A deserialization flaw was discovered in the jackson-databind in versions before 2.8.10 and 2.9.1, which could allow an unauthenticated user to perform code execution by sending the maliciously crafted input to the readValue method of the ObjectMapper. This issue extends the previous flaw CVE-2017-7525 by blacklisting more classes that could be used maliciously.\", \"topFix\": { \"vulnerability\": \"CVE-2017-15095\", \"type\": \"CHANGE_FILES\", \"origin\": \"GITHUB_COMMIT\", \"url\": \"https://github.com/FasterXML/jackson-databind/commit/60d459ce\"," + + "\"fixResolution\": \"src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java,release-notes/VERSION,src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java\", \"date\": \"2017-04-13\", \"message\": \"Fix #1599 for 2.8.9\\n\\nMerge branch '2.7' into 2.8\", \"extraData\": \"key=60d459c&committerName=cowtowncoder&committerUrl=https://github.com/cowtowncoder&committerAvatar=https://avatars0.githubusercontent.com/u/55065?v=4\" }, \"allFixes\": [ { \"vulnerability\": \"CVE-2017-15095\", \"type\": \"CHANGE_FILES\", \"origin\": \"GITHUB_COMMIT\", \"url\": \"https://github.com/FasterXML/jackson-databind/commit/60d459ce\", \"fixResolution\": \"src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java,release-notes/VERSION,src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java\", \"date\": \"2017-04-13\", \"message\": \"Fix #1599 for 2.8.9\\n\\nMerge branch '2.7' into 2.8\"," + + "\"extraData\": \"key=60d459c&committerName=cowtowncoder&committerUrl=https://github.com/cowtowncoder&committerAvatar=https://avatars0.githubusercontent.com/u/55065?v=4\" }, { \"vulnerability\": \"CVE-2017-15095\", \"type\": \"CHANGE_FILES\", \"origin\": \"GITHUB_COMMIT\", \"url\": \"https://github.com/FasterXML/jackson-databind/commit/e865a7a4464da63ded9f4b1a2328ad85c9ded78b#diff-98084d808198119d550a9211e128a16f\", \"fixResolution\": \"src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java,release-notes/VERSION,src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java\", \"date\": \"2017-12-12\", \"message\": \"Fix #1737 (#1857)\", \"extraData\": \"key=e865a7a&committerName=cowtowncoder&committerUrl=https://github.com/cowtowncoder&committerAvatar=https://avatars0.githubusercontent.com/u/55065?v=4\" }, { \"vulnerability\": \"CVE-2017-15095\", \"type\": \"CHANGE_FILES\", \"origin\": \"GITHUB_COMMIT\"," + + "\"url\": \"https://github.com/FasterXML/jackson-databind/commit/e8f043d1\", \"fixResolution\": \"release-notes/VERSION,src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java\", \"date\": \"2017-06-30\", \"message\": \"Fix #1680\", \"extraData\": \"key=e8f043d&committerName=cowtowncoder&committerUrl=https://github.com/cowtowncoder&committerAvatar=https://avatars0.githubusercontent.com/u/55065?v=4\" } ], \"fixResolutionText\": \"Replace or update the following files: IllegalTypesCheckTest.java, VERSION, BeanDeserializerFactory.java\", \"references\": [] }, \"type\": \"SECURITY_VULNERABILITY\", \"level\": \"MAJOR\", \"library\": { \"keyUuid\": \"13f7802e-8aa1-4303-a5db-1d0c85e871a9\", \"keyId\": 23410061, \"filename\": \"jackson-databind-2.8.8.jar\", \"name\": \"jackson-databind\", \"groupId\": \"com.fasterxml.jackson.core\", \"artifactId\": \"jackson-databind\", \"version\": \"2.8.8\", \"sha1\": \"bf88c7b27e95cbadce4e7c316a56c3efffda8026\"," + + "\"type\": \"Java\", \"references\": { \"url\": \"http://github.com/FasterXML/jackson\", \"issueUrl\": \"https://github.com/FasterXML/jackson-databind/issues\", \"pomUrl\": \"http://repo.jfrog.org/artifactory/list/repo1/com/fasterxml/jackson/core/jackson-databind/2.8.8/jackson-databind-2.8.8.pom\", \"scmUrl\": \"http://github.com/FasterXML/jackson-databind\" }, \"licenses\": [ { \"name\": \"Apache 2.0\", \"url\": \"http://apache.org/licenses/LICENSE-2.0\", \"profileInfo\": { \"copyrightRiskScore\": \"THREE\", \"patentRiskScore\": \"ONE\", \"copyleft\": \"NO\", \"linking\": \"DYNAMIC\", \"royaltyFree\": \"CONDITIONAL\" } } ] }, \"project\": \"pipeline-test - 0.0.1\", \"projectId\": 302194, \"projectToken\": \"1b8fdc36cb6949f482d0fd936a39dab69d6b34f43fff4dda8a9241f2c6e536c7\", \"directDependency\": false, \"description\": \"High:5,\", \"date\": \"2017-11-15\" } ] }").alerts + }) + + try { + stepRule.step.whitesourceExecuteScan([ + script : nullScript, + whitesourceRepositoryStub : whitesourceStub, + whitesourceOrgAdminRepositoryStub: whitesourceOrgAdminRepositoryStub, + descriptorUtilsStub : descriptorUtilsStub, + scanType : 'npm', + juStabUtils : utils, + securityVulnerabilities : true, + orgToken : 'testOrgToken', + productName : 'SHC - Piper', + projectNames : ['piper-demo - 0.0.1'], + cvssSeverityLimit : 0 + ]) + } catch (e) { + assertThat(e.getMessage(), containsString('[whitesourceExecuteScan] 1 Open Source Software Security vulnerabilities with CVSS score greater or equal 0 detected. - ')) + assertThat(writeFileRule.files['piper_whitesource_vulnerability_report.json'], not(isEmptyOrNullString())) + } + } + @Test void testCheckNoFindings() { helper.registerAllowedMethod("readProperties", [Map], { @@ -833,7 +875,6 @@ class WhitesourceExecuteScanTest extends BasePiperTest { @Test void testCheckStatus_0() { - def error = false try { stepRule.step.checkStatus(0, [licensingVulnerabilities: true]) @@ -931,10 +972,10 @@ class WhitesourceExecuteScanTest extends BasePiperTest { void testCheckStatus_vulnerability() { def error = false try { - stepRule.step.checkStatus(0, [licensingVulnerabilities: false, securityVulnerabilities: true, severeVulnerabilities: 5]) + stepRule.step.checkStatus(0, [licensingVulnerabilities: false, securityVulnerabilities: true, severeVulnerabilities: 5, cvssSeverityLimit: 7]) } catch (e) { error = true - assertThat(e.getMessage(), is("[whitesourceExecuteScan] 5 Open Source Software Security vulnerabilities with CVSS score greater or equal 7.0 detected. - ")) + assertThat(e.getMessage(), is("[whitesourceExecuteScan] 5 Open Source Software Security vulnerabilities with CVSS score greater or equal 7 detected. - ")) } assertThat(error, is(true)) } @@ -948,7 +989,7 @@ class WhitesourceExecuteScanTest extends BasePiperTest { error = true } assertThat(error, is(false)) - assertThat(loggingRule.log, containsString("****\r\n[whitesourceExecuteScan] No policy violations found. You can deploy to production, and set the \"Intellectual Property (IP) Scan Plan\" in Sirius to completed. \r\n****")) + assertThat(loggingRule.log, containsString("[whitesourceExecuteScan] No policy violations found")) } @Test diff --git a/vars/whitesourceExecuteScan.groovy b/vars/whitesourceExecuteScan.groovy index 3d32d1600..9058e0de5 100644 --- a/vars/whitesourceExecuteScan.groovy +++ b/vars/whitesourceExecuteScan.groovy @@ -45,12 +45,29 @@ import static com.sap.piper.Prerequisites.checkScript 'stashContent', 'timeout', 'vulnerabilityReportFileName', - 'vulnerabilityReportTitle', - 'whitesourceAccessor' + 'vulnerabilityReportTitle' ] @Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS +@Field Map CONFIG_KEY_COMPATIBILITY = [ + whitesource : [ + 'orgAdminUserTokenCredentialsId' : 'orgAdminUserTokenCredentialsId', + 'orgToken' : 'orgToken', + 'productName' : 'productName', + 'productVersion' : 'productVersion', + 'productToken' : 'productToken', + 'projectNames' : 'projectNames', + 'scanType' : 'scanType', + 'serviceUrl' : 'serviceUrl', + 'userTokenCredentialsId' : 'userTokenCredentialsId' + ], + whitesourceUserTokenCredentialsId : 'userTokenCredentialsId', + whitesourceProductName : 'productName', + whitesourceProjectNames : 'projectNames', + whitesourceProductToken : 'productToken' +] + void call(Map parameters = [:]) { handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) { def script = checkScript(this, parameters) ?: this @@ -61,9 +78,9 @@ void call(Map parameters = [:]) { // load default & individual configuration Map config = ConfigurationHelper.newInstance(this) .loadStepDefaults() - .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) - .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS) - .mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS) + .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY) + .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY) + .mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY) .mixin([ style : libraryResource('piper-os.css') ]) @@ -78,7 +95,7 @@ void call(Map parameters = [:]) { .withMandatoryProperty('productName') .use() - config.cvssSeverityLimit = config.cvssSeverityLimit ? Integer.valueOf(config.cvssSeverityLimit) : -1 + config.cvssSeverityLimit = config.cvssSeverityLimit == null ? -1 : Integer.valueOf(config.cvssSeverityLimit) config.stashContent = utils.unstashAll(config.stashContent) config.projectNames = (config.projectNames instanceof List) ? config.projectNames : config.projectNames?.tokenize(',') parameters.projectNames = config.projectNames @@ -267,7 +284,7 @@ int fetchViolationCount(Map config, WhitesourceRepository repository) { void checkViolationStatus(int violationCount) { if (violationCount == 0) { - echo "****\r\n[${STEP_NAME}] No policy violations found. You can deploy to production, and set the \"Intellectual Property (IP) Scan Plan\" in Sirius to completed. \r\n****" + echo "[${STEP_NAME}] No policy violations found" } else { error "[${STEP_NAME}] Whitesource found ${violationCount} policy violations for your product" }