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
17b423da
Commit
17b423da
authored
Mar 22, 2022
by
Daniel Tian
Committed by
Savas Vedova
Mar 22, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix vulnerability report not showing for manually-added vulnerabilities
parent
ae7134ae
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
148 additions
and
143 deletions
+148
-143
ee/app/assets/javascripts/approvals/components/rule_form.vue
ee/app/assets/javascripts/approvals/components/rule_form.vue
+7
-9
ee/app/assets/javascripts/security_dashboard/components/pipeline/filters.vue
...cripts/security_dashboard/components/pipeline/filters.vue
+2
-2
ee/app/assets/javascripts/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue
...ard/components/pipeline/pipeline_vulnerability_report.vue
+1
-1
ee/app/assets/javascripts/security_dashboard/components/project/project_vulnerability_report.vue
...board/components/project/project_vulnerability_report.vue
+14
-4
ee/app/assets/javascripts/security_dashboard/components/shared/project_pipeline_status.vue
...y_dashboard/components/shared/project_pipeline_status.vue
+16
-23
ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/constants.js
...board/components/shared/vulnerability_report/constants.js
+8
-6
ee/app/assets/javascripts/security_dashboard/helpers.js
ee/app/assets/javascripts/security_dashboard/helpers.js
+8
-15
ee/app/assets/javascripts/security_dashboard/store/constants.js
.../assets/javascripts/security_dashboard/store/constants.js
+15
-3
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/policy_rule_builder.vue
.../policy_editor/scan_result_policy/policy_rule_builder.vue
+4
-7
ee/app/assets/javascripts/vue_shared/security_reports/components/vulnerability_details.vue
...red/security_reports/components/vulnerability_details.vue
+2
-2
ee/app/assets/javascripts/vue_shared/security_reports/store/utils/convert_report_type.js
...hared/security_reports/store/utils/convert_report_type.js
+2
-2
ee/app/helpers/ee/projects_helper.rb
ee/app/helpers/ee/projects_helper.rb
+1
-0
ee/spec/frontend/approvals/components/rule_form_spec.js
ee/spec/frontend/approvals/components/rule_form_spec.js
+3
-16
ee/spec/frontend/security_dashboard/components/project/project_vulnerability_report_spec.js
...d/components/project/project_vulnerability_report_spec.js
+33
-9
ee/spec/frontend/security_dashboard/components/shared/filters/scanner_filter_spec.js
...ashboard/components/shared/filters/scanner_filter_spec.js
+3
-3
ee/spec/frontend/security_dashboard/components/shared/project_pipeline_status_spec.js
...shboard/components/shared/project_pipeline_status_spec.js
+25
-41
ee/spec/helpers/projects_helper_spec.rb
ee/spec/helpers/projects_helper_spec.rb
+1
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
ee/app/assets/javascripts/approvals/components/rule_form.vue
View file @
17b423da
<
script
>
import
{
GlFormGroup
,
GlFormInput
,
GlDropdown
,
GlTruncate
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
groupBy
,
isEqual
,
isNumber
,
omit
}
from
'
lodash
'
;
import
{
groupBy
,
isEqual
,
isNumber
}
from
'
lodash
'
;
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
{
REPORT_TYPES
,
SEVERITY_LEVELS
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPES
_DEFAULT
,
SEVERITY_LEVELS
}
from
'
ee/security_dashboard/store/constants
'
;
import
ProtectedBranchesSelector
from
'
ee/vue_shared/components/branches_selector/protected_branches_selector.vue
'
;
import
{
sprintf
}
from
'
~/locale
'
;
import
{
...
...
@@ -21,8 +21,6 @@ import ApproversSelect from './approvers_select.vue';
const
DEFAULT_NAME
=
'
Default
'
;
export
const
EXCLUDED_REPORT_TYPE
=
'
cluster_image_scanning
'
;
export
const
READONLY_NAMES
=
[
LICENSE_CHECK_NAME
,
VULNERABILITY_CHECK_NAME
,
COVERAGE_CHECK_NAME
];
function
mapServerResponseToValidationErrors
(
messages
)
{
...
...
@@ -75,7 +73,7 @@ export default {
severityLevels
:
[],
vulnerabilityStates
:
[],
approvalVulnerabilityStatesKeys
:
Object
.
keys
(
APPROVAL_VULNERABILITY_STATES
),
reportTypesKeys
:
Object
.
keys
(
this
.
$options
.
REPORT_TYPES
),
reportTypesKeys
:
Object
.
keys
(
REPORT_TYPES_DEFAULT
),
severityLevelsKeys
:
Object
.
keys
(
SEVERITY_LEVELS
),
...
this
.
getInitialData
(),
};
...
...
@@ -265,10 +263,10 @@ export default {
case
0
:
return
APPROVAL_DIALOG_I18N
.
form
.
scannersSelectLabel
;
case
1
:
return
this
.
$options
.
REPORT_TYPES
[
this
.
scanners
[
0
]];
return
REPORT_TYPES_DEFAULT
[
this
.
scanners
[
0
]];
default
:
return
sprintf
(
APPROVAL_DIALOG_I18N
.
form
.
multipleSelectedLabel
,
{
firstLabel
:
this
.
$options
.
REPORT_TYPES
[
this
.
scanners
[
0
]],
firstLabel
:
REPORT_TYPES_DEFAULT
[
this
.
scanners
[
0
]],
numberOfAdditionalLabels
:
this
.
scanners
.
length
-
1
,
});
}
...
...
@@ -476,7 +474,7 @@ export default {
},
},
APPROVAL_DIALOG_I18N
,
REPORT_TYPES
:
omit
(
REPORT_TYPES
,
EXCLUDED_REPORT_TYPE
)
,
REPORT_TYPES
_DEFAULT
,
SEVERITY_LEVELS
,
APPROVAL_VULNERABILITY_STATES
,
};
...
...
@@ -519,7 +517,7 @@ export default {
<gl-truncate
:text=
"$options.APPROVAL_DIALOG_I18N.form.selectAllLabel"
/>
</gl-dropdown-item>
<gl-dropdown-item
v-for=
"(value, key) in $options.REPORT_TYPES"
v-for=
"(value, key) in $options.REPORT_TYPES
_DEFAULT
"
:key=
"key"
is-check-item
:is-checked=
"isScannerSelected(key)"
...
...
ee/app/assets/javascripts/security_dashboard/components/pipeline/filters.vue
View file @
17b423da
<
script
>
import
{
GlToggle
}
from
'
@gitlab/ui
'
;
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
{
severityFilter
,
simpleScannerFilter
}
from
'
ee/security_dashboard/helpers
'
;
import
{
severityFilter
,
simpleScannerFilter
Pipeline
}
from
'
ee/security_dashboard/helpers
'
;
import
{
DISMISSAL_STATES
}
from
'
ee/security_dashboard/store/modules/filters/constants
'
;
import
{
s__
}
from
'
~/locale
'
;
import
SimpleFilter
from
'
../shared/filters/simple_filter.vue
'
;
...
...
@@ -16,7 +16,7 @@ export default {
},
data
()
{
return
{
filterConfigs
:
[
severityFilter
,
simpleScannerFilter
],
filterConfigs
:
[
severityFilter
,
simpleScannerFilter
Pipeline
],
};
},
computed
:
{
...
...
ee/app/assets/javascripts/security_dashboard/components/pipeline/pipeline_vulnerability_report.vue
View file @
17b423da
...
...
@@ -40,7 +40,7 @@ export default {
this
.
selectedFinding
=
undefined
;
},
},
filtersToShow
:
[
FILTERS
.
STATUS
,
FILTERS
.
SEVERITY
,
FILTERS
.
TOOL_
SIMPL
E
],
filtersToShow
:
[
FILTERS
.
STATUS
,
FILTERS
.
SEVERITY
,
FILTERS
.
TOOL_
PIPELIN
E
],
fieldsToShow
:
[
FIELDS
.
CHECKBOX
,
FIELDS
.
STATUS
,
...
...
ee/app/assets/javascripts/security_dashboard/components/project/project_vulnerability_report.vue
View file @
17b423da
...
...
@@ -3,7 +3,6 @@ import { difference } from 'lodash';
import
{
getCookie
,
setCookie
,
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
glFeatureFlagsMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
import
LocalStorageSync
from
'
~/vue_shared/components/local_storage_sync.vue
'
;
import
{
translateScannerNames
}
from
'
~/security_configuration/utils
'
;
import
SecurityTrainingPromo
from
'
ee/security_dashboard/components/shared/security_training_promo.vue
'
;
import
ReportNotConfiguredProject
from
'
../shared/empty_states/report_not_configured_project.vue
'
;
...
...
@@ -25,7 +24,7 @@ export default {
SecurityTrainingPromo
,
},
mixins
:
[
glFeatureFlagsMixin
()],
inject
:
[
'
fullPath
'
,
'
pipeline
'
,
'
autoFixDocumentation
'
],
inject
:
[
'
fullPath
'
,
'
pipeline
'
,
'
autoFixDocumentation
'
,
'
hasVulnerabilities
'
],
data
()
{
return
{
scannerAlertDismissed
:
false
,
...
...
@@ -53,7 +52,15 @@ export default {
},
computed
:
{
isReportConfigured
()
{
return
this
.
pipeline
?.
id
;
// A report is configured when either a pipeline generated a security report, or when
// vulnerabilities are added through the new vulnerability page or API. There are 3 cases:
// 1. No vulnerabilities exist and no pipeline has ever generated a security report. The
// report is not configured.
// 2. Vulnerabilities were added through the new vulnerability page or the API. Whether a
// pipeline was run does not matter, the report is configured.
// 3. A pipeline was run that outputted a security report. Whether vulnerabilities exist does
// not matter, the report is configured.
return
Boolean
(
this
.
pipeline
.
id
)
||
this
.
hasVulnerabilities
;
},
notEnabledSecurityScanners
()
{
const
{
available
=
[],
enabled
=
[]
}
=
this
.
securityScanners
;
...
...
@@ -63,6 +70,9 @@ export default {
const
{
enabled
=
[],
pipelineRun
=
[]
}
=
this
.
securityScanners
;
return
difference
(
enabled
,
pipelineRun
);
},
shouldShowPipelineStatus
()
{
return
this
.
pipeline
.
createdAt
&&
this
.
pipeline
.
id
&&
this
.
pipeline
.
path
;
},
shouldShowScannersAlert
()
{
return
(
!
this
.
scannerAlertDismissed
&&
...
...
@@ -112,7 +122,7 @@ export default {
<vulnerability-report-tabs
:query=
"$options.projectVulnerabilitiesQuery"
>
<template
#header-development
>
<project-pipeline-status
:pipeline=
"pipeline"
/>
<project-pipeline-status
v-if=
"shouldShowPipelineStatus"
:pipeline=
"pipeline"
/>
</
template
>
</vulnerability-report-tabs>
</div>
...
...
ee/app/assets/javascripts/security_dashboard/components/shared/project_pipeline_status.vue
View file @
17b423da
...
...
@@ -33,11 +33,6 @@ export default {
props
:
{
pipeline
:
{
type
:
Object
,
required
:
true
},
},
computed
:
{
shouldShowPipelineStatus
()
{
return
this
.
pipeline
.
createdAt
&&
this
.
pipeline
.
id
&&
this
.
pipeline
.
path
;
},
},
i18n
:
{
lastUpdated
:
__
(
'
Last updated
'
),
autoFixSolutions
:
s__
(
'
AutoRemediation|Auto-fix solutions
'
),
...
...
@@ -47,24 +42,22 @@ export default {
</
script
>
<
template
>
<div
v-if=
"shouldShowPipelineStatus"
>
<div
class=
"gl-display-flex gl-align-items-center gl-border-solid gl-border-1 gl-border-gray-100 gl-p-6"
>
<div
class=
"gl-mr-6"
>
<span
class=
"gl-font-weight-bold gl-mr-3"
>
{{
$options
.
i18n
.
lastUpdated
}}
</span>
<span
class=
"gl-white-space-nowrap"
>
<time-ago-tooltip
class=
"gl-pr-3"
:time=
"pipeline.createdAt"
/>
<gl-link
:href=
"pipeline.path"
>
#
{{
pipeline
.
id
}}
</gl-link>
<pipeline-status-badge
:pipeline=
"pipeline"
class=
"gl-ml-3"
/>
</span>
</div>
<div
v-if=
"autoFixMrsCount"
data-testid=
"auto-fix-mrs-link"
>
<span
class=
"gl-font-weight-bold gl-mr-3"
>
{{
$options
.
i18n
.
autoFixSolutions
}}
</span>
<gl-link
:href=
"autoFixMrsPath"
class=
"gl-white-space-nowrap"
>
{{
sprintf
(
$options
.
i18n
.
autoFixMrsLink
,
{
mrsCount
:
autoFixMrsCount
}
)
}}
<
/gl-link
>
<
/div
>
<div
class=
"gl-display-flex gl-align-items-center gl-border-solid gl-border-1 gl-border-gray-100 gl-p-6"
>
<div
class=
"gl-mr-6"
>
<span
class=
"gl-font-weight-bold gl-mr-3"
>
{{
$options
.
i18n
.
lastUpdated
}}
</span>
<span
class=
"gl-white-space-nowrap"
>
<time-ago-tooltip
class=
"gl-pr-3"
:time=
"pipeline.createdAt"
/>
<gl-link
:href=
"pipeline.path"
>
#
{{
pipeline
.
id
}}
</gl-link>
<pipeline-status-badge
:pipeline=
"pipeline"
class=
"gl-ml-3"
/>
</span>
</div>
<div
v-if=
"autoFixMrsCount"
data-testid=
"auto-fix-mrs-link"
>
<span
class=
"gl-font-weight-bold gl-mr-3"
>
{{
$options
.
i18n
.
autoFixSolutions
}}
</span>
<gl-link
:href=
"autoFixMrsPath"
class=
"gl-white-space-nowrap"
>
{{
sprintf
(
$options
.
i18n
.
autoFixMrsLink
,
{
mrsCount
:
autoFixMrsCount
}
)
}}
<
/gl-link
>
<
/div
>
<
/div
>
<
/template
>
ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/constants.js
View file @
17b423da
...
...
@@ -4,10 +4,11 @@ import {
severityFilter
,
activityFilter
,
projectFilter
,
simpleScannerFilterNoClusterImage
,
vendorScannerFilterNoClusterImage
,
simpleScannerFilter
,
simpleScannerFilterPipeline
,
vendorScannerFilter
,
}
from
'
ee/security_dashboard/helpers
'
;
import
{
REPORT_TYPES_
NO_CLUSTER_IMAGE
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPES_
WITH_MANUALLY_ADDED
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPE_CLUSTER_IMAGE_SCANNING
}
from
'
~/vue_shared/security_reports/constants
'
;
export
const
REPORT_TAB
=
{
...
...
@@ -75,8 +76,9 @@ export const FILTERS = {
STATUS
:
stateFilter
,
SEVERITY
:
severityFilter
,
ACTIVITY
:
activityFilter
,
TOOL_SIMPLE
:
simpleScannerFilterNoClusterImage
,
TOOL_VENDOR
:
vendorScannerFilterNoClusterImage
,
TOOL_SIMPLE
:
simpleScannerFilter
,
TOOL_VENDOR
:
vendorScannerFilter
,
TOOL_PIPELINE
:
simpleScannerFilterPipeline
,
PROJECT
:
projectFilter
,
};
...
...
@@ -98,6 +100,6 @@ export const FILTER_PRESETS = {
};
export
const
REPORT_TYPE_PRESETS
=
{
DEVELOPMENT
:
Object
.
keys
(
REPORT_TYPES_
NO_CLUSTER_IMAGE
).
map
((
type
)
=>
type
.
toUpperCase
()),
DEVELOPMENT
:
Object
.
keys
(
REPORT_TYPES_
WITH_MANUALLY_ADDED
).
map
((
type
)
=>
type
.
toUpperCase
()),
OPERATIONAL
:
[
REPORT_TYPE_CLUSTER_IMAGE_SCANNING
.
toUpperCase
()],
};
ee/app/assets/javascripts/security_dashboard/helpers.js
View file @
17b423da
import
isPlainObject
from
'
lodash/isPlainObject
'
;
import
{
REPORT_TYPES
,
REPORT_TYPES_NO_CLUSTER_IMAGE
,
REPORT_TYPES_WITH_MANUALLY_ADDED
,
REPORT_TYPES_WITH_CLUSTER_IMAGE
,
REPORT_TYPES_ALL
,
SEVERITY_LEVELS
,
}
from
'
ee/security_dashboard/store/constants
'
;
import
convertReportType
from
'
ee/vue_shared/security_reports/store/utils/convert_report_type
'
;
...
...
@@ -51,15 +52,15 @@ export const createScannerOption = (vendor, reportType) => {
export
const
simpleScannerFilter
=
{
name
:
toolName
,
id
:
'
reportType
'
,
options
:
parseOptions
(
REPORT_TYPES
),
options
:
parseOptions
(
REPORT_TYPES
_WITH_MANUALLY_ADDED
),
allOption
:
{
name
:
allToolsName
},
defaultOptions
:
[],
};
export
const
simpleScannerFilter
NoClusterImag
e
=
{
export
const
simpleScannerFilter
Pipelin
e
=
{
name
:
toolName
,
id
:
'
reportType
'
,
options
:
parseOptions
(
REPORT_TYPES_
NO
_CLUSTER_IMAGE
),
options
:
parseOptions
(
REPORT_TYPES_
WITH
_CLUSTER_IMAGE
),
allOption
:
{
name
:
allToolsName
},
defaultOptions
:
[],
};
...
...
@@ -69,15 +70,7 @@ export const simpleScannerFilterNoClusterImage = {
export
const
vendorScannerFilter
=
{
name
:
toolName
,
id
:
'
scanner
'
,
options
:
Object
.
keys
(
REPORT_TYPES
).
map
((
x
)
=>
createScannerOption
(
DEFAULT_SCANNER
,
x
)),
allOption
:
{
name
:
allToolsName
},
defaultOptions
:
[],
};
export
const
vendorScannerFilterNoClusterImage
=
{
name
:
toolName
,
id
:
'
scanner
'
,
options
:
Object
.
keys
(
REPORT_TYPES_NO_CLUSTER_IMAGE
).
map
((
x
)
=>
options
:
Object
.
keys
(
REPORT_TYPES_WITH_MANUALLY_ADDED
).
map
((
x
)
=>
createScannerOption
(
DEFAULT_SCANNER
,
x
),
),
allOption
:
{
name
:
allToolsName
},
...
...
@@ -146,7 +139,7 @@ export const getFormattedSummary = (rawSummary = {}) => {
);
// Replace keys with translations found in REPORT_TYPES if available
const
formattedEntries
=
withoutEmptyEntries
.
map
(([
scanType
,
scanSummary
])
=>
{
const
name
=
REPORT_TYPES
[
scanType
];
const
name
=
REPORT_TYPES
_ALL
[
scanType
];
return
name
?
[
name
,
scanSummary
]
:
null
;
});
// Filter out keys that could not be matched with any translation and are thus considered invalid
...
...
ee/app/assets/javascripts/security_dashboard/store/constants.js
View file @
17b423da
...
...
@@ -19,7 +19,7 @@ export const SEVERITY_LEVELS = {
info
:
s__
(
'
severity|Info
'
),
};
export
const
REPORT_TYPES_
NO_CLUSTER_IMAGE
=
{
export
const
REPORT_TYPES_
DEFAULT
=
{
container_scanning
:
s__
(
'
ciReport|Container Scanning
'
),
dast
:
s__
(
'
ciReport|DAST
'
),
dependency_scanning
:
s__
(
'
ciReport|Dependency Scanning
'
),
...
...
@@ -29,10 +29,22 @@ export const REPORT_TYPES_NO_CLUSTER_IMAGE = {
api_fuzzing
:
s__
(
'
ciReport|API Fuzzing
'
),
};
export
const
REPORT_TYPES
=
{
...
REPORT_TYPES_
NO_CLUSTER_IMAGE
,
export
const
REPORT_TYPES
_WITH_CLUSTER_IMAGE
=
{
...
REPORT_TYPES_
DEFAULT
,
cluster_image_scanning
:
s__
(
'
ciReport|Cluster Image Scanning
'
),
};
export
const
REPORT_TYPES_WITH_MANUALLY_ADDED
=
{
...
REPORT_TYPES_DEFAULT
,
generic
:
s__
(
'
ciReport|Manually Added
'
),
};
export
const
REPORT_TYPES_ALL
=
{
...
REPORT_TYPES_DEFAULT
,
...
REPORT_TYPES_WITH_CLUSTER_IMAGE
,
...
REPORT_TYPES_WITH_MANUALLY_ADDED
,
};
export
const
DASHBOARD_TYPES
=
{
PROJECT
:
'
project
'
,
PIPELINE
:
'
pipeline
'
,
...
...
ee/app/assets/javascripts/threat_monitoring/components/policy_editor/scan_result_policy/policy_rule_builder.vue
View file @
17b423da
<
script
>
import
{
GlSprintf
,
GlForm
,
GlButton
,
GlFormGroup
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
REPORT_TYPES_NO_CLUSTER_IMAGE
,
SEVERITY_LEVELS
,
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPES_DEFAULT
,
SEVERITY_LEVELS
}
from
'
ee/security_dashboard/store/constants
'
;
import
ProtectedBranchesSelector
from
'
ee/vue_shared/components/branches_selector/protected_branches_selector.vue
'
;
import
PolicyRuleMultiSelect
from
'
ee/threat_monitoring/components/policy_rule_multi_select.vue
'
;
import
{
APPROVAL_VULNERABILITY_STATES
}
from
'
ee/approvals/constants
'
;
...
...
@@ -31,7 +28,7 @@ export default {
},
data
()
{
return
{
reportTypesKeys
:
Object
.
keys
(
REPORT_TYPES_
NO_CLUSTER_IMAGE
),
reportTypesKeys
:
Object
.
keys
(
REPORT_TYPES_
DEFAULT
),
};
},
computed
:
{
...
...
@@ -82,7 +79,7 @@ export default {
this
.
$emit
(
'
changed
'
,
{
...
this
.
initRule
,
...
value
});
},
},
REPORT_TYPES_
NO_CLUSTER_IMAGE
,
REPORT_TYPES_
DEFAULT
,
SEVERITY_LEVELS
,
APPROVAL_VULNERABILITY_STATES
,
i18n
:
{
...
...
@@ -108,7 +105,7 @@ export default {
v-model=
"scannersToAdd"
class=
"gl-mr-3"
:item-type-name=
"$options.i18n.scanners"
:items=
"$options.REPORT_TYPES_
NO_CLUSTER_IMAGE
"
:items=
"$options.REPORT_TYPES_
DEFAULT
"
data-testid=
"scanners-select"
/>
</
template
>
...
...
ee/app/assets/javascripts/vue_shared/security_reports/components/vulnerability_details.vue
View file @
17b423da
<
script
>
import
{
GlFriendlyWrap
,
GlLink
,
GlBadge
,
GlSafeHtmlDirective
}
from
'
@gitlab/ui
'
;
import
{
REPORT_TYPES
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPES
_ALL
}
from
'
ee/security_dashboard/store/constants
'
;
import
FalsePositiveAlert
from
'
ee/vulnerabilities/components/false_positive_alert.vue
'
;
import
GenericReportSection
from
'
ee/vulnerabilities/components/generic_report/report_section.vue
'
;
import
{
...
...
@@ -117,7 +117,7 @@ export default {
return
this
.
vulnerability
.
response
?.
status_code
;
},
scannerType
()
{
return
REPORT_TYPES
[
this
.
vulnerability
.
report_type
];
return
REPORT_TYPES
_ALL
[
this
.
vulnerability
.
report_type
];
},
scannerUrl
()
{
return
this
.
vulnerability
.
scanner
?.
url
||
''
;
...
...
ee/app/assets/javascripts/vue_shared/security_reports/store/utils/convert_report_type.js
View file @
17b423da
import
{
REPORT_TYPES
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPES
_ALL
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
humanize
}
from
'
~/lib/utils/text_utility
'
;
/**
...
...
@@ -9,7 +9,7 @@ import { humanize } from '~/lib/utils/text_utility';
const
convertReportType
=
(
reportType
)
=>
{
if
(
!
reportType
)
return
''
;
const
lowerCaseType
=
reportType
.
toLowerCase
();
return
REPORT_TYPES
[
lowerCaseType
]
||
humanize
(
lowerCaseType
);
return
REPORT_TYPES
_ALL
[
lowerCaseType
]
||
humanize
(
lowerCaseType
);
};
export
default
convertReportType
;
ee/app/helpers/ee/projects_helper.rb
View file @
17b423da
...
...
@@ -179,6 +179,7 @@ module EE
survey_request_svg_path:
image_path
(
'illustrations/security-dashboard_empty.svg'
),
security_dashboard_help_path:
help_page_path
(
'user/application_security/security_dashboard/index'
),
no_vulnerabilities_svg_path:
image_path
(
'illustrations/issues.svg'
),
dashboard_documentation:
help_page_path
(
'user/application_security/security_dashboard/index'
),
project_full_path:
project
.
full_path
,
security_configuration_path:
project_security_configuration_path
(
@project
)
}.
merge!
(
security_dashboard_pipeline_data
(
project
))
...
...
ee/spec/frontend/approvals/components/rule_form_spec.js
View file @
17b423da
...
...
@@ -4,10 +4,7 @@ import Vue, { nextTick } from 'vue';
import
Vuex
from
'
vuex
'
;
import
ApproversList
from
'
ee/approvals/components/approvers_list.vue
'
;
import
ApproversSelect
from
'
ee/approvals/components/approvers_select.vue
'
;
import
RuleForm
,
{
READONLY_NAMES
,
EXCLUDED_REPORT_TYPE
,
}
from
'
ee/approvals/components/rule_form.vue
'
;
import
RuleForm
,
{
READONLY_NAMES
}
from
'
ee/approvals/components/rule_form.vue
'
;
import
{
TYPE_USER
,
TYPE_GROUP
,
...
...
@@ -18,7 +15,7 @@ import {
}
from
'
ee/approvals/constants
'
;
import
{
createStoreOptions
}
from
'
ee/approvals/stores
'
;
import
projectSettingsModule
from
'
ee/approvals/stores/modules/project_settings
'
;
import
{
REPORT_TYPES
}
from
'
ee/security_dashboard/store/constants
'
;
import
{
REPORT_TYPES
_DEFAULT
}
from
'
ee/security_dashboard/store/constants
'
;
import
ProtectedBranchesSelector
from
'
ee/vue_shared/components/branches_selector/protected_branches_selector.vue
'
;
import
{
stubComponent
}
from
'
helpers/stub_component
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
...
...
@@ -652,15 +649,6 @@ describe('EE Approvals RuleForm', () => {
findAllScannersSelected
().
trigger
(
'
click
'
);
findForm
().
trigger
(
'
submit
'
);
});
it
(
`dispatches the action on submit without including
${
EXCLUDED_REPORT_TYPE
}
`
,
()
=>
{
const
reportTypesKeys
=
Object
.
keys
(
REPORT_TYPES
);
const
expectedScanners
=
reportTypesKeys
.
filter
((
item
)
=>
item
!==
EXCLUDED_REPORT_TYPE
);
expect
(
actions
.
postRule
).
toHaveBeenCalledWith
(
expect
.
anything
(),
expect
.
objectContaining
({
scanners
:
expectedScanners
}),
);
});
});
describe
(
'
with invalid number of vulnerabilities
'
,
()
=>
{
...
...
@@ -695,8 +683,7 @@ describe('EE Approvals RuleForm', () => {
});
it
(
'
contains the supported report types and select all option
'
,
()
=>
{
const
supportedReportsPlusAll
=
Object
.
keys
(
REPORT_TYPES
).
length
-
[
EXCLUDED_REPORT_TYPE
].
length
+
1
;
const
supportedReportsPlusAll
=
Object
.
keys
(
REPORT_TYPES_DEFAULT
).
length
+
1
;
expect
(
findScannersGroup
().
findAllComponents
(
GlTruncate
)).
toHaveLength
(
supportedReportsPlusAll
,
);
...
...
ee/spec/frontend/security_dashboard/components/project/project_vulnerability_report_spec.js
View file @
17b423da
...
...
@@ -23,6 +23,8 @@ Vue.use(VueApollo);
Vue
.
use
(
VueRouter
);
const
router
=
new
VueRouter
();
const
examplePipeline
=
{
id
:
1
,
createdAt
:
'
now
'
,
path
:
'
path
'
};
describe
(
'
Project vulnerability report app component
'
,
()
=>
{
useLocalStorageSpy
();
...
...
@@ -39,7 +41,8 @@ describe('Project vulnerability report app component', () => {
});
const
createWrapper
=
({
pipeline
=
{
id
:
1
},
pipeline
=
examplePipeline
,
hasVulnerabilities
=
true
,
securityScanners
,
securityAutoFix
=
false
,
secureVulnerabilityTraining
=
true
,
...
...
@@ -53,6 +56,7 @@ describe('Project vulnerability report app component', () => {
fullPath
:
'
#
'
,
autoFixDocumentation
:
'
#
'
,
pipeline
,
hasVulnerabilities
,
dashboardType
:
DASHBOARD_TYPES
.
PROJECT
,
glFeatures
:
{
securityAutoFix
,
secureVulnerabilityTraining
},
},
...
...
@@ -74,20 +78,40 @@ describe('Project vulnerability report app component', () => {
});
describe
(
'
report not configured component
'
,
()
=>
{
it
(
'
shows the
report not configured component if there are no project
s
'
,
()
=>
{
createWrapper
({
pipeline
:
null
});
it
(
'
shows the
not configured component if there is no pipeline and no vulnerabilitie
s
'
,
()
=>
{
createWrapper
({
pipeline
:
{},
hasVulnerabilities
:
false
});
expect
(
findReportNotConfiguredProject
().
exists
()).
toBe
(
true
);
expect
(
findVulnerabilityReportTabs
().
exists
()).
toBe
(
false
);
});
it
(
'
shows the vulnerability report tabs and project pipeline status components if there are projects
'
,
()
=>
{
const
pipeline
=
{
id
:
1
};
createWrapper
({
pipeline
});
it
.
each
`
pipeline | hasVulnerabilities
${
examplePipeline
}
|
${
false
}
${{}}
|
$
{
true
}
${
examplePipeline
}
|
${
true
}
`
(
'
shows the report if pipeline is $pipeline and hasVulnerabilities is $hasVulnerabilities
'
,
({
pipeline
,
hasVulnerabilities
})
=>
{
createWrapper
({
pipeline
,
hasVulnerabilities
});
expect
(
findReportNotConfiguredProject
().
exists
()).
toBe
(
false
);
expect
(
findVulnerabilityReportTabs
().
exists
()).
toBe
(
true
);
},
);
});
describe
(
'
project pipeline status component
'
,
()
=>
{
it
(
'
shows the component if there is a pipeline
'
,
()
=>
{
createWrapper
();
expect
(
findProjectPipelineStatus
().
props
(
'
pipeline
'
)).
toBe
(
examplePipeline
);
});
it
(
'
does not show the component if there is no pipeline
'
,
()
=>
{
createWrapper
({
pipeline
:
{}
});
expect
(
findReportNotConfiguredProject
().
exists
()).
toBe
(
false
);
expect
(
findVulnerabilityReportTabs
().
exists
()).
toBe
(
true
);
expect
(
findProjectPipelineStatus
().
props
(
'
pipeline
'
)).
toBe
(
pipeline
);
expect
(
findProjectPipelineStatus
().
exists
()).
toBe
(
false
);
});
});
...
...
ee/spec/frontend/security_dashboard/components/shared/filters/scanner_filter_spec.js
View file @
17b423da
...
...
@@ -6,7 +6,7 @@ import VueRouter from 'vue-router';
import
FilterItem
from
'
ee/security_dashboard/components/shared/filters/filter_item.vue
'
;
import
ScannerFilter
from
'
ee/security_dashboard/components/shared/filters/scanner_filter.vue
'
;
import
{
DEFAULT_SCANNER
,
SCANNER_ID_PREFIX
}
from
'
ee/security_dashboard/constants
'
;
import
{
vendorScannerFilter
NoClusterImage
}
from
'
ee/security_dashboard/helpers
'
;
import
{
vendorScannerFilter
}
from
'
ee/security_dashboard/helpers
'
;
Vue
.
use
(
VueRouter
);
const
router
=
new
VueRouter
();
...
...
@@ -41,7 +41,7 @@ describe('Scanner Filter component', () => {
let
filter
;
const
createWrapper
=
({
scanners
=
customScanners
}
=
{})
=>
{
filter
=
cloneDeep
(
vendorScannerFilter
NoClusterImage
);
filter
=
cloneDeep
(
vendorScannerFilter
);
wrapper
=
shallowMount
(
ScannerFilter
,
{
router
,
...
...
@@ -124,7 +124,7 @@ describe('Scanner Filter component', () => {
it
(
'
emits filter-changed event with expected data for selected options
'
,
async
()
=>
{
const
ids
=
[
'
GitLab.SAST
'
,
'
Custom.SAST
'
,
'
GitLab.API_FUZZING
'
,
'
GitLab.COVERAGE_FUZZING
'
];
router
.
replace
({
query
:
{
[
vendorScannerFilter
NoClusterImage
.
id
]:
ids
}
});
router
.
replace
({
query
:
{
[
vendorScannerFilter
.
id
]:
ids
}
});
const
selectedScanners
=
customScanners
.
filter
((
x
)
=>
ids
.
includes
(
`
${
x
.
vendor
}
.
${
x
.
report_type
}
`
),
);
...
...
ee/spec/frontend/security_dashboard/components/shared/project_pipeline_status_spec.js
View file @
17b423da
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
merge
}
from
'
lodash
'
;
import
PipelineStatusBadge
from
'
ee/security_dashboard/components/shared/pipeline_status_badge.vue
'
;
import
ProjectPipelineStatus
from
'
ee/security_dashboard/components/shared/project_pipeline_status.vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
TimeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
const
defaultPipeline
=
{
createdAt
:
'
2020-10-06T20:08:07Z
'
,
id
:
'
214
'
,
path
:
'
/mixed-vulnerabilities/dependency-list-test-01/-/pipelines/214
'
,
};
describe
(
'
Project Pipeline Status Component
'
,
()
=>
{
let
wrapper
;
const
DEFAULT_PROPS
=
{
pipeline
:
{
createdAt
:
'
2020-10-06T20:08:07Z
'
,
id
:
'
214
'
,
path
:
'
/mixed-vulnerabilities/dependency-list-test-01/-/pipelines/214
'
,
},
};
const
findPipelineStatusBadge
=
()
=>
wrapper
.
findComponent
(
PipelineStatusBadge
);
const
findTimeAgoTooltip
=
()
=>
wrapper
.
findComponent
(
TimeAgoTooltip
);
const
findLink
=
()
=>
wrapper
.
findComponent
(
GlLink
);
...
...
@@ -24,30 +21,25 @@ describe('Project Pipeline Status Component', () => {
const
createWrapper
=
(
options
=
{})
=>
{
return
extendedWrapper
(
shallowMount
(
ProjectPipelineStatus
,
merge
(
{},
{
propsData
:
DEFAULT_PROPS
,
provide
:
{
projectFullPath
:
'
/group/project
'
,
glFeatures
:
{
securityAutoFix
:
true
},
autoFixMrsPath
:
'
/merge_requests?label_name=GitLab-auto-fix
'
,
},
data
()
{
return
{
autoFixMrsCount
:
0
};
},
},
options
,
),
),
shallowMount
(
ProjectPipelineStatus
,
{
propsData
:
{
pipeline
:
defaultPipeline
,
},
provide
:
{
projectFullPath
:
'
/group/project
'
,
glFeatures
:
{
securityAutoFix
:
true
},
autoFixMrsPath
:
'
/merge_requests?label_name=GitLab-auto-fix
'
,
},
data
()
{
return
{
autoFixMrsCount
:
0
};
},
...
options
,
}),
);
};
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
default state
'
,
()
=>
{
...
...
@@ -59,7 +51,7 @@ describe('Project Pipeline Status Component', () => {
const
TimeComponent
=
findTimeAgoTooltip
();
expect
(
TimeComponent
.
exists
()).
toBeTruthy
();
expect
(
TimeComponent
.
props
()).
toStrictEqual
({
time
:
DEFAULT_PROPS
.
p
ipeline
.
createdAt
,
time
:
defaultP
ipeline
.
createdAt
,
cssClass
:
''
,
tooltipPlacement
:
'
top
'
,
});
...
...
@@ -68,20 +60,12 @@ describe('Project Pipeline Status Component', () => {
it
(
'
should show the link component
'
,
()
=>
{
const
GlLinkComponent
=
findLink
();
expect
(
GlLinkComponent
.
exists
()).
toBeTruthy
();
expect
(
GlLinkComponent
.
text
()).
toBe
(
`#
${
DEFAULT_PROPS
.
pipeline
.
id
}
`
);
expect
(
GlLinkComponent
.
attributes
(
'
href
'
)).
toBe
(
DEFAULT_PROPS
.
pipeline
.
path
);
});
});
describe
(
'
when no pipeline has run
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createWrapper
({
propsData
:
{
pipeline
:
{
path
:
''
}
}
});
expect
(
GlLinkComponent
.
text
()).
toBe
(
`#
${
defaultPipeline
.
id
}
`
);
expect
(
GlLinkComponent
.
attributes
(
'
href
'
)).
toBe
(
defaultPipeline
.
path
);
});
it
(
'
should not show the project_pipeline_status component
'
,
()
=>
{
expect
(
findLink
().
exists
()).
toBe
(
false
);
expect
(
findTimeAgoTooltip
().
exists
()).
toBe
(
false
);
expect
(
findPipelineStatusBadge
().
exists
()).
toBe
(
false
);
it
(
'
should show the pipeline status badge component
'
,
()
=>
{
expect
(
findPipelineStatusBadge
().
props
(
'
pipeline
'
)).
toBe
(
defaultPipeline
);
});
});
...
...
ee/spec/helpers/projects_helper_spec.rb
View file @
17b423da
...
...
@@ -196,6 +196,7 @@ RSpec.describe ProjectsHelper do
security_dashboard_help_path:
'/help/user/application_security/security_dashboard/index'
,
project_full_path:
project
.
full_path
,
no_vulnerabilities_svg_path:
start_with
(
'/assets/illustrations/issues-'
),
dashboard_documentation:
'/help/user/application_security/security_dashboard/index'
,
security_configuration_path:
end_with
(
'/configuration'
)
}
end
...
...
locale/gitlab.pot
View file @
17b423da
...
...
@@ -43791,6 +43791,9 @@ msgstr ""
msgid "ciReport|Manage licenses"
msgstr ""
msgid "ciReport|Manually Added"
msgstr ""
msgid "ciReport|New"
msgstr ""
...
...
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