@contrast/contrast 1.0.23 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -138
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -19
- package/dist/audit/save.js +6 -1
- package/dist/cliConstants.js +49 -0
- package/dist/commands/audit/auditController.js +2 -1
- package/dist/commands/audit/help.js +2 -3
- package/dist/commands/audit/processAudit.js +2 -0
- package/dist/commands/audit/saveFile.js +5 -1
- package/dist/commands/{fingerprint → github}/processFingerprint.js +6 -2
- package/dist/commands/github/projectGroup.js +174 -0
- package/dist/commands/github/repoServices.js +70 -0
- package/dist/common/HTTPClient.js +165 -13
- package/dist/common/errorHandling.js +1 -1
- package/dist/constants/constants.js +3 -5
- package/dist/constants/locales.js +7 -3
- package/dist/index.js +4 -4
- package/dist/lambda/lambda.js +3 -1
- package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +3 -3
- package/dist/scaAnalysis/common/scaServicesUpload.js +77 -7
- package/dist/scaAnalysis/common/treeUpload.js +19 -5
- package/dist/scaAnalysis/go/goAnalysis.js +6 -1
- package/dist/scaAnalysis/java/index.js +6 -1
- package/dist/scaAnalysis/javascript/index.js +5 -2
- package/dist/scaAnalysis/legacy/legacyFlow.js +33 -0
- package/dist/scaAnalysis/php/index.js +8 -2
- package/dist/scaAnalysis/processServicesFlow.js +39 -0
- package/dist/scaAnalysis/python/analysis.js +10 -4
- package/dist/scaAnalysis/python/index.js +6 -1
- package/dist/scaAnalysis/repoMode/index.js +2 -2
- package/dist/scaAnalysis/ruby/analysis.js +10 -1
- package/dist/scaAnalysis/ruby/index.js +6 -1
- package/dist/scaAnalysis/scaAnalysis.js +47 -25
- package/dist/scan/autoDetection.js +47 -4
- package/dist/scan/fileUtils.js +5 -4
- package/dist/utils/commonApi.js +26 -1
- package/dist/utils/settingsHelper.js +14 -0
- package/package.json +8 -5
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +3 -22
- package/src/audit/save.js +10 -1
- package/src/cliConstants.js +52 -0
- package/src/commands/audit/auditController.js +2 -1
- package/src/commands/audit/help.js +2 -3
- package/src/commands/audit/processAudit.js +2 -0
- package/src/commands/audit/saveFile.js +6 -1
- package/src/commands/{fingerprint → github}/processFingerprint.js +8 -2
- package/src/commands/github/projectGroup.js +198 -0
- package/src/commands/github/repoServices.js +80 -0
- package/src/common/HTTPClient.js +221 -13
- package/src/common/errorHandling.js +2 -2
- package/src/constants/constants.js +3 -5
- package/src/constants/locales.js +9 -3
- package/src/index.ts +5 -5
- package/src/lambda/lambda.ts +3 -1
- package/src/lambda/lambdaUtils.ts +1 -1
- package/src/scaAnalysis/common/commonReportingFunctionsSca.js +3 -3
- package/src/scaAnalysis/common/scaServicesUpload.js +92 -7
- package/src/scaAnalysis/common/treeUpload.js +20 -5
- package/src/scaAnalysis/go/goAnalysis.js +6 -1
- package/src/scaAnalysis/java/index.js +6 -1
- package/src/scaAnalysis/javascript/index.js +6 -4
- package/src/scaAnalysis/legacy/legacyFlow.js +48 -0
- package/src/scaAnalysis/php/index.js +8 -2
- package/src/scaAnalysis/processServicesFlow.js +61 -0
- package/src/scaAnalysis/python/analysis.js +10 -4
- package/src/scaAnalysis/python/index.js +6 -1
- package/src/scaAnalysis/repoMode/index.js +2 -2
- package/src/scaAnalysis/ruby/analysis.js +11 -1
- package/src/scaAnalysis/ruby/index.js +6 -1
- package/src/scaAnalysis/scaAnalysis.js +61 -37
- package/src/scan/autoDetection.js +50 -5
- package/src/scan/fileUtils.js +5 -4
- package/src/utils/commonApi.js +29 -1
- package/src/utils/settingsHelper.js +16 -0
- /package/dist/commands/{fingerprint → github}/fingerprintConfig.js +0 -0
- /package/src/commands/{fingerprint → github}/fingerprintConfig.js +0 -0
package/src/index.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { processAudit } from './commands/audit/processAudit'
|
|
|
5
5
|
import { processAuth } from './commands/auth/auth'
|
|
6
6
|
import { processConfig } from './commands/config/config'
|
|
7
7
|
import { processScan } from './commands/scan/processScan'
|
|
8
|
-
import { processFingerprint } from './commands/fingerprint/processFingerprint'
|
|
9
8
|
import constants from './cliConstants'
|
|
10
9
|
import { APP_NAME, APP_VERSION } from './constants/constants'
|
|
11
10
|
import { processLambda } from './lambda/lambda'
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
import { findCommandOnError } from './common/errorHandling'
|
|
18
17
|
import { sendTelemetryConfigAsConfObj } from './telemetry/telemetry'
|
|
19
18
|
import { processLearn } from './commands/learn/processLearn'
|
|
19
|
+
import { processFingerprint } from './commands/github/processFingerprint'
|
|
20
20
|
const {
|
|
21
21
|
commandLineDefinitions: { mainUsageGuide, mainDefinition }
|
|
22
22
|
} = constants
|
|
@@ -84,14 +84,14 @@ const start = async () => {
|
|
|
84
84
|
return await processAudit(config, argvMain)
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
if (command === 'learn') {
|
|
88
|
-
return processLearn()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
87
|
if (command === 'fingerprint') {
|
|
92
88
|
return await processFingerprint(config, argvMain)
|
|
93
89
|
}
|
|
94
90
|
|
|
91
|
+
if (command === 'learn') {
|
|
92
|
+
return processLearn()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
95
|
if (
|
|
96
96
|
command === 'help' ||
|
|
97
97
|
argvMain.includes('--help') ||
|
package/src/lambda/lambda.ts
CHANGED
|
@@ -126,7 +126,9 @@ const processLambda = async (argv: string[]) => {
|
|
|
126
126
|
|
|
127
127
|
const getAvailableFunctions = async (lambdaOptions: LambdaOptions) => {
|
|
128
128
|
const lambdas = await getAllLambdas(lambdaOptions)
|
|
129
|
-
printAvailableLambdas(lambdas, {
|
|
129
|
+
printAvailableLambdas(lambdas, {
|
|
130
|
+
runtimes: ['python', 'java', 'node', 'dotnet']
|
|
131
|
+
})
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
|
|
@@ -11,7 +11,7 @@ import ora from '../utils/oraWrapper'
|
|
|
11
11
|
import { LambdaOptions } from './lambda'
|
|
12
12
|
import { log, getReadableFileSize } from './logUtils'
|
|
13
13
|
|
|
14
|
-
type RuntimeLanguage = 'java' | 'python' | 'node'
|
|
14
|
+
type RuntimeLanguage = 'java' | 'python' | 'node' | 'dotnet'
|
|
15
15
|
|
|
16
16
|
type FilterLambdas = {
|
|
17
17
|
runtimes: RuntimeLanguage[]
|
|
@@ -142,12 +142,12 @@ const printFormattedOutputSca = (
|
|
|
142
142
|
`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
|
|
143
143
|
)
|
|
144
144
|
|
|
145
|
-
if (config.host !== CE_URL) {
|
|
145
|
+
if (config.host !== CE_URL && config.projectId) {
|
|
146
146
|
console.log(
|
|
147
|
-
'\n' + chalk.bold(
|
|
147
|
+
'\n' + chalk.bold("Check out your project's results in Contrast")
|
|
148
148
|
)
|
|
149
149
|
console.log(
|
|
150
|
-
`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/
|
|
150
|
+
`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/libraries?view=static&projects=${config.name}`
|
|
151
151
|
)
|
|
152
152
|
}
|
|
153
153
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
const commonApi = require('../../utils/commonApi')
|
|
2
2
|
const { APP_VERSION } = require('../../constants/constants')
|
|
3
3
|
const requestUtils = require('../../utils/requestUtils')
|
|
4
|
+
const { performance } = require('perf_hooks')
|
|
4
5
|
|
|
5
|
-
const scaTreeUpload = async (analysis, config) => {
|
|
6
|
+
const scaTreeUpload = async (analysis, config, reportSpinner) => {
|
|
7
|
+
if (config.projectId === '') {
|
|
8
|
+
console.log(
|
|
9
|
+
'We were unable to create/locate a project for this manifest, please try again or run with --debug for more information'
|
|
10
|
+
)
|
|
11
|
+
process.exit(1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
config.language = config.language === 'JAVASCRIPT' ? 'NODE' : config.language
|
|
15
|
+
const startTime = performance.now()
|
|
16
|
+
const timeout = commonApi.getTimeout(config)
|
|
6
17
|
const requestBody = {
|
|
7
|
-
applicationId: config.applicationId,
|
|
8
18
|
dependencyTree: analysis,
|
|
9
19
|
organizationId: config.organizationId,
|
|
10
20
|
language: config.language,
|
|
@@ -22,7 +32,7 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
22
32
|
const reportID = await client
|
|
23
33
|
.scaServiceIngest(requestBody, config)
|
|
24
34
|
.then(res => {
|
|
25
|
-
if (res.statusCode === 201) {
|
|
35
|
+
if (res.statusCode === 201 || res.statusCode === 200) {
|
|
26
36
|
return res.body.libraryIngestJobId
|
|
27
37
|
} else {
|
|
28
38
|
throw new Error(res.statusCode + ` error ingesting dependencies`)
|
|
@@ -40,21 +50,95 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
40
50
|
while (keepChecking) {
|
|
41
51
|
res = await client.scaServiceReportStatus(config, reportID).then(res => {
|
|
42
52
|
if (config.debug) {
|
|
43
|
-
console.log(res.statusCode)
|
|
53
|
+
console.log('scaServiceReportStatus', res.statusCode)
|
|
44
54
|
console.log(res.body)
|
|
45
55
|
}
|
|
46
56
|
if (res.body.status === 'COMPLETED') {
|
|
47
57
|
keepChecking = false
|
|
48
58
|
return client.scaServiceReport(config, reportID).then(res => {
|
|
49
59
|
const reportBody = res.body
|
|
50
|
-
return { reportBody, reportID }
|
|
60
|
+
return { reportBody, reportId: reportID }
|
|
51
61
|
})
|
|
52
62
|
}
|
|
53
63
|
})
|
|
54
64
|
|
|
55
65
|
if (!keepChecking) {
|
|
56
|
-
return { reportArray: res.reportBody, reportID }
|
|
66
|
+
return { reportArray: res.reportBody, reportId: reportID }
|
|
57
67
|
}
|
|
68
|
+
|
|
69
|
+
commonApi.handleTimeout(startTime, timeout, reportSpinner)
|
|
70
|
+
|
|
71
|
+
await requestUtils.sleep(5000)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { reportArray: res, reportID }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const noProjectUpload = async (analysis, config, reportSpinner) => {
|
|
78
|
+
config.language = config.language === 'JAVASCRIPT' ? 'NODE' : config.language
|
|
79
|
+
const startTime = performance.now()
|
|
80
|
+
const timeout = commonApi.getTimeout(config)
|
|
81
|
+
const requestBody = {
|
|
82
|
+
dependencyTree: analysis,
|
|
83
|
+
language: config.language,
|
|
84
|
+
tool: {
|
|
85
|
+
name: 'Contrast Codesec',
|
|
86
|
+
version: APP_VERSION
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (config.branch) {
|
|
91
|
+
requestBody.branchName = config.branch
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const client = commonApi.getHttpClient(config)
|
|
95
|
+
const reportID = await client
|
|
96
|
+
.noProjectIdUpload(requestBody, config)
|
|
97
|
+
.then(res => {
|
|
98
|
+
if (res.statusCode === 201 || res.statusCode === 200) {
|
|
99
|
+
return res.body.libraryIngestJobId
|
|
100
|
+
} else {
|
|
101
|
+
throw new Error(
|
|
102
|
+
res.statusCode + ` error ingesting dependencies with no project id`
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
.catch(err => {
|
|
107
|
+
throw err
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
if (config.debug) {
|
|
111
|
+
console.log(' polling report no project', reportID)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let keepChecking = true
|
|
115
|
+
let res
|
|
116
|
+
while (keepChecking) {
|
|
117
|
+
res = await client
|
|
118
|
+
.scaServiceNoProjectIdReportStatus(config, reportID)
|
|
119
|
+
.then(res => {
|
|
120
|
+
if (config.debug) {
|
|
121
|
+
console.log('\nscaServiceReportStatus')
|
|
122
|
+
console.log(res.statusCode)
|
|
123
|
+
console.log(res.body)
|
|
124
|
+
}
|
|
125
|
+
if (res.body.status === 'COMPLETED') {
|
|
126
|
+
keepChecking = false
|
|
127
|
+
return client
|
|
128
|
+
.scaServiceReportNoProjectId(config, reportID)
|
|
129
|
+
.then(res => {
|
|
130
|
+
const reportBody = res.body
|
|
131
|
+
return { reportBody, reportId: reportID }
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
if (!keepChecking) {
|
|
137
|
+
return { reportArray: res.reportBody, reportId: reportID }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
commonApi.handleTimeout(startTime, timeout, reportSpinner)
|
|
141
|
+
|
|
58
142
|
await requestUtils.sleep(5000)
|
|
59
143
|
}
|
|
60
144
|
|
|
@@ -62,5 +146,6 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
62
146
|
}
|
|
63
147
|
|
|
64
148
|
module.exports = {
|
|
65
|
-
scaTreeUpload
|
|
149
|
+
scaTreeUpload,
|
|
150
|
+
noProjectUpload
|
|
66
151
|
}
|
|
@@ -3,11 +3,13 @@ const { APP_VERSION } = require('../../constants/constants')
|
|
|
3
3
|
|
|
4
4
|
const commonSendSnapShot = async (analysis, config) => {
|
|
5
5
|
let requestBody = {}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
config.legacy === false
|
|
7
|
+
? (requestBody = sendToSCAServices(config, analysis))
|
|
8
|
+
: (requestBody = {
|
|
9
|
+
appID: config.applicationId,
|
|
10
|
+
cliVersion: APP_VERSION,
|
|
11
|
+
snapshot: analysis
|
|
12
|
+
})
|
|
11
13
|
|
|
12
14
|
const client = commonApi.getHttpClient(config)
|
|
13
15
|
return client
|
|
@@ -31,6 +33,19 @@ const commonSendSnapShot = async (analysis, config) => {
|
|
|
31
33
|
})
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
const sendToSCAServices = (config, analysis) => {
|
|
37
|
+
return {
|
|
38
|
+
applicationId: config.applicationId,
|
|
39
|
+
dependencyTree: analysis,
|
|
40
|
+
organizationId: config.organizationId,
|
|
41
|
+
language: config.language,
|
|
42
|
+
tool: {
|
|
43
|
+
name: 'Contrast Codesec',
|
|
44
|
+
version: APP_VERSION
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
34
49
|
module.exports = {
|
|
35
50
|
commonSendSnapShot
|
|
36
51
|
}
|
|
@@ -10,7 +10,12 @@ const goAnalysis = config => {
|
|
|
10
10
|
const rawGoDependencies = goReadDepFile.getGoDependencies(config)
|
|
11
11
|
const parsedGoDependencies =
|
|
12
12
|
goParseDeps.parseGoDependencies(rawGoDependencies)
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
if (config.legacy === false) {
|
|
15
|
+
return parseDependenciesForSCAServices(parsedGoDependencies)
|
|
16
|
+
} else {
|
|
17
|
+
return createGoTSMessage(parsedGoDependencies)
|
|
18
|
+
}
|
|
14
19
|
} catch (e) {
|
|
15
20
|
console.log(e.message.toString())
|
|
16
21
|
}
|
|
@@ -11,7 +11,12 @@ const javaAnalysis = async (config, languageFiles) => {
|
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
if (config.legacy === false) {
|
|
16
|
+
return parseDependenciesForSCAServices(javaDeps)
|
|
17
|
+
} else {
|
|
18
|
+
return createJavaTSMessage(javaDeps)
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
const buildJavaTree = (config, files) => {
|
|
@@ -14,6 +14,10 @@ const jsAnalysis = async (config, languageFiles) => {
|
|
|
14
14
|
const buildNodeTree = async (config, files) => {
|
|
15
15
|
let analysis = await readFiles(config, files)
|
|
16
16
|
const rawNode = await parseFiles(config, files, analysis)
|
|
17
|
+
if (config.legacy === false) {
|
|
18
|
+
return scaServiceParser.parseJS(rawNode)
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
return formatMessage.createJavaScriptTSMessage(rawNode)
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -60,10 +64,8 @@ const parseFiles = async (config, files, js) => {
|
|
|
60
64
|
)
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
if (currentLockFileVersion === 3) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
`NPM lockfileVersion 3 is only supported when using the '-e' flag.`
|
|
66
|
-
)
|
|
67
|
+
if (currentLockFileVersion === 3 && config.legacy) {
|
|
68
|
+
throw new Error(`NPM lockfileVersion 3 is not support with --legacy`)
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
js.npmLockFile = await analysis.parseNpmLockFile(npmLockFile)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const auditController = require('../../commands/audit/auditController')
|
|
2
|
+
const {
|
|
3
|
+
returnOra,
|
|
4
|
+
startSpinner,
|
|
5
|
+
succeedSpinner
|
|
6
|
+
} = require('../../utils/oraWrapper')
|
|
7
|
+
const i18n = require('i18n')
|
|
8
|
+
const treeUpload = require('../common/treeUpload')
|
|
9
|
+
const {
|
|
10
|
+
pollForSnapshotCompletion
|
|
11
|
+
} = require('../../audit/languageAnalysisEngine/sendSnapshot')
|
|
12
|
+
const { vulnerabilityReportV2 } = require('../../audit/report/reportingFeature')
|
|
13
|
+
const { auditSave } = require('../../audit/save')
|
|
14
|
+
|
|
15
|
+
const legacyFlow = async (config, messageToSend) => {
|
|
16
|
+
const startTime = performance.now()
|
|
17
|
+
if (!config.applicationId) {
|
|
18
|
+
config.applicationId = await auditController.dealWithNoAppId(config)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log('') //empty log for space before spinner
|
|
22
|
+
//send message to TS
|
|
23
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
24
|
+
startSpinner(reportSpinner)
|
|
25
|
+
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
26
|
+
messageToSend,
|
|
27
|
+
config
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// poll for completion
|
|
31
|
+
await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner)
|
|
32
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
33
|
+
|
|
34
|
+
await vulnerabilityReportV2(config, snapshotResponse.id)
|
|
35
|
+
if (config.save !== undefined) {
|
|
36
|
+
await auditSave(config)
|
|
37
|
+
} else {
|
|
38
|
+
console.log('\nUse contrast audit --save to generate an SBOM')
|
|
39
|
+
}
|
|
40
|
+
const endTime = performance.now() - startTime
|
|
41
|
+
const scanDurationMs = endTime - startTime
|
|
42
|
+
|
|
43
|
+
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
legacyFlow
|
|
48
|
+
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
const { readFile, parseProjectFiles } = require('./analysis')
|
|
2
2
|
const { createPhpTSMessage } = require('../common/formatMessage')
|
|
3
|
+
const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper')
|
|
3
4
|
|
|
4
5
|
const phpAnalysis = config => {
|
|
5
6
|
let analysis = readFiles(config)
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
if (config.legacy === false) {
|
|
9
|
+
return parsePHPLockFileForScaServices(analysis.rawLockFileContents)
|
|
10
|
+
} else {
|
|
11
|
+
const phpDep = parseProjectFiles(analysis)
|
|
12
|
+
return createPhpTSMessage(phpDep)
|
|
13
|
+
}
|
|
8
14
|
}
|
|
9
15
|
|
|
10
16
|
const readFiles = config => {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const projectConfig = require('../commands/github/projectGroup')
|
|
2
|
+
const scaServicesUpload = require('../scaAnalysis/common/scaServicesUpload')
|
|
3
|
+
|
|
4
|
+
const trackProcess = async (analysis, config, reportSpinner) => {
|
|
5
|
+
await projectConfig.registerNewProjectGroup(config)
|
|
6
|
+
let projectId = await projectConfig.getProjectIdByOrg(config)
|
|
7
|
+
await projectConfig.registerProjectIdOnCliServices(config, projectId)
|
|
8
|
+
config.projectId = projectId
|
|
9
|
+
return await scaServicesUpload.scaTreeUpload(analysis, config, reportSpinner)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const repoProcess = async (analysis, config, reportSpinner) => {
|
|
13
|
+
let repoInfo = repoService.retrieveRepoId(config)
|
|
14
|
+
if (repoInfo.repoId === '') {
|
|
15
|
+
repoInfo = repoService.registerRepo(config)
|
|
16
|
+
}
|
|
17
|
+
await projectConfig.registerProjectIdOnCliServices(config, repoInfo.projectId)
|
|
18
|
+
return repoInfo
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const dealWithNoProjectId = async (analysis, config, reportSpinner) => {
|
|
22
|
+
// if (config.repo === '') {
|
|
23
|
+
// return repoProcess(analysis, config, reportSpinner)
|
|
24
|
+
// }
|
|
25
|
+
if (config.track) {
|
|
26
|
+
return trackProcess(analysis, config, reportSpinner)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!config.track) {
|
|
30
|
+
return await scaServicesUpload.noProjectUpload(
|
|
31
|
+
analysis,
|
|
32
|
+
config,
|
|
33
|
+
reportSpinner
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const processUpload = async (analysis, config, reportSpinner) => {
|
|
39
|
+
// if repo but no repoId -> RegisterRepo -> GroupProjectFlow THEN scaTreeUpload
|
|
40
|
+
// if cli tracked but no projectId -> registerNewProjectGroup THEN scaTreeUpload
|
|
41
|
+
// if cli not tracked and no projectID -> noProjectUpload
|
|
42
|
+
// if cli not tracked and projectID -> scaTreeUpload}
|
|
43
|
+
let projectId = await projectConfig.getProjectIdByOrg(config)
|
|
44
|
+
|
|
45
|
+
if (projectId === '') {
|
|
46
|
+
return dealWithNoProjectId(analysis, config, reportSpinner)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (projectId) {
|
|
50
|
+
config.projectId = projectId
|
|
51
|
+
return await scaServicesUpload.scaTreeUpload(
|
|
52
|
+
analysis,
|
|
53
|
+
config,
|
|
54
|
+
reportSpinner
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = {
|
|
60
|
+
processUpload
|
|
61
|
+
}
|
|
@@ -60,10 +60,16 @@ const checkForCorrectFiles = languageFiles => {
|
|
|
60
60
|
|
|
61
61
|
const getPythonDeps = (config, languageFiles) => {
|
|
62
62
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
if (config.legacy === false) {
|
|
64
|
+
let pythonLockFileContents = readLockFile(config.file)
|
|
65
|
+
return scaPythonParser(pythonLockFileContents)
|
|
66
|
+
} else {
|
|
67
|
+
checkForCorrectFiles(languageFiles)
|
|
68
|
+
const parseProject = readAndParseProjectFile(config.file)
|
|
69
|
+
const parsePip = readAndParseLockFile(config.file)
|
|
70
|
+
|
|
71
|
+
return { pipfileLock: parsePip, pipfilDependanceies: parseProject }
|
|
72
|
+
}
|
|
67
73
|
} catch (err) {
|
|
68
74
|
console.log(err.message.toString())
|
|
69
75
|
process.exit(1)
|
|
@@ -3,7 +3,12 @@ const { getPythonDeps, secondaryParser } = require('./analysis')
|
|
|
3
3
|
|
|
4
4
|
const pythonAnalysis = (config, languageFiles) => {
|
|
5
5
|
const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
if (config.legacy === false) {
|
|
8
|
+
return pythonDeps
|
|
9
|
+
} else {
|
|
10
|
+
return createPythonTSMessage(pythonDeps)
|
|
11
|
+
}
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
module.exports = {
|
|
@@ -7,10 +7,10 @@ const buildRepo = async (config, languageFiles) => {
|
|
|
7
7
|
|
|
8
8
|
if (project.projectType === 'maven') {
|
|
9
9
|
let jsonPomFile = mavenParser.readPomFile(project)
|
|
10
|
-
mavenParser.parsePomFile(jsonPomFile)
|
|
10
|
+
return mavenParser.parsePomFile(jsonPomFile)
|
|
11
11
|
} else if (project.projectType === 'gradle') {
|
|
12
12
|
const gradleJson = gradleParser.readBuildGradleFile(project)
|
|
13
|
-
gradleParser.parseGradleJson(await gradleJson)
|
|
13
|
+
return gradleParser.parseGradleJson(await gradleJson)
|
|
14
14
|
} else {
|
|
15
15
|
console.log('Unable to read project files.')
|
|
16
16
|
}
|
|
@@ -6,7 +6,17 @@ const getRubyDeps = (config, languageFiles) => {
|
|
|
6
6
|
checkForCorrectFiles(languageFiles)
|
|
7
7
|
const parsedGem = readAndParseGemfile(config.file)
|
|
8
8
|
const parsedLock = readAndParseGemLockFile(config.file)
|
|
9
|
-
|
|
9
|
+
if (config.legacy === false) {
|
|
10
|
+
const rubyArray = removeRedundantAndPopulateDefinedElements(
|
|
11
|
+
parsedLock.sources
|
|
12
|
+
)
|
|
13
|
+
let rubyTree = createRubyTree(rubyArray)
|
|
14
|
+
findChildrenDependencies(rubyTree)
|
|
15
|
+
processRootDependencies(parsedLock.dependencies, rubyTree)
|
|
16
|
+
return rubyTree
|
|
17
|
+
} else {
|
|
18
|
+
return { gemfilesDependanceies: parsedGem, gemfileLock: parsedLock }
|
|
19
|
+
}
|
|
10
20
|
} catch (err) {
|
|
11
21
|
throw err
|
|
12
22
|
}
|
|
@@ -3,7 +3,12 @@ const { createRubyTSMessage } = require('../common/formatMessage')
|
|
|
3
3
|
|
|
4
4
|
const rubyAnalysis = (config, languageFiles) => {
|
|
5
5
|
const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY)
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
if (config.legacy === false) {
|
|
8
|
+
return rubyDeps
|
|
9
|
+
} else {
|
|
10
|
+
return createRubyTSMessage(rubyDeps)
|
|
11
|
+
}
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
module.exports = {
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
const {
|
|
2
2
|
supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
|
|
3
3
|
} = require('../constants/constants')
|
|
4
|
-
const {
|
|
5
|
-
pollForSnapshotCompletion
|
|
6
|
-
} = require('../audit/languageAnalysisEngine/sendSnapshot')
|
|
7
4
|
const {
|
|
8
5
|
returnOra,
|
|
9
6
|
startSpinner,
|
|
10
7
|
succeedSpinner
|
|
11
8
|
} = require('../utils/oraWrapper')
|
|
12
|
-
const { vulnerabilityReportV2 } = require('../audit/report/reportingFeature')
|
|
13
9
|
const autoDetection = require('../scan/autoDetection')
|
|
14
|
-
const treeUpload = require('./common/treeUpload')
|
|
15
|
-
const auditController = require('../commands/audit/auditController')
|
|
16
10
|
const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames')
|
|
17
11
|
const path = require('path')
|
|
18
12
|
const i18n = require('i18n')
|
|
@@ -26,12 +20,16 @@ const { rubyAnalysis } = require('./ruby')
|
|
|
26
20
|
const { pythonAnalysis } = require('./python')
|
|
27
21
|
const javaAnalysis = require('./java')
|
|
28
22
|
const jsAnalysis = require('./javascript')
|
|
23
|
+
const auditReport = require('./common/auditReport')
|
|
24
|
+
const processServices = require('./processServicesFlow')
|
|
29
25
|
const chalk = require('chalk')
|
|
26
|
+
const {
|
|
27
|
+
convertGenericToTypedReportModelSca
|
|
28
|
+
} = require('./common/utils/reportUtilsSca')
|
|
29
|
+
const projectConfig = require('../commands/github/projectGroup')
|
|
30
|
+
const { legacyFlow } = require('./legacy/legacyFlow')
|
|
30
31
|
|
|
31
32
|
const processSca = async config => {
|
|
32
|
-
//checks to see whether to use old TS / new SCA path
|
|
33
|
-
|
|
34
|
-
const startTime = performance.now()
|
|
35
33
|
let filesFound
|
|
36
34
|
|
|
37
35
|
if (config.help) {
|
|
@@ -64,7 +62,17 @@ const processSca = async config => {
|
|
|
64
62
|
switch (Object.keys(filesFound[0])[0]) {
|
|
65
63
|
case JAVA:
|
|
66
64
|
config.language = JAVA
|
|
67
|
-
|
|
65
|
+
if (config.repo && !config.legacy) {
|
|
66
|
+
try {
|
|
67
|
+
messageToSend = await repoMode.buildRepo(config, filesFound[0])
|
|
68
|
+
} catch (e) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
'Unable to build in repository mode. Check your project file'
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
messageToSend = await javaAnalysis.javaAnalysis(config, filesFound[0])
|
|
75
|
+
}
|
|
68
76
|
break
|
|
69
77
|
case JAVASCRIPT:
|
|
70
78
|
messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
|
|
@@ -87,43 +95,59 @@ const processSca = async config => {
|
|
|
87
95
|
config.language = GO
|
|
88
96
|
break
|
|
89
97
|
case DOTNET:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
if (config.legacy === false) {
|
|
99
|
+
console.log(
|
|
100
|
+
`${chalk.bold(
|
|
101
|
+
'\n.NET project found\n'
|
|
102
|
+
)} Language type is unsupported.`
|
|
103
|
+
)
|
|
104
|
+
return
|
|
105
|
+
} else {
|
|
106
|
+
messageToSend = dotNetAnalysis(config, filesFound[0])
|
|
107
|
+
config.language = DOTNET
|
|
108
|
+
break
|
|
109
|
+
}
|
|
93
110
|
default:
|
|
94
111
|
//something is wrong
|
|
95
112
|
console.log('No supported language detected in project path')
|
|
96
113
|
return
|
|
97
114
|
}
|
|
98
115
|
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
messageToSend,
|
|
108
|
-
config
|
|
109
|
-
)
|
|
116
|
+
if (config.legacy === false) {
|
|
117
|
+
if (!config.name) {
|
|
118
|
+
config = await projectConfig.dealWithNoName(config)
|
|
119
|
+
}
|
|
120
|
+
const startTime = performance.now()
|
|
121
|
+
console.log('') //empty log for space before spinner
|
|
122
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
123
|
+
startSpinner(reportSpinner)
|
|
110
124
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
125
|
+
let reportResponse = await processServices.processUpload(
|
|
126
|
+
messageToSend,
|
|
127
|
+
config,
|
|
128
|
+
reportSpinner
|
|
129
|
+
)
|
|
114
130
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
const reportModelLibraryList = convertGenericToTypedReportModelSca(
|
|
132
|
+
reportResponse.reportArray
|
|
133
|
+
)
|
|
134
|
+
auditReport.processAuditReport(config, reportModelLibraryList)
|
|
135
|
+
if (config.save !== undefined) {
|
|
136
|
+
await auditSave.auditSave(config, reportResponse.reportId)
|
|
137
|
+
} else {
|
|
138
|
+
console.log('Use contrast audit --save to generate an SBOM')
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
142
|
+
|
|
143
|
+
const endTime = performance.now() - startTime
|
|
144
|
+
const scanDurationMs = endTime - startTime
|
|
145
|
+
console.log(
|
|
146
|
+
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
147
|
+
)
|
|
118
148
|
} else {
|
|
119
|
-
|
|
149
|
+
await legacyFlow(config, messageToSend)
|
|
120
150
|
}
|
|
121
|
-
const endTime = performance.now() - startTime
|
|
122
|
-
const scanDurationMs = endTime - startTime
|
|
123
|
-
|
|
124
|
-
console.log(
|
|
125
|
-
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
126
|
-
)
|
|
127
151
|
} else {
|
|
128
152
|
if (filesFound.length === 0) {
|
|
129
153
|
console.log(i18n.__('languageAnalysisNoLanguage'))
|