import com.sap.piper.DescriptorUtils import com.sap.piper.JsonUtils import com.sap.piper.integration.WhitesourceOrgAdminRepository import com.sap.piper.integration.WhitesourceRepository import com.sap.piper.MapUtils import hudson.AbortException import org.hamcrest.Matchers import org.junit.Assert import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.ExpectedException import org.junit.rules.RuleChain import org.springframework.beans.factory.annotation.Autowired import util.* import static org.hamcrest.Matchers.* import static org.junit.Assert.assertThat class WhitesourceExecuteScanTest extends BasePiperTest { private ExpectedException thrown = ExpectedException.none() private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this) private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this) private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this) private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this) private JenkinsStepRule stepRule = new JenkinsStepRule(this) @Rule public RuleChain ruleChain = Rules .getCommonRules(this) .around(new JenkinsReadYamlRule(this)) .around(thrown) .around(dockerExecuteRule) .around(shellRule) .around(loggingRule) .around(writeFileRule) .around(stepRule) .around(new JenkinsCredentialsRule(this) .withCredentials('ID-123456789', 'token-0815') .withCredentials('ID-9876543', 'token-0816')) def whitesourceOrgAdminRepositoryStub def whitesourceStub @Autowired DescriptorUtils descriptorUtilsStub @Before void init() { helper.registerAllowedMethod("archiveArtifacts", [Map.class], { m -> if (m.artifacts == null) { throw new Exception('artifacts cannot be null') } return null }) helper.registerAllowedMethod("findFiles", [Map.class], { map -> return [].toArray() }) whitesourceOrgAdminRepositoryStub = new WhitesourceOrgAdminRepository(nullScript, [whitesource: [serviceUrl: "http://some.host.whitesource.com/api/"]]) LibraryLoadingTestExecutionListener.prepareObjectInterceptors(whitesourceOrgAdminRepositoryStub) whitesourceStub = new WhitesourceRepository(nullScript, [whitesource: [serviceUrl: "http://some.host.whitesource.com/api/"]]) LibraryLoadingTestExecutionListener.prepareObjectInterceptors(whitesourceStub) helper.registerAllowedMethod("fetchProductMetaInfo", [], { return new JsonUtils().jsonStringToGroovyObject("{ \"productVitals\": [{ \"id\": 59639, \"name\": \"SHC - Piper\", \"token\": \"e30132d8e8f04a4c8be6332c75a0ff0580ab326fa7534540ad326e97a74d945b\", \"creationDate\": \"2017-09-20 09:22:46 +0000\", \"lastUpdatedDate\": \"2018-09-19 09:44:40 +0000\" }]}") }) helper.registerAllowedMethod("fetchProjectsMetaInfo", [], { return new JsonUtils().jsonStringToGroovyObject("{ \"projectVitals\": [{ \"id\": 261964, \"name\": \"piper-demo - 0.0.1\", \"token\": \"a2a62e5d7beb4170ad4dccfa3316b5a4cd3fadefc56c49f88fbf9400a09f7d94\", \"creationDate\": \"2017-09-21 00:28:06 +0000\", \"lastUpdatedDate\": \"2017-10-12 01:03:05 +0000\" }]}").projectVitals }) helper.registerAllowedMethod("fetchReportForProduct", [String], { }) helper.registerAllowedMethod( "fetchProjectLicenseAlerts", [Object.class], { return new JsonUtils().jsonStringToGroovyObject("{ \"alerts\": [] }").alerts }) helper.registerAllowedMethod( "fetchProductLicenseAlerts", [], { return new JsonUtils().jsonStringToGroovyObject("{ \"alerts\": [] }").alerts }) helper.registerAllowedMethod( "fetchVulnerabilities", [List], { return new JsonUtils().jsonStringToGroovyObject("{ \"alerts\": [] }").alerts }) helper.registerAllowedMethod( "createProduct", [], { return new JsonUtils().jsonStringToGroovyObject("{ \"productToken\": \"e30132d8e8f04a4c8be6332c75a0ff0580ab326fa7534540ad326e97a74d945b\" }") }) helper.registerAllowedMethod( "publishHTML", [Map], {}) helper.registerAllowedMethod( "getNpmGAV", [String], {return [group: 'com.sap.node', artifact: 'test-node', version: '1.2.3']}) helper.registerAllowedMethod( "getSbtGAV", [String], {return [group: 'com.sap.sbt', artifact: 'test-scala', version: '1.2.3']}) helper.registerAllowedMethod( "getPipGAV", [String], {return [artifact: 'test-python', version: '1.2.3']}) helper.registerAllowedMethod( "getMavenGAV", [String], {return [group: 'com.sap.maven', artifact: 'test-java', version: '1.2.3']}) helper.registerAllowedMethod( "getDubGAV", [String], {return [group: 'com.sap.dlang', artifact: 'test-dub', version: '1.2.3']}) nullScript.commonPipelineEnvironment.configuration = nullScript.commonPipelineEnvironment.configuration ?: [:] nullScript.commonPipelineEnvironment.configuration['steps'] = nullScript.commonPipelineEnvironment.configuration['steps'] ?: [:] nullScript.commonPipelineEnvironment.configuration['steps']['whitesourceExecuteScan'] = nullScript.commonPipelineEnvironment.configuration['steps']['whitesourceExecuteScan'] ?: [:] nullScript.commonPipelineEnvironment.configuration['general'] = nullScript.commonPipelineEnvironment.configuration['general'] ?: [:] nullScript.commonPipelineEnvironment.configuration['general']['whitesource'] = nullScript.commonPipelineEnvironment.configuration['general']['whitesource'] ?: [:] nullScript.commonPipelineEnvironment.configuration['general']['whitesource']['serviceUrl'] = "http://some.host.whitesource.com/api/" nullScript.commonPipelineEnvironment.configuration['general']['whitesource']['userTokenCredentialsId'] = 'ID-123456789' nullScript.commonPipelineEnvironment.configuration['steps']['whitesourceExecuteScan']['userTokenCredentialsId'] = 'ID-123456789' } @Test void testDockerFromCustomStepConfiguration() { def expectedImage = 'image:test' def expectedEnvVars = ['env1': 'value1', 'env2': 'value2'] def expectedOptions = '--opt1=val1 --opt2=val2 --opt3' def expectedWorkspace = '/path/to/workspace' helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "1.0.0" ]) return result }) nullScript.commonPipelineEnvironment.configuration = MapUtils.merge(nullScript.commonPipelineEnvironment.configuration, [steps:[whitesourceExecuteScan:[ dockerImage: expectedImage, dockerOptions: expectedOptions, dockerEnvVars: expectedEnvVars, dockerWorkspace: expectedWorkspace ]]] ) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'maven', juStabUtils : utils, orgToken : 'testOrgToken', whitesourceProductName : 'testProduct' ]) assert expectedImage == dockerExecuteRule.dockerParams.dockerImage assert expectedOptions == dockerExecuteRule.dockerParams.dockerOptions assert expectedEnvVars.equals(dockerExecuteRule.dockerParams.dockerEnvVars) assert expectedWorkspace == dockerExecuteRule.dockerParams.dockerWorkspace } @Test void testMaven() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "1.0.0" ]) return result }) def publishHtmlMap = [:] helper.registerAllowedMethod("publishHTML", [Map.class], { m -> publishHtmlMap = m return null }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'maven', juStabUtils : utils, orgToken : 'testOrgToken', whitesourceProductName : 'testProduct' ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'maven:3.5-jdk-8')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/java')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'modified whitesource config d3aa80454919391024374ba46b4df082d15ab9a3'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProduct\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProduct')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) } @Test void testNpm() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "devDep": "false", "checkPolicies": "true", "projectName": "pipeline-test-node", "projectVersion": "1.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'npm', juStabUtils : utils, orgToken : 'testOrgToken', productName : 'testProductName', productToken : 'testProductToken', reporting : false ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'node:lts-stretch')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/node')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'modified whitesource config d3aa80454919391024374ba46b4df082d15ab9a3'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('curl --location --output jvm.tar.gz https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.2/sapmachine-jre-11.0.2_linux-x64_bin.tar.gz && tar --strip-components=1 -xzf jvm.tar.gz'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productToken=testProductToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productVersion=1')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('projectName=com.sap.node.test-node')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) } @Test void testNpmWithCustomConfigAndFilePath() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "devDep": "false", "checkPolicies": "true", "projectName": "pipeline-test-node", "projectVersion": "1.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'npm', productName : 'SHC - Piper', configFilePath : './../../testConfigPath', file : 'package.json', juStabUtils : utils, orgToken : 'b39d1328-52e2-42e3-98f0-932709daf3f0' ]) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('curl --location --output jvm.tar.gz https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.2/sapmachine-jre-11.0.2_linux-x64_bin.tar.gz && tar --strip-components=1 -xzf jvm.tar.gz'), is('./bin/java -jar wss-unified-agent.jar -c \'./../../testConfigPath.2766cacc0cf1449dd4034385f4a9f0a6fdb755cf\' -apiKey \'b39d1328-52e2-42e3-98f0-932709daf3f0\' -userKey \'token-0815\' -product \'SHC - Piper\'') )) } @Test void testPip() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "1.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'pip', juStabUtils : utils, orgToken : 'testOrgToken', productName : 'testProductName', reporting : false ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'python:3.7.2-stretch')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/python')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'modified whitesource config d3aa80454919391024374ba46b4df082d15ab9a3'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('curl --location --output jvm.tar.gz https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.2/sapmachine-jre-11.0.2_linux-x64_bin.tar.gz && tar --strip-components=1 -xzf jvm.tar.gz'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productVersion=1')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('projectName=test-python')) } @Test void testWithOrgAdminCredentials() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "1.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'pip', juStabUtils : utils, orgToken : 'testOrgToken', productName : 'testProductName', orgAdminUserTokenCredentialsId : 'ID-9876543', reporting : false ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'python:3.7.2-stretch')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/python')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'modified whitesource config d3aa80454919391024374ba46b4df082d15ab9a3'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('curl --location --output jvm.tar.gz https://github.com/SAP/SapMachine/releases/download/sapmachine-11.0.2/sapmachine-jre-11.0.2_linux-x64_bin.tar.gz && tar --strip-components=1 -xzf jvm.tar.gz'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productVersion=1')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('projectName=test-python')) } @Test void testNoProjectNoCreation() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "1.0.0" ]) return result }) def errorCaught = false try { stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub: whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'pip', juStabUtils : utils, orgToken : 'testOrgToken', productName : 'testProductName', createProductFromPipeline : false, orgAdminUserTokenCredentialsId : 'ID-9876543', reporting : false ]) } catch (e) { errorCaught = true assertThat(e, isA(AbortException.class)) assertThat(e.getMessage(), is("[WhiteSource] Could not fetch/find requested product 'testProductName' and automatic creation has been disabled")) } assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(errorCaught, is(true)) } @Test void testSbt() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "1.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'sbt', juStabUtils : utils, productName : 'testProductName', orgToken : 'testOrgToken', reporting : false ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'hseeberger/scala-sbt:8u181_2.12.8_1.2.8')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/scala')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'modified whitesource config d3aa80454919391024374ba46b4df082d15ab9a3'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productVersion=1')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('projectName=com.sap.sbt.test-scala')) } @Test void testDub() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "2.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'dub', juStabUtils : utils, productName : 'testProductName', orgToken : 'testOrgToken', reporting : false ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: checkmarx')) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) } @Test void testGo() { nullScript.commonPipelineEnvironment.gitHttpsUrl = 'https://github.com/test/golang' helper.registerAllowedMethod("readFile", [Map.class], { map -> def path = 'test/resources/DescriptorUtils/go/' + map.file.substring(map.file.lastIndexOf('/') + 1, map.file.length()) def descriptorFile = new File(path) if(descriptorFile.exists()) return descriptorFile.text else return null }) helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "2.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'golang', juStabUtils : utils, productName : 'testProductName', orgToken : 'testOrgToken', reporting : false, buildDescriptorFile : './myProject/glide.yaml' ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'golang:1.12-stretch')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/dep')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'checkmarx', 'modified whitesource config 7d1c90ed46c66061fc8ea45dd96e209bf767f038'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('./bin/java -jar wss-unified-agent.jar -c \'./myProject/wss-unified-agent.config.7d1c90ed46c66061fc8ea45dd96e209bf767f038\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./myProject/wss-unified-agent.config.7d1c90ed46c66061fc8ea45dd96e209bf767f038'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./myProject/wss-unified-agent.config.7d1c90ed46c66061fc8ea45dd96e209bf767f038'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./myProject/wss-unified-agent.config.7d1c90ed46c66061fc8ea45dd96e209bf767f038'], containsString('userKey=token-0815')) assertThat(writeFileRule.files['./myProject/wss-unified-agent.config.7d1c90ed46c66061fc8ea45dd96e209bf767f038'], containsString('productVersion=1')) assertThat(writeFileRule.files['./myProject/wss-unified-agent.config.7d1c90ed46c66061fc8ea45dd96e209bf767f038'], containsString('projectName=github.com/test/golang.myProject')) } @Test void testGoDefaults() { nullScript.commonPipelineEnvironment.gitHttpsUrl = 'https://github.com/test/golang' helper.registerAllowedMethod("readFile", [Map.class], { map -> def path = 'test/resources/DescriptorUtils/go/' + map.file.substring(map.file.lastIndexOf('/') + 1, map.file.length()) def descriptorFile = new File(path) if(descriptorFile.exists()) return descriptorFile.text else return null }) helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "2.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'golang', juStabUtils : utils, productName : 'testProductName', orgToken : 'testOrgToken', reporting : false ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerImage', 'golang:1.12-stretch')) assertThat(dockerExecuteRule.dockerParams, hasEntry('dockerWorkspace', '/home/dep')) assertThat(dockerExecuteRule.dockerParams, hasEntry('stashContent', ['buildDescriptor', 'opensourceConfiguration', 'checkmarx', 'modified whitesource config d3aa80454919391024374ba46b4df082d15ab9a3'])) assertThat(shellRule.shell, Matchers.hasItems( is('curl --location --output wss-unified-agent.jar https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar'), is('./bin/java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\'') )) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('apiKey=testOrgToken')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productName=testProductName')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('userKey=token-0815')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('productVersion=1')) assertThat(writeFileRule.files['./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3'], containsString('projectName=github.com/test/golang')) } @Test void testAgentNoDownloads() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "2.0.0" ]) return result }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'maven', agentDownloadUrl : '', jreDownloadUrl : '', agentParameters : 'testParams', juStabUtils : utils, orgToken : 'testOrgToken', productName : 'testProductName' ]) assertThat(shellRule.shell[0], is('java -jar wss-unified-agent.jar -c \'./wss-unified-agent.config.d3aa80454919391024374ba46b4df082d15ab9a3\' -apiKey \'testOrgToken\' -userKey \'token-0815\' -product \'testProductName\' testParams')) } @Test void testMta() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "2.0.0" ]) return result }) helper.registerAllowedMethod("findFiles", [Map.class], { map -> if (map.glob == "**${File.separator}pom.xml") { return [new File('maven1/pom.xml'), new File('maven2/pom.xml')].toArray() } if (map.glob == "**${File.separator}package.json") { return [new File('npm1/package.json'), new File('npm2/package.json')].toArray() } if (map.glob == "**${File.separator}setup.py") { return [new File('pip/setup.py')].toArray() } return [].toArray() }) def whitesourceCalls = [] helper.registerAllowedMethod("whitesourceExecuteScan", [Map.class], { map -> whitesourceCalls.add(map) stepRule.step.call(map) }) def parallelMap = [:] helper.registerAllowedMethod("parallel", [Map.class], { map -> parallelMap = map parallelMap['Whitesource - maven1']() parallelMap['Whitesource - npm1']() parallelMap['Whitesource - pip']() }) //need to use call due to mock above stepRule.step.call([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, scanType : 'mta', whitesource: [ productName : 'SHC - Piper', orgToken : 'b39d1328-52e2-42e3-98f0-932709daf3f0' ], buildDescriptorExcludeList : ["maven2${File.separator}pom.xml".toString(), "npm2${File.separator}package.json".toString()], reporting : true, juStabUtils : utils ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(parallelMap, hasKey('Whitesource - maven1')) assertThat(parallelMap, hasKey('Whitesource - npm1')) assertThat(parallelMap, hasKey('Whitesource - pip')) assertThat(parallelMap.keySet(), hasSize(4)) assertThat(whitesourceCalls, contains( allOf( hasEntry('scanType', 'maven'), hasEntry('buildDescriptorFile', "maven1${File.separator}pom.xml".toString()) ), allOf( hasEntry('scanType', 'npm'), hasEntry('buildDescriptorFile', "npm1${File.separator}package.json".toString()) ), allOf( hasEntry('scanType', 'pip'), hasEntry('buildDescriptorFile', "pip${File.separator}setup.py".toString()) ) ) ) assertThat(whitesourceCalls[0]['whitesource']['projectNames'], contains("com.sap.maven.test-java - 1", "com.sap.node.test-node - 1", "test-python - 1")) assertThat(whitesourceCalls[1]['whitesource']['projectNames'], contains("com.sap.maven.test-java - 1", "com.sap.node.test-node - 1", "test-python - 1")) assertThat(whitesourceCalls[2]['whitesource']['projectNames'], contains("com.sap.maven.test-java - 1", "com.sap.node.test-node - 1", "test-python - 1")) } @Test void testMtaBlocks() { helper.registerAllowedMethod("findFiles", [Map.class], { map -> if (map.glob == "**${File.separator}pom.xml") { return [new File('maven1/pom.xml'), new File('maven2/pom.xml')].toArray() } if (map.glob == "**${File.separator}package.json") { return [new File('npm1/package.json'), new File('npm2/package.json'), new File('npm3/package.json'), new File('npm4/package.json')].toArray() } return [].toArray() }) def whitesourceCalls = [] helper.registerAllowedMethod("whitesourceExecuteScan", [Map.class], { map -> whitesourceCalls.add(map) }) def invocation = 0 def parallelMap = [:] helper.registerAllowedMethod("parallel", [Map.class], { map -> parallelMap[invocation] = map for(i = 0; i < parallelMap[invocation].keySet().size(); i++) { def key = parallelMap[invocation].keySet()[i] if(key != "failFast") parallelMap[invocation][key]() } invocation++ }) //need to use call due to mock above stepRule.step.call([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, scanType : 'mta', productName : 'SHC - Piper', buildDescriptorExcludeList : ["maven2${File.separator}pom.xml".toString()], juStabUtils : utils, parallelLimit : 3, orgToken : 'b39d1328-52e2-42e3-98f0-932709daf3f0' ]) assertThat(loggingRule.log, containsString('Unstash content: buildDescriptor')) assertThat(loggingRule.log, containsString('Unstash content: opensourceConfiguration')) assertThat(invocation, is(2)) assertThat(parallelMap[0], hasKey('Whitesource - maven1')) assertThat(parallelMap[0], hasKey('Whitesource - npm1')) assertThat(parallelMap[0], hasKey('Whitesource - npm2')) assertThat(parallelMap[0].keySet(), hasSize(4)) assertThat(parallelMap[1], hasKey('Whitesource - npm3')) assertThat(parallelMap[1], hasKey('Whitesource - npm4')) assertThat(parallelMap[1].keySet(), hasSize(3)) assertThat(whitesourceCalls, hasItem(allOf( hasEntry('scanType', 'maven'), hasEntry('buildDescriptorFile', "maven1${File.separator}pom.xml".toString()) ))) assertThat(whitesourceCalls, hasItem(allOf( hasEntry('scanType', 'npm'), hasEntry('buildDescriptorFile', "npm1${File.separator}package.json".toString()) ))) assertThat(whitesourceCalls, hasItem(allOf( hasEntry('scanType', 'npm'), hasEntry('buildDescriptorFile', "npm2${File.separator}package.json".toString()) ))) assertThat(whitesourceCalls, hasItem(allOf( hasEntry('scanType', 'npm'), hasEntry('buildDescriptorFile', "npm3${File.separator}package.json".toString()) ))) assertThat(whitesourceCalls, hasItem(allOf( hasEntry('scanType', 'npm'), hasEntry('buildDescriptorFile', "npm4${File.separator}package.json".toString()) ))) } @Test void testMtaSingleExclude() { helper.registerAllowedMethod("findFiles", [Map.class], { map -> if (map.glob == "**${File.separator}pom.xml") { return [new File('maven1/pom.xml'), new File('maven2/pom.xml')].toArray() } if (map.glob == "**${File.separator}package.json") { return [new File('npm1/package.json'), new File('npm2/package.json')].toArray() } return [].toArray() }) def parallelMap = [:] helper.registerAllowedMethod("parallel", [Map.class], { map -> parallelMap = map }) stepRule.step.whitesourceExecuteScan([ script : nullScript, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, scanType : 'mta', productName : 'SHC - Piper', buildDescriptorExcludeList : "maven2${File.separator}pom.xml", juStabUtils : utils, orgToken : 'b39d1328-52e2-42e3-98f0-932709daf3f0' ]) assertThat(parallelMap.keySet(), hasSize(4)) } @Test void testPassProjectNamesToCPE() { helper.registerAllowedMethod("findFiles", [Map.class], { map -> if (map.glob == "**${File.separator}pom.xml") { return [new File('maven1/pom.xml'), new File('maven2/pom.xml')].toArray() } if (map.glob == "**${File.separator}package.json") { return [new File('npm1/package.json'), new File('npm2/package.json'), new File('npm3/package.json'), new File('npm4/package.json')].toArray() } return [].toArray() }) helper.registerAllowedMethod("parallel", [Map.class], { map -> map.each {m -> if (m.key != 'failFast') { m.value() } } }) helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() return result }) //need to use call due to mock above stepRule.step.call([ script : nullScript, descriptorUtilsStub : descriptorUtilsStub, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub: whitesourceOrgAdminRepositoryStub, scanType : 'mta', productName : 'SHC - Piper', buildDescriptorExcludeList : ["maven2${File.separator}pom.xml".toString()], juStabUtils : utils, orgToken : 'b39d1328-52e2-42e3-98f0-932709daf3f0' ]) assertThat(nullScript.commonPipelineEnvironment.getValue('whitesourceProjectNames'), hasItem('com.sap.maven.test-java - 1')) assertThat(nullScript.commonPipelineEnvironment.getValue('whitesourceProjectNames'), hasItem('com.sap.node.test-node - 1')) } @Test void testNPMStatusCheckScanException() { thrown.expect(AbortException.class) stepRule.step.checkStatus(-1 & 0xFF, [whitesource:[licensingVulnerabilities: true]]) } @Test void testNPMStatusCheckPolicyViolation() { thrown.expect(AbortException.class) stepRule.step.checkStatus(-2 & 0xFF, [whitesource:[licensingVulnerabilities: true]]) } @Test void testNPMStatusCheckNoPolicyViolation() { stepRule.step.checkStatus(-2 & 0xFF, [whitesource:[licensingVulnerabilities: false]]) } @Test void testNPMStatusCheckClientException() { thrown.expect(AbortException.class) stepRule.step.checkStatus(-3 & 0xFF, [whitesource:[licensingVulnerabilities: true]]) } @Test void testNPMStatusCheckConnectionException() { thrown.expect(AbortException.class) stepRule.step.checkStatus(-4 & 0xFF, [whitesource:[licensingVulnerabilities: true]]) } @Test void testNPMStatusCheckServerException() { thrown.expect(AbortException.class) stepRule.step.checkStatus(-3 & 0xFF, [whitesource:[licensingVulnerabilities: true]]) } @Test void testViolationPolicy() { stepRule.step.checkViolationStatus(0) } @Test void testViolationPolicyException() { thrown.expect(AbortException.class) thrown.expectMessage("1") stepRule.step.checkViolationStatus(1) } @Test void testFetchViolationCountProject() { def config = [projectNames: ["piper-java-cc - 0.0.1", "pipeline-test - 0.0.1"], productToken: "product-token"] def projectTokens = [[token:"abc-project-token"],[token:"def-project-token"]] helper.registerAllowedMethod('fetchProjectsMetaInfo', [], { return projectTokens }) helper.registerAllowedMethod('fetchProjectLicenseAlerts', [String], { projectToken -> if(projectToken == projectTokens[0].token) return [alerts: []] if(projectToken == projectTokens[1].token) return [alerts: []] }) def violationCount = stepRule.step.fetchViolationCount(config, whitesourceStub) Assert.assertTrue(violationCount == 0) } @Test void testFetchViolationCountProjectNotZero() { def config = [whitesource: [projectNames: ["piper-java-cc - 0.0.1", "pipeline-test - 0.0.1"]]] def projectTokens = [[token:"abc-project-token"],[token:"def-project-token"]] helper.registerAllowedMethod('fetchProjectsMetaInfo', [], { return projectTokens }) helper.registerAllowedMethod('fetchProjectLicenseAlerts', [String], { projectToken -> if(projectToken == projectTokens[0].token) return [alerts: [{}, {}]] if(projectToken == projectTokens[1].token) return [alerts: [{}, {}, {}]] }) def violationCount = stepRule.step.fetchViolationCount(config, whitesourceStub) Assert.assertTrue(violationCount == 5) } @Test void testFetchViolationCountProduct() { def config = [:] helper.registerAllowedMethod('fetchProductLicenseAlerts', [], { return [alerts: []] }) def violationCount = stepRule.step.fetchViolationCount(config, whitesourceStub) Assert.assertTrue(violationCount == 0) } @Test void testFetchViolationCountProductNotZero() { def config = [:] helper.registerAllowedMethod('fetchProductLicenseAlerts', [], { return [alerts: [{}, {}]]}) def violationCount = stepRule.step.fetchViolationCount(config, whitesourceStub) Assert.assertTrue(violationCount == 2) } @Test void testCheckException() { helper.registerAllowedMethod("readProperties", [Map], { def result = new Properties() result.putAll([ "apiKey": "b39d1328-52e2-42e3-98f0-932709daf3f0", "productName": "SHC - Piper", "checkPolicies": "true", "projectName": "python-test", "projectVersion": "2.0.0" ]) return result }) helper.registerAllowedMethod("fetchVulnerabilities", [List], { return new JsonUtils().jsonStringToGroovyObject("""{"alerts":[{"vulnerability":{"name":"CVE-2017-15095","type":"CVE","severity":"high","score":7.5,"cvss3_severity":"high","cvss3_score":9.8,"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 }) thrown.expect(AbortException.class) stepRule.step.whitesourceExecuteScan([ script : nullScript, scanType : 'npm', juStabUtils : utils, securityVulnerabilities : true, whitesourceRepositoryStub : whitesourceStub, whitesourceOrgAdminRepositoryStub : whitesourceOrgAdminRepositoryStub, descriptorUtilsStub : descriptorUtilsStub, cvssSeverityLimit : 7, orgToken : 'testOrgToken', productName : 'SHC - Piper', projectNames : [ 'piper-demo - 0.0.1' ] ]) } @Test void testCheckFindingBelowThreshold() { 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": "2.0.0" ]) return result }) helper.registerAllowedMethod("fetchVulnerabilities", [List], { return new JsonUtils().jsonStringToGroovyObject("""{ \"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 }) 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 : 7 ]) 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": "2.0.0" ]) return result }) helper.registerAllowedMethod("fetchVulnerabilities", [List], { return new JsonUtils().jsonStringToGroovyObject("""{ \"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 }) thrown.expect(AbortException) thrown.expectMessage('[whitesourceExecuteScan] 1 Open Source Software Security vulnerabilities with CVSS score greater or equal 0 detected. - ') 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 ]) assertThat(writeFileRule.files['piper_whitesource_vulnerability_report.json'], not(isEmptyOrNullString())) } @Test void testCheckNoFindings() { 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": "2.0.0" ]) return result }) helper.registerAllowedMethod("fetchVulnerabilities", [Object.class], { return new JsonUtils().jsonStringToGroovyObject("{ \"alerts\": [] }").alerts }) 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' ] ]) assertThat(loggingRule.log, containsString('No Open Source Software Security vulnerabilities detected.')) assertThat(writeFileRule.files['piper_whitesource_vulnerability_report.json'], not(isEmptyOrNullString())) } @Test void testCheckStatus_0() { stepRule.step.checkStatus(0, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_255() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] The scan resulted in an error") stepRule.step.checkStatus(255, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_254() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] Whitesource found one or multiple policy violations") stepRule.step.checkStatus(254, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_253() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] The local scan client failed to execute the scan") stepRule.step.checkStatus(253, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_252() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] There was a failure in the connection to the WhiteSource servers") stepRule.step.checkStatus(252, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_251() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] The server failed to analyze the scan") stepRule.step.checkStatus(251, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_250() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] Pre-step failure") stepRule.step.checkStatus(250, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_127() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] Whitesource scan failed with unknown error code '127'") stepRule.step.checkStatus(127, [whitesource:[licensingVulnerabilities: true]]) } @Test void testCheckStatus_vulnerability() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] 5 Open Source Software Security vulnerabilities with CVSS score greater or equal 7 detected. - ") stepRule.step.checkStatus(0, [whitesource:[licensingVulnerabilities: false, securityVulnerabilities: true, severeVulnerabilities: 5, cvssSeverityLimit: 7]]) } @Test void testCheckViolationStatus_0() { stepRule.step.checkViolationStatus(0) assertThat(loggingRule.log, containsString ("[whitesourceExecuteScan] No policy violations found")) } @Test void testCheckViolationStatus_5() { thrown.expect(AbortException) thrown.expectMessage("[whitesourceExecuteScan] Whitesource found 5 policy violations for your product") stepRule.step.checkViolationStatus(5) } }