Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
a7305e64
Commit
a7305e64
authored
Nov 05, 2021
by
Savas Vedova
Committed by
Olena Horal-Koretska
Nov 05, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Track security report findings
parent
721c7bbb
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
65 additions
and
9 deletions
+65
-9
app/assets/javascripts/vue_shared/security_reports/store/modules/sast/actions.js
...vue_shared/security_reports/store/modules/sast/actions.js
+1
-0
app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js
...ecurity_reports/store/modules/secret_detection/actions.js
+1
-0
ee/app/assets/javascripts/vue_shared/security_reports/grouped_security_reports_app.vue
..._shared/security_reports/grouped_security_reports_app.vue
+25
-7
ee/app/assets/javascripts/vue_shared/security_reports/store/actions.js
.../javascripts/vue_shared/security_reports/store/actions.js
+8
-2
ee/app/assets/javascripts/vue_shared/security_reports/store/modules/api_fuzzing/actions.js
...red/security_reports/store/modules/api_fuzzing/actions.js
+1
-0
ee/spec/frontend/vue_shared/security_reports/grouped_security_reports_app_spec.js
...red/security_reports/grouped_security_reports_app_spec.js
+29
-0
No files found.
app/assets/javascripts/vue_shared/security_reports/store/modules/sast/actions.js
View file @
a7305e64
...
@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
...
@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
return
fetchDiffData
(
rootState
,
state
.
paths
.
diffEndpoint
,
REPORT_TYPE_SAST
)
return
fetchDiffData
(
rootState
,
state
.
paths
.
diffEndpoint
,
REPORT_TYPE_SAST
)
.
then
((
data
)
=>
{
.
then
((
data
)
=>
{
dispatch
(
'
receiveDiffSuccess
'
,
data
);
dispatch
(
'
receiveDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveDiffError
'
);
dispatch
(
'
receiveDiffError
'
);
...
...
app/assets/javascripts/vue_shared/security_reports/store/modules/secret_detection/actions.js
View file @
a7305e64
...
@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
...
@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
return
fetchDiffData
(
rootState
,
state
.
paths
.
diffEndpoint
,
REPORT_TYPE_SECRET_DETECTION
)
return
fetchDiffData
(
rootState
,
state
.
paths
.
diffEndpoint
,
REPORT_TYPE_SECRET_DETECTION
)
.
then
((
data
)
=>
{
.
then
((
data
)
=>
{
dispatch
(
'
receiveDiffSuccess
'
,
data
);
dispatch
(
'
receiveDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveDiffError
'
);
dispatch
(
'
receiveDiffError
'
);
...
...
ee/app/assets/javascripts/vue_shared/security_reports/grouped_security_reports_app.vue
View file @
a7305e64
...
@@ -394,38 +394,38 @@ export default {
...
@@ -394,38 +394,38 @@ export default {
if
(
this
.
sastComparisonPath
&&
this
.
hasSastReports
)
{
if
(
this
.
sastComparisonPath
&&
this
.
hasSastReports
)
{
this
.
setSastDiffEndpoint
(
this
.
sastComparisonPath
);
this
.
setSastDiffEndpoint
(
this
.
sastComparisonPath
);
this
.
fetchS
astDiff
(
);
this
.
fetchS
ecurityReport
(
this
.
fetchSastDiff
,
'
sast
'
);
}
}
if
(
this
.
containerScanningComparisonPath
&&
this
.
hasContainerScanningReports
)
{
if
(
this
.
containerScanningComparisonPath
&&
this
.
hasContainerScanningReports
)
{
this
.
setContainerScanningDiffEndpoint
(
this
.
containerScanningComparisonPath
);
this
.
setContainerScanningDiffEndpoint
(
this
.
containerScanningComparisonPath
);
this
.
fetch
ContainerScanningDiff
(
);
this
.
fetch
SecurityReport
(
this
.
fetchContainerScanningDiff
,
'
container_scanning
'
);
}
}
if
(
this
.
dastComparisonPath
&&
this
.
hasDastReports
)
{
if
(
this
.
dastComparisonPath
&&
this
.
hasDastReports
)
{
this
.
setDastDiffEndpoint
(
this
.
dastComparisonPath
);
this
.
setDastDiffEndpoint
(
this
.
dastComparisonPath
);
this
.
fetch
DastDiff
(
);
this
.
fetch
SecurityReport
(
this
.
fetchDastDiff
,
'
dast
'
);
}
}
if
(
this
.
dependencyScanningComparisonPath
&&
this
.
hasDependencyScanningReports
)
{
if
(
this
.
dependencyScanningComparisonPath
&&
this
.
hasDependencyScanningReports
)
{
this
.
setDependencyScanningDiffEndpoint
(
this
.
dependencyScanningComparisonPath
);
this
.
setDependencyScanningDiffEndpoint
(
this
.
dependencyScanningComparisonPath
);
this
.
fetch
DependencyScanningDiff
(
);
this
.
fetch
SecurityReport
(
this
.
fetchDependencyScanningDiff
,
'
dependency_scanning
'
);
}
}
if
(
this
.
secretDetectionComparisonPath
&&
this
.
hasSecretDetectionReports
)
{
if
(
this
.
secretDetectionComparisonPath
&&
this
.
hasSecretDetectionReports
)
{
this
.
setSecretDetectionDiffEndpoint
(
this
.
secretDetectionComparisonPath
);
this
.
setSecretDetectionDiffEndpoint
(
this
.
secretDetectionComparisonPath
);
this
.
fetchSec
retDetectionDiff
(
);
this
.
fetchSec
urityReport
(
this
.
fetchSecretDetectionDiff
,
'
secret_detection
'
);
}
}
if
(
this
.
coverageFuzzingComparisonPath
&&
this
.
hasCoverageFuzzingReports
)
{
if
(
this
.
coverageFuzzingComparisonPath
&&
this
.
hasCoverageFuzzingReports
)
{
this
.
setCoverageFuzzingDiffEndpoint
(
this
.
coverageFuzzingComparisonPath
);
this
.
setCoverageFuzzingDiffEndpoint
(
this
.
coverageFuzzingComparisonPath
);
this
.
fetch
CoverageFuzzingDiff
(
);
this
.
fetch
SecurityReport
(
this
.
fetchCoverageFuzzingDiff
,
'
coverage_fuzzing
'
);
this
.
fetchPipelineJobs
();
this
.
fetchPipelineJobs
();
}
}
if
(
this
.
apiFuzzingComparisonPath
&&
this
.
hasApiFuzzingReports
)
{
if
(
this
.
apiFuzzingComparisonPath
&&
this
.
hasApiFuzzingReports
)
{
this
.
setApiFuzzingDiffEndpoint
(
this
.
apiFuzzingComparisonPath
);
this
.
setApiFuzzingDiffEndpoint
(
this
.
apiFuzzingComparisonPath
);
this
.
fetch
ApiFuzzingDiff
(
);
this
.
fetch
SecurityReport
(
this
.
fetchApiFuzzingDiff
,
'
api_fuzzing
'
);
}
}
},
},
methods
:
{
methods
:
{
...
@@ -475,6 +475,24 @@ export default {
...
@@ -475,6 +475,24 @@ export default {
hasIssuesForReportType
(
reportType
)
{
hasIssuesForReportType
(
reportType
)
{
return
Boolean
(
this
[
reportType
]?.
newIssues
.
length
||
this
[
reportType
]?.
resolvedIssues
.
length
);
return
Boolean
(
this
[
reportType
]?.
newIssues
.
length
||
this
[
reportType
]?.
resolvedIssues
.
length
);
},
},
async
fetchSecurityReport
(
fetchFn
,
toolName
)
{
try
{
const
reports
=
await
fetchFn
();
const
category
=
'
Vulnerability_Management
'
;
const
eventNameFixed
=
`mr_widget_findings_counts_
${
toolName
}
_fixed`
;
const
eventNameAdded
=
`mr_widget_findings_counts_
${
toolName
}
_added`
;
Tracking
.
event
(
category
,
eventNameFixed
,
{
value
:
reports
?.
diff
?.
fixed
?.
length
||
0
,
});
Tracking
.
event
(
category
,
eventNameAdded
,
{
value
:
reports
?.
diff
?.
added
?.
length
||
0
,
});
}
catch
{
// Do nothing, we dispatch an error message in the action
}
},
},
},
summarySlots
:
[
'
success
'
,
'
error
'
,
'
loading
'
],
summarySlots
:
[
'
success
'
,
'
error
'
,
'
loading
'
],
reportTypes
:
{
reportTypes
:
{
...
...
ee/app/assets/javascripts/vue_shared/security_reports/store/actions.js
View file @
a7305e64
...
@@ -67,6 +67,7 @@ export const fetchContainerScanningDiff = ({ state, dispatch }) => {
...
@@ -67,6 +67,7 @@ export const fetchContainerScanningDiff = ({ state, dispatch }) => {
return
fetchDiffData
(
state
,
state
.
containerScanning
.
paths
.
diffEndpoint
,
'
container_scanning
'
)
return
fetchDiffData
(
state
,
state
.
containerScanning
.
paths
.
diffEndpoint
,
'
container_scanning
'
)
.
then
((
data
)
=>
{
.
then
((
data
)
=>
{
dispatch
(
'
receiveContainerScanningDiffSuccess
'
,
data
);
dispatch
(
'
receiveContainerScanningDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveContainerScanningDiffError
'
);
dispatch
(
'
receiveContainerScanningDiffError
'
);
...
@@ -96,6 +97,7 @@ export const fetchDastDiff = ({ state, dispatch }) => {
...
@@ -96,6 +97,7 @@ export const fetchDastDiff = ({ state, dispatch }) => {
return
fetchDiffData
(
state
,
state
.
dast
.
paths
.
diffEndpoint
,
'
dast
'
)
return
fetchDiffData
(
state
,
state
.
dast
.
paths
.
diffEndpoint
,
'
dast
'
)
.
then
((
data
)
=>
{
.
then
((
data
)
=>
{
dispatch
(
'
receiveDastDiffSuccess
'
,
data
);
dispatch
(
'
receiveDastDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveDastDiffError
'
);
dispatch
(
'
receiveDastDiffError
'
);
...
@@ -124,6 +126,7 @@ export const fetchDependencyScanningDiff = ({ state, dispatch }) => {
...
@@ -124,6 +126,7 @@ export const fetchDependencyScanningDiff = ({ state, dispatch }) => {
return
fetchDiffData
(
state
,
state
.
dependencyScanning
.
paths
.
diffEndpoint
,
'
dependency_scanning
'
)
return
fetchDiffData
(
state
,
state
.
dependencyScanning
.
paths
.
diffEndpoint
,
'
dependency_scanning
'
)
.
then
((
data
)
=>
{
.
then
((
data
)
=>
{
dispatch
(
'
receiveDependencyScanningDiffSuccess
'
,
data
);
dispatch
(
'
receiveDependencyScanningDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveDependencyScanningDiffError
'
);
dispatch
(
'
receiveDependencyScanningDiffError
'
);
...
@@ -160,10 +163,13 @@ export const fetchCoverageFuzzingDiff = ({ state, dispatch }) => {
...
@@ -160,10 +163,13 @@ export const fetchCoverageFuzzingDiff = ({ state, dispatch }) => {
}),
}),
])
])
.
then
((
values
)
=>
{
.
then
((
values
)
=>
{
dispatch
(
'
receiveCoverageFuzzingDiffSuccess
'
,
{
const
data
=
{
diff
:
values
[
0
].
data
,
diff
:
values
[
0
].
data
,
enrichData
:
values
[
1
].
data
,
enrichData
:
values
[
1
].
data
,
});
};
dispatch
(
'
receiveCoverageFuzzingDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveCoverageFuzzingDiffError
'
);
dispatch
(
'
receiveCoverageFuzzingDiffError
'
);
...
...
ee/app/assets/javascripts/vue_shared/security_reports/store/modules/api_fuzzing/actions.js
View file @
a7305e64
...
@@ -17,6 +17,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
...
@@ -17,6 +17,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
return
fetchDiffData
(
rootState
,
state
.
paths
.
diffEndpoint
,
'
api_fuzzing
'
)
return
fetchDiffData
(
rootState
,
state
.
paths
.
diffEndpoint
,
'
api_fuzzing
'
)
.
then
((
data
)
=>
{
.
then
((
data
)
=>
{
dispatch
(
'
receiveDiffSuccess
'
,
data
);
dispatch
(
'
receiveDiffSuccess
'
,
data
);
return
data
;
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
dispatch
(
'
receiveDiffError
'
);
dispatch
(
'
receiveDiffError
'
);
...
...
ee/spec/frontend/vue_shared/security_reports/grouped_security_reports_app_spec.js
View file @
a7305e64
...
@@ -274,6 +274,9 @@ describe('Grouped security reports app', () => {
...
@@ -274,6 +274,9 @@ describe('Grouped security reports app', () => {
});
});
describe
(
'
with successful responses
'
,
()
=>
{
describe
(
'
with successful responses
'
,
()
=>
{
let
trackingSpy
;
const
{
category
}
=
trackMrSecurityReportDetails
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
CONTAINER_SCANNING_DIFF_ENDPOINT
).
reply
(
200
,
containerScanningDiffSuccessMock
);
mock
.
onGet
(
CONTAINER_SCANNING_DIFF_ENDPOINT
).
reply
(
200
,
containerScanningDiffSuccessMock
);
mock
.
onGet
(
DEPENDENCY_SCANNING_DIFF_ENDPOINT
).
reply
(
200
,
dependencyScanningDiffSuccessMock
);
mock
.
onGet
(
DEPENDENCY_SCANNING_DIFF_ENDPOINT
).
reply
(
200
,
dependencyScanningDiffSuccessMock
);
...
@@ -284,6 +287,7 @@ describe('Grouped security reports app', () => {
...
@@ -284,6 +287,7 @@ describe('Grouped security reports app', () => {
mock
.
onGet
(
API_FUZZING_DIFF_ENDPOINT
).
reply
(
200
,
apiFuzzingDiffSuccessMock
);
mock
.
onGet
(
API_FUZZING_DIFF_ENDPOINT
).
reply
(
200
,
apiFuzzingDiffSuccessMock
);
createWrapper
(
allReportProps
);
createWrapper
(
allReportProps
);
trackingSpy
=
mockTracking
(
category
,
wrapper
.
element
,
jest
.
spyOn
);
return
Promise
.
all
([
return
Promise
.
all
([
waitForMutation
(
wrapper
.
vm
.
$store
,
`sast/
${
sastTypes
.
RECEIVE_DIFF_SUCCESS
}
`
),
waitForMutation
(
wrapper
.
vm
.
$store
,
`sast/
${
sastTypes
.
RECEIVE_DIFF_SUCCESS
}
`
),
...
@@ -299,6 +303,31 @@ describe('Grouped security reports app', () => {
...
@@ -299,6 +303,31 @@ describe('Grouped security reports app', () => {
]);
]);
});
});
afterEach
(()
=>
{
unmockTracking
();
});
const
eventName
=
(
toolName
,
eventType
)
=>
`mr_widget_findings_counts_
${
toolName
}
_
${
eventType
}
`
;
it
.
each
`
toolName | report
${
'
coverage_fuzzing
'
}
|
${
coverageFuzzingDiffSuccessMock
}
${
'
sast
'
}
|
${
sastDiffSuccessMock
}
${
'
container_scanning
'
}
|
${
containerScanningDiffSuccessMock
}
${
'
dast
'
}
|
${
dastDiffSuccessMock
}
${
'
dependency_scanning
'
}
|
${
dependencyScanningDiffSuccessMock
}
${
'
secret_detection
'
}
|
${
secretDetectionDiffSuccessMock
}
${
'
api_fuzzing
'
}
|
${
apiFuzzingDiffSuccessMock
}
`
(
'
track reports for "$toolName
'
,
({
toolName
,
report
})
=>
{
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
category
,
eventName
(
toolName
,
'
fixed
'
),
{
value
:
report
.
fixed
.
length
,
});
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
category
,
eventName
(
toolName
,
'
added
'
),
{
value
:
report
.
added
.
length
,
});
});
it
(
'
renders reports
'
,
()
=>
{
it
(
'
renders reports
'
,
()
=>
{
// It's not loading
// It's not loading
expect
(
findSpinner
().
exists
()).
toBe
(
false
);
expect
(
findSpinner
().
exists
()).
toBe
(
false
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment