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
9041c27c
Commit
9041c27c
authored
Nov 02, 2018
by
Sam Beckham
Committed by
Phil Hughes
Nov 02, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add modals and actions for the vulnerabilities in the Group security dashboard
parent
c3a5223b
Changes
20
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1312 additions
and
206 deletions
+1312
-206
ee/app/assets/javascripts/security_dashboard/components/app.vue
.../assets/javascripts/security_dashboard/components/app.vue
+19
-3
ee/app/assets/javascripts/security_dashboard/components/security_dashboard_action_buttons.vue
...ashboard/components/security_dashboard_action_buttons.vue
+0
-62
ee/app/assets/javascripts/security_dashboard/components/security_dashboard_table.vue
...ecurity_dashboard/components/security_dashboard_table.vue
+2
-1
ee/app/assets/javascripts/security_dashboard/components/security_dashboard_table_row.vue
...ity_dashboard/components/security_dashboard_table_row.vue
+28
-15
ee/app/assets/javascripts/security_dashboard/components/vulnerability_action_buttons.vue
...ity_dashboard/components/vulnerability_action_buttons.vue
+114
-0
ee/app/assets/javascripts/security_dashboard/components/vulnerability_issue_link.vue
...ecurity_dashboard/components/vulnerability_issue_link.vue
+3
-3
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/actions.js
...curity_dashboard/store/modules/vulnerabilities/actions.js
+124
-6
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/mutation_types.js
...dashboard/store/modules/vulnerabilities/mutation_types.js
+14
-0
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/mutations.js
...rity_dashboard/store/modules/vulnerabilities/mutations.js
+89
-0
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/state.js
...security_dashboard/store/modules/vulnerabilities/state.js
+24
-0
ee/changelogs/unreleased/6709-group-security-dashboard-vulnerabilites-fe-ee.yml
...ed/6709-group-security-dashboard-vulnerabilites-fe-ee.yml
+5
-0
ee/spec/javascripts/security_dashboard/components/security_dashboard_action_buttons_spec.js
...oard/components/security_dashboard_action_buttons_spec.js
+0
-60
ee/spec/javascripts/security_dashboard/components/security_dashboard_table_row_spec.js
...dashboard/components/security_dashboard_table_row_spec.js
+40
-26
ee/spec/javascripts/security_dashboard/components/security_dashboard_table_spec.js
...ity_dashboard/components/security_dashboard_table_spec.js
+3
-1
ee/spec/javascripts/security_dashboard/components/vulnerability_action_buttons_spec.js
...dashboard/components/vulnerability_action_buttons_spec.js
+147
-0
ee/spec/javascripts/security_dashboard/store/vulnerabilities/actions_spec.js
.../security_dashboard/store/vulnerabilities/actions_spec.js
+366
-9
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities.json
...store/vulnerabilities/data/mock_data_vulnerabilities.json
+6
-0
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities_count.json
...vulnerabilities/data/mock_data_vulnerabilities_count.json
+0
-0
ee/spec/javascripts/security_dashboard/store/vulnerabilities/mutations_spec.js
...ecurity_dashboard/store/vulnerabilities/mutations_spec.js
+268
-11
locale/gitlab.pot
locale/gitlab.pot
+60
-9
No files found.
ee/app/assets/javascripts/security_dashboard/components/app.vue
View file @
9041c27c
<
script
>
import
{
mapActions
,
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
spriteIcon
}
from
'
~/lib/utils/common_utils
'
;
import
Tabs
from
'
~/vue_shared/components/tabs/tabs
'
;
import
Tab
from
'
~/vue_shared/components/tabs/tab.vue
'
;
import
IssueModal
from
'
ee/vue_shared/security_reports/components/modal.vue
'
;
import
SecurityDashboardTable
from
'
./security_dashboard_table.vue
'
;
import
VulnerabilityCountList
from
'
./vulnerability_count_list.vue
'
;
import
SvgBlankState
from
'
~/pipelines/components/blank_state.vue
'
;
...
...
@@ -16,6 +18,7 @@ export default {
},
components
:
{
Icon
,
IssueModal
,
SecurityDashboardTable
,
SvgBlankState
,
Tab
,
...
...
@@ -46,7 +49,7 @@ export default {
},
computed
:
{
...
mapGetters
(
'
vulnerabilities
'
,
[
'
vulnerabilitiesCountByReportType
'
]),
...
mapState
(
'
vulnerabilities
'
,
[
'
hasError
'
]),
...
mapState
(
'
vulnerabilities
'
,
[
'
hasError
'
,
'
modal
'
]),
sastCount
()
{
return
this
.
vulnerabilitiesCountByReportType
(
'
sast
'
);
},
...
...
@@ -66,7 +69,7 @@ export default {
<span class="vertical-align-middle">
${
s__
(
'
Security Reports|Security Dashboard Documentation
'
,
)}
</span>
${
gl
.
utils
.
spriteIcon
(
'
external-link
'
,
'
s16 vertical-align-middle
'
)}
${
spriteIcon
(
'
external-link
'
,
'
s16 vertical-align-middle
'
)}
</a>
`
,
html
:
true
,
...
...
@@ -83,6 +86,9 @@ export default {
'
setVulnerabilitiesCountEndpoint
'
,
'
setVulnerabilitiesEndpoint
'
,
'
fetchVulnerabilitiesCount
'
,
'
createIssue
'
,
'
dismissVulnerability
'
,
'
undoDismissal
'
,
]),
},
};
...
...
@@ -90,6 +96,7 @@ export default {
<
template
>
<div>
<div
class=
"flash-container"
></div>
<svg-blank-state
v-if=
"hasError"
:svg-path=
"errorStateSvgPath"
...
...
@@ -110,7 +117,8 @@ export default {
</span>
<span
v-popover=
"popoverOptions"
class=
"text-muted ml-1"
class=
"text-muted prepend-left-4"
:aria-label=
"__('help')"
>
<icon
name=
"question"
...
...
@@ -124,6 +132,14 @@ export default {
/>
</tab>
</tabs>
<issue-modal
:modal=
"modal"
:can-create-issue-permission=
"true"
:can-create-feedback-permission=
"true"
@
createNewIssue=
"createIssue({ vulnerability: modal.vulnerability })"
@
dismissIssue=
"dismissVulnerability({ vulnerability: modal.vulnerability })"
@
revertDismissIssue=
"undoDismissal({ vulnerability: modal.vulnerability })"
/>
</div>
</div>
</template>
ee/app/assets/javascripts/security_dashboard/components/security_dashboard_action_buttons.vue
deleted
100644 → 0
View file @
c3a5223b
<
script
>
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
export
default
{
name
:
'
SecurityDashboardActionButtons
'
,
components
:
{
Icon
,
},
props
:
{
vulnerability
:
{
type
:
Object
,
required
:
true
,
},
},
methods
:
{
openModal
()
{
// TODO: Open the modal
},
newIssue
()
{
this
.
$store
.
dispatch
(
'
newIssue
'
,
this
.
vulnerability
);
},
dismissVulnerability
()
{
this
.
$store
.
dispatch
(
'
dismissVulnerability
'
,
this
.
vulnerability
);
},
},
};
</
script
>
<
template
>
<div>
<button
:aria-label=
"s__('Reports|More info')"
class=
"btn btn-secondary js-more-info"
type=
"button"
@
click=
"openModal()"
>
<icon
name=
"external-link"
/>
</button>
<button
:aria-label=
"s__('Reports|New Issue')"
class=
"btn btn-inverted btn-info js-new-issue"
type=
"button"
@
click=
"newIssue()"
>
<icon
name=
"issue-new"
/>
</button>
<button
:aria-label=
"s__('Reports|Dismiss Vulnerability')"
class=
"btn btn-inverted btn-remove js-dismiss-vulnerability"
type=
"button"
@
click=
"dismissVulnerability()"
>
<icon
name=
"cancel"
/>
</button>
</div>
</
template
>
ee/app/assets/javascripts/security_dashboard/components/security_dashboard_table.vue
View file @
9041c27c
...
...
@@ -19,7 +19,7 @@ export default {
this
.
fetchVulnerabilities
();
},
methods
:
{
...
mapActions
(
'
vulnerabilities
'
,
[
'
fetchVulnerabilities
'
]),
...
mapActions
(
'
vulnerabilities
'
,
[
'
fetchVulnerabilities
'
,
'
openModal
'
]),
},
};
</
script
>
...
...
@@ -63,6 +63,7 @@ export default {
v-for=
"vulnerability in vulnerabilities"
:key=
"vulnerability.id"
:vulnerability=
"vulnerability"
@
openModal=
"openModal(
{ vulnerability })"
/>
<pagination
...
...
ee/app/assets/javascripts/security_dashboard/components/security_dashboard_table_row.vue
View file @
9041c27c
<
script
>
import
{
mapActions
}
from
'
vuex
'
;
import
{
GlSkeletonLoading
}
from
'
@gitlab-org/gitlab-ui
'
;
import
SeverityBadge
from
'
ee/vue_shared/security_reports/components/severity_badge.vue
'
;
import
SecurityDashboardActionButtons
from
'
./security_dashboard
_action_buttons.vue
'
;
import
VulnerabilityActionButtons
from
'
./vulnerability
_action_buttons.vue
'
;
import
VulnerabilityIssueLink
from
'
./vulnerability_issue_link.vue
'
;
export
default
{
name
:
'
SecurityDashboardTableRow
'
,
components
:
{
SeverityBadge
,
SecurityDashboardActionButtons
,
GlSkeletonLoading
,
VulnerabilityActionButtons
,
VulnerabilityIssueLink
,
},
props
:
{
...
...
@@ -31,16 +32,25 @@ export default {
severity
()
{
return
this
.
vulnerability
.
severity
||
'
'
;
},
project
Namespac
e
()
{
project
FullNam
e
()
{
const
{
project
}
=
this
.
vulnerability
;
return
project
&&
project
.
full_name
?
project
.
full_name
:
null
;
return
project
&&
project
.
full_name
;
},
isDismissed
()
{
return
this
.
vulnerability
.
dismissal_feedback
;
return
Boolean
(
this
.
vulnerability
.
dismissal_feedback
)
;
},
hasIssue
()
{
return
this
.
vulnerability
.
issue_feedback
;
return
Boolean
(
this
.
vulnerability
.
issue_feedback
)
;
},
canDismissVulnerability
()
{
return
Boolean
(
this
.
vulnerability
.
vulnerability_feedback_url
);
},
canCreateIssue
()
{
return
this
.
canDismissVulnerability
&&
!
this
.
hasIssue
;
},
},
methods
:
{
...
mapActions
(
'
vulnerabilities
'
,
[
'
openModal
'
]),
},
};
</
script
>
...
...
@@ -73,8 +83,11 @@ export default {
:lines=
"2"
/>
<div
v-else
>
<strike
v-if=
"isDismissed"
>
{{
vulnerability
.
name
}}
</strike>
<span
v-else
>
{{
vulnerability
.
name
}}
</span>
<span
class=
"js-vulnerability-info"
:class=
"
{ strikethrough: isDismissed }"
@click="openModal({ vulnerability })"
>
{{
vulnerability
.
name
}}
</span>
<vulnerability-issue-link
v-if=
"hasIssue"
:issue=
"vulnerability.issue_feedback"
...
...
@@ -82,9 +95,9 @@ export default {
/>
<br
/>
<span
v-if=
"project
Namespac
e"
v-if=
"project
FullNam
e"
class=
"vulnerability-namespace"
>
{{
project
Namespac
e
}}
{{
project
FullNam
e
}}
</span>
</div>
</div>
...
...
@@ -98,12 +111,10 @@ export default {
{{
s__
(
'
Reports|Confidence
'
)
}}
</div>
<div
class=
"table-mobile-content text-capitalize"
>
<strike
v-if=
"isDismissed"
>
{{
confidence
}}
</strike>
<span
v-else
>
{{
confidence
}}
</span>
<span
:class=
"
{ strikethrough: isDismissed }">
{{
confidence
}}
</span>
</div>
</div>
<!-- This is hidden till we can hook up the actions
<div
class=
"table-section section-20"
>
<div
class=
"table-mobile-header"
...
...
@@ -112,12 +123,14 @@ export default {
{{
s__
(
'
Reports|Actions
'
)
}}
</div>
<div
class=
"table-mobile-content vulnerabilities-action-buttons"
>
<
security-dashboard
-action-buttons
<
vulnerability
-action-buttons
:vulnerability=
"vulnerability"
:can-create-issue=
"canCreateIssue"
:can-dismiss-vulnerability=
"canDismissVulnerability"
:is-dismissed=
"isDismissed"
/>
</div>
</div>
-->
</div>
</
template
>
...
...
ee/app/assets/javascripts/security_dashboard/components/vulnerability_action_buttons.vue
0 → 100644
View file @
9041c27c
<
script
>
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
GlTooltipDirective
}
from
'
@gitlab-org/gitlab-ui
'
;
import
LoadingButton
from
'
~/vue_shared/components/loading_button.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
export
default
{
name
:
'
SecurityDashboardActionButtons
'
,
components
:
{
Icon
,
LoadingButton
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
},
props
:
{
vulnerability
:
{
type
:
Object
,
required
:
true
,
},
canCreateIssue
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
canDismissVulnerability
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
isDismissed
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
computed
:
{
...
mapState
(
'
vulnerabilities
'
,
[
'
isCreatingIssue
'
,
'
isDismissingVulnerability
'
]),
},
methods
:
{
...
mapActions
(
'
vulnerabilities
'
,
[
'
openModal
'
,
'
createIssue
'
,
'
dismissVulnerability
'
,
'
undoDismissal
'
,
]),
handleCreateIssue
()
{
const
{
vulnerability
}
=
this
;
this
.
createIssue
({
vulnerability
,
flashError
:
true
});
},
handleDismissVulnerability
()
{
const
{
vulnerability
}
=
this
;
this
.
dismissVulnerability
({
vulnerability
,
flashError
:
true
});
},
handleUndoDismissal
()
{
const
{
vulnerability
}
=
this
;
this
.
undoDismissal
({
vulnerability
,
flashError
:
true
});
},
},
};
</
script
>
<
template
>
<div>
<button
key=
"more-info"
v-gl-tooltip
:aria-label=
"s__('Security Reports|More info')"
:title=
"s__('Security Reports|More info')"
class=
"btn btn-secondary js-more-info"
type=
"button"
@
click=
"openModal(
{ vulnerability })"
>
<icon
name=
"information"
/>
</button>
<loading-button
v-if=
"canCreateIssue"
key=
"create-issue"
v-gl-tooltip
:aria-label=
"s__('Security Reports|New Issue')"
:loading=
"isCreatingIssue"
:title=
"s__('Security Reports|New Issue')"
container-class=
"btn btn-inverted btn-success js-create-issue"
type=
"button"
@
click=
"handleCreateIssue"
>
<icon
name=
"issue-new"
/>
</loading-button>
<template
v-if=
"canDismissVulnerability"
>
<loading-button
v-if=
"isDismissed"
key=
"undo-dismissal"
:label=
"s__('Security Reports|Undo Dismissal')"
:loading=
"isDismissingVulnerability"
container-class=
"btn btn-inverted btn-warning js-undo-dismissal"
type=
"button"
@
click=
"handleUndoDismissal"
/>
<loading-button
v-else
key=
"dismiss-vulnerability"
v-gl-tooltip
:aria-label=
"s__('Security Reports|Dismiss Vulnerability')"
:loading=
"isDismissingVulnerability"
:title=
"s__('Security Reports|Dismiss Vulnerability')"
container-class=
"btn btn-inverted btn-warning js-dismiss-vulnerability"
type=
"button"
@
click=
"handleDismissVulnerability"
>
<icon
name=
"cancel"
/>
</loading-button>
</
template
>
</div>
</template>
ee/app/assets/javascripts/security_dashboard/components/vulnerability_issue_link.vue
View file @
9041c27c
<
script
>
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
{
GlTooltipDirective
}
from
'
@gitlab-org/gitlab-ui
'
;
export
default
{
name
:
'
VulnerabilityIssueLink
'
,
...
...
@@ -8,7 +8,7 @@ export default {
Icon
,
},
directives
:
{
Tooltip
,
GlTooltip
:
GlTooltipDirective
,
},
props
:
{
issue
:
{
...
...
@@ -31,7 +31,7 @@ export default {
<
template
>
<div
class=
"d-inline"
>
<icon
v-tooltip
v-
gl-
tooltip
name=
"issues"
css-classes=
"text-success vertical-align-middle"
:title=
"s__('Security Dashboard|Issue Created')"
...
...
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/actions.js
View file @
9041c27c
import
$
from
'
jquery
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
{
parseIntPagination
,
normalizeHeaders
}
from
'
~/lib/utils/common_utils
'
;
import
{
s__
}
from
'
~/locale
'
;
import
createFlash
from
'
~/flash
'
;
export
const
setVulnerabilitiesEndpoint
=
({
commit
},
endpoint
)
=>
{
commit
(
types
.
SET_VULNERABILITIES_ENDPOINT
,
endpoint
);
...
...
@@ -30,17 +33,19 @@ export const requestVulnerabilitiesCount = ({ commit }) => {
commit
(
types
.
REQUEST_VULNERABILITIES_COUNT
);
};
export
const
receiveVulnerabilitiesCountSuccess
=
({
commit
},
response
)
=>
{
commit
(
types
.
RECEIVE_VULNERABILITIES_COUNT_SUCCESS
,
response
.
data
);
export
const
receiveVulnerabilitiesCountSuccess
=
({
commit
},
{
data
}
)
=>
{
commit
(
types
.
RECEIVE_VULNERABILITIES_COUNT_SUCCESS
,
data
);
};
export
const
receiveVulnerabilitiesCountError
=
({
commit
})
=>
{
commit
(
types
.
RECEIVE_VULNERABILITIES_COUNT_ERROR
);
};
export
const
fetchVulnerabilities
=
({
state
,
dispatch
},
page
=
1
)
=>
{
export
const
fetchVulnerabilities
=
({
state
,
dispatch
},
page
Number
)
=>
{
dispatch
(
'
requestVulnerabilities
'
);
const
page
=
pageNumber
||
(
state
.
pageInfo
&&
state
.
pageInfo
.
page
)
||
1
;
axios
({
method
:
'
GET
'
,
url
:
state
.
vulnerabilitiesEndpoint
,
...
...
@@ -59,10 +64,10 @@ export const requestVulnerabilities = ({ commit }) => {
commit
(
types
.
REQUEST_VULNERABILITIES
);
};
export
const
receiveVulnerabilitiesSuccess
=
({
commit
},
response
=
{
})
=>
{
const
normalizedHeaders
=
normalizeHeaders
(
response
.
headers
);
export
const
receiveVulnerabilitiesSuccess
=
({
commit
},
{
headers
,
data
})
=>
{
const
normalizedHeaders
=
normalizeHeaders
(
headers
);
const
pageInfo
=
parseIntPagination
(
normalizedHeaders
);
const
vulnerabilities
=
response
.
data
;
const
vulnerabilities
=
data
;
commit
(
types
.
RECEIVE_VULNERABILITIES_SUCCESS
,
{
pageInfo
,
vulnerabilities
});
};
...
...
@@ -71,4 +76,117 @@ export const receiveVulnerabilitiesError = ({ commit }) => {
commit
(
types
.
RECEIVE_VULNERABILITIES_ERROR
);
};
export
const
openModal
=
({
commit
},
payload
=
{})
=>
{
$
(
'
#modal-mrwidget-security-issue
'
).
modal
(
'
show
'
);
commit
(
types
.
SET_MODAL_DATA
,
payload
);
};
export
const
createIssue
=
({
dispatch
},
{
vulnerability
,
flashError
})
=>
{
dispatch
(
'
requestCreateIssue
'
);
axios
.
post
(
vulnerability
.
vulnerability_feedback_url
,
{
vulnerability_feedback
:
{
feedback_type
:
'
issue
'
,
category
:
vulnerability
.
report_type
,
project_fingerprint
:
vulnerability
.
project_fingerprint
,
vulnerability_data
:
{
...
vulnerability
,
category
:
vulnerability
.
report_type
,
},
},
})
.
then
(({
data
})
=>
{
dispatch
(
'
receiveCreateIssueSuccess
'
,
data
);
})
.
catch
(()
=>
{
dispatch
(
'
receiveCreateIssueError
'
,
{
flashError
});
});
};
export
const
requestCreateIssue
=
({
commit
})
=>
{
commit
(
types
.
REQUEST_CREATE_ISSUE
);
};
export
const
receiveCreateIssueSuccess
=
({
commit
},
payload
)
=>
{
commit
(
types
.
RECEIVE_CREATE_ISSUE_SUCCESS
,
payload
);
};
export
const
receiveCreateIssueError
=
({
commit
})
=>
{
commit
(
types
.
RECEIVE_CREATE_ISSUE_ERROR
);
createFlash
(
s__
(
'
Security Reports|There was an error creating the issue.
'
));
};
export
const
dismissVulnerability
=
({
dispatch
},
{
vulnerability
,
flashError
})
=>
{
dispatch
(
'
requestDismissVulnerability
'
);
axios
.
post
(
vulnerability
.
vulnerability_feedback_url
,
{
vulnerability_feedback
:
{
feedback_type
:
'
dismissal
'
,
category
:
vulnerability
.
report_type
,
project_fingerprint
:
vulnerability
.
project_fingerprint
,
vulnerability_data
:
{
...
vulnerability
,
category
:
vulnerability
.
report_type
,
},
},
})
.
then
(({
data
})
=>
{
const
{
id
}
=
vulnerability
;
dispatch
(
'
receiveDismissVulnerabilitySuccess
'
,
{
id
,
data
});
})
.
catch
(()
=>
{
dispatch
(
'
receiveDismissVulnerabilityError
'
,
{
flashError
});
});
};
export
const
requestDismissVulnerability
=
({
commit
})
=>
{
commit
(
types
.
REQUEST_DISMISS_VULNERABILITY
);
};
export
const
receiveDismissVulnerabilitySuccess
=
({
commit
},
payload
)
=>
{
commit
(
types
.
RECEIVE_DISMISS_VULNERABILITY_SUCCESS
,
payload
);
};
export
const
receiveDismissVulnerabilityError
=
({
commit
},
{
flashError
})
=>
{
commit
(
types
.
RECEIVE_DISMISS_VULNERABILITY_ERROR
);
if
(
flashError
)
{
createFlash
(
s__
(
'
Security Reports|There was an error dismissing the issue.
'
));
}
};
export
const
undoDismissal
=
({
dispatch
},
{
vulnerability
,
flashError
})
=>
{
const
{
vulnerability_feedback_url
,
dismissal_feedback
}
=
vulnerability
;
// eslint-disable-next-line camelcase
const
url
=
`
${
vulnerability_feedback_url
}
/
${
dismissal_feedback
.
id
}
`
;
dispatch
(
'
requestUndoDismissal
'
);
axios
.
delete
(
url
)
.
then
(()
=>
{
const
{
id
}
=
vulnerability
;
dispatch
(
'
receiveUndoDismissalSuccess
'
,
{
id
});
})
.
catch
(()
=>
{
dispatch
(
'
receiveUndoDismissalError
'
,
{
flashError
});
});
};
export
const
requestUndoDismissal
=
({
commit
})
=>
{
commit
(
types
.
REQUEST_UNDO_DISMISSAL
);
};
export
const
receiveUndoDismissalSuccess
=
({
commit
},
payload
)
=>
{
commit
(
types
.
RECEIVE_UNDO_DISMISSAL_SUCCESS
,
payload
);
};
export
const
receiveUndoDismissalError
=
({
commit
},
{
flashError
})
=>
{
commit
(
types
.
RECEIVE_UNDO_DISMISSAL_ERROR
);
if
(
flashError
)
{
createFlash
(
s__
(
'
Security Reports|There was an error undoing this dismissal.
'
));
}
};
export
default
()
=>
{};
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/mutation_types.js
View file @
9041c27c
...
...
@@ -7,3 +7,17 @@ export const SET_VULNERABILITIES_COUNT_ENDPOINT = 'SET_VULNERABILITIES_COUNT_END
export
const
REQUEST_VULNERABILITIES_COUNT
=
'
REQUEST_VULNERABILITIES_COUNT
'
;
export
const
RECEIVE_VULNERABILITIES_COUNT_SUCCESS
=
'
RECEIVE_VULNERABILITIES_COUNT_SUCCESS
'
;
export
const
RECEIVE_VULNERABILITIES_COUNT_ERROR
=
'
RECEIVE_VULNERABILITIES_COUNT_ERROR
'
;
export
const
SET_MODAL_DATA
=
'
SET_MODAL_DATA
'
;
export
const
REQUEST_CREATE_ISSUE
=
'
REQUEST_CREATE_ISSUE
'
;
export
const
RECEIVE_CREATE_ISSUE_SUCCESS
=
'
RECEIVE_CREATE_ISSUE_SUCCESS
'
;
export
const
RECEIVE_CREATE_ISSUE_ERROR
=
'
RECEIVE_CREATE_ISSUE_ERROR
'
;
export
const
REQUEST_DISMISS_VULNERABILITY
=
'
REQUEST_DISMISS_VULNERABILITY
'
;
export
const
RECEIVE_DISMISS_VULNERABILITY_SUCCESS
=
'
RECEIVE_DISMISS_VULNERABILITY_SUCCESS
'
;
export
const
RECEIVE_DISMISS_VULNERABILITY_ERROR
=
'
RECEIVE_DISMISS_VULNERABILITY_ERROR
'
;
export
const
REQUEST_UNDO_DISMISSAL
=
'
REQUEST_UNDO_DISMISSAL
'
;
export
const
RECEIVE_UNDO_DISMISSAL_SUCCESS
=
'
RECEIVE_UNDO_DISMISSAL_SUCCESS
'
;
export
const
RECEIVE_UNDO_DISMISSAL_ERROR
=
'
RECEIVE_UNDO_DISMISSAL_ERROR
'
;
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/mutations.js
View file @
9041c27c
import
Vue
from
'
vue
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
import
*
as
types
from
'
./mutation_types
'
;
export
default
{
...
...
@@ -32,4 +35,90 @@ export default {
state
.
isLoadingVulnerabilitiesCount
=
false
;
state
.
hasError
=
true
;
},
[
types
.
SET_MODAL_DATA
](
state
,
payload
)
{
const
{
vulnerability
}
=
payload
;
Vue
.
set
(
state
.
modal
,
'
title
'
,
vulnerability
.
name
);
Vue
.
set
(
state
.
modal
.
data
.
description
,
'
value
'
,
vulnerability
.
description
);
Vue
.
set
(
state
.
modal
.
data
.
project
,
'
value
'
,
vulnerability
.
project
&&
vulnerability
.
project
.
full_name
,
);
Vue
.
set
(
state
.
modal
.
data
.
project
,
'
url
'
,
vulnerability
.
project
&&
vulnerability
.
project
.
full_path
,
);
Vue
.
set
(
state
.
modal
.
data
.
file
,
'
value
'
,
vulnerability
.
location
&&
vulnerability
.
location
.
file
);
Vue
.
set
(
state
.
modal
.
data
.
identifiers
,
'
value
'
,
vulnerability
.
identifiers
.
length
&&
vulnerability
.
identifiers
,
);
Vue
.
set
(
state
.
modal
.
data
.
severity
,
'
value
'
,
vulnerability
.
severity
);
Vue
.
set
(
state
.
modal
.
data
.
confidence
,
'
value
'
,
vulnerability
.
confidence
);
Vue
.
set
(
state
.
modal
.
data
.
solution
,
'
value
'
,
vulnerability
.
solution
);
Vue
.
set
(
state
.
modal
.
data
.
links
,
'
value
'
,
vulnerability
.
links
);
Vue
.
set
(
state
.
modal
.
data
.
instances
,
'
value
'
,
vulnerability
.
instances
);
Vue
.
set
(
state
.
modal
,
'
vulnerability
'
,
vulnerability
);
Vue
.
set
(
state
.
modal
.
vulnerability
,
'
hasIssue
'
,
Boolean
(
vulnerability
.
issue_feedback
));
Vue
.
set
(
state
.
modal
,
'
error
'
,
null
);
},
[
types
.
REQUEST_CREATE_ISSUE
](
state
)
{
state
.
isCreatingIssue
=
true
;
Vue
.
set
(
state
.
modal
,
'
isCreatingNewIssue
'
,
true
);
Vue
.
set
(
state
.
modal
,
'
error
'
,
null
);
},
[
types
.
RECEIVE_CREATE_ISSUE_SUCCESS
](
state
,
payload
)
{
// We don't cancel the loading state here because we're navigating away from the page
visitUrl
(
payload
.
issue_url
);
},
[
types
.
RECEIVE_CREATE_ISSUE_ERROR
](
state
)
{
state
.
isCreatingIssue
=
false
;
Vue
.
set
(
state
.
modal
,
'
isCreatingNewIssue
'
,
false
);
Vue
.
set
(
state
.
modal
,
'
error
'
,
'
There was an error creating the issue
'
);
},
[
types
.
REQUEST_DISMISS_VULNERABILITY
](
state
)
{
state
.
isDismissingVulnerability
=
true
;
Vue
.
set
(
state
.
modal
,
'
isDismissingVulnerability
'
,
true
);
Vue
.
set
(
state
.
modal
,
'
error
'
,
null
);
},
[
types
.
RECEIVE_DISMISS_VULNERABILITY_SUCCESS
](
state
,
payload
)
{
const
vulnerability
=
state
.
vulnerabilities
.
find
(
vuln
=>
vuln
.
id
===
payload
.
id
);
vulnerability
.
dismissal_feedback
=
payload
.
data
;
state
.
isDismissingVulnerability
=
false
;
Vue
.
set
(
state
.
modal
,
'
isDismissingVulnerability
'
,
false
);
Vue
.
set
(
state
.
modal
.
vulnerability
,
'
isDismissed
'
,
true
);
},
[
types
.
RECEIVE_DISMISS_VULNERABILITY_ERROR
](
state
)
{
state
.
isDismissingVulnerability
=
false
;
Vue
.
set
(
state
.
modal
,
'
isDismissingVulnerability
'
,
false
);
Vue
.
set
(
state
.
modal
,
'
error
'
,
s__
(
'
Security Reports|There was an error dismissing the vulnerability.
'
),
);
},
[
types
.
REQUEST_UNDO_DISMISSAL
](
state
)
{
state
.
isDismissingVulnerability
=
true
;
Vue
.
set
(
state
.
modal
,
'
isDismissingVulnerability
'
,
true
);
Vue
.
set
(
state
.
modal
,
'
error
'
,
null
);
},
[
types
.
RECEIVE_UNDO_DISMISSAL_SUCCESS
](
state
,
payload
)
{
const
vulnerability
=
state
.
vulnerabilities
.
find
(
vuln
=>
vuln
.
id
===
payload
.
id
);
vulnerability
.
dismissal_feedback
=
null
;
state
.
isDismissingVulnerability
=
false
;
Vue
.
set
(
state
.
modal
,
'
isDismissingVulnerability
'
,
false
);
Vue
.
set
(
state
.
modal
.
vulnerability
,
'
isDismissed
'
,
false
);
},
[
types
.
RECEIVE_UNDO_DISMISSAL_ERROR
](
state
)
{
state
.
isDismissingVulnerability
=
false
;
Vue
.
set
(
state
.
modal
,
'
isDismissingVulnerability
'
,
false
);
Vue
.
set
(
state
.
modal
,
'
error
'
,
s__
(
'
Security Reports|There was an error undoing the dismissal.
'
),
);
},
};
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/state.js
View file @
9041c27c
import
{
s__
}
from
'
~/locale
'
;
export
default
()
=>
({
hasError
:
false
,
isLoadingVulnerabilities
:
true
,
...
...
@@ -7,4 +9,26 @@ export default () => ({
vulnerabilitiesCount
:
{},
vulnerabilitiesCountEndpoint
:
null
,
vulnerabilitiesEndpoint
:
null
,
activeVulnerability
:
null
,
modal
:
{
data
:
{
description
:
{
text
:
s__
(
'
Vulnerability|Description
'
)
},
project
:
{
text
:
s__
(
'
Vulnerability|Project
'
),
isLink
:
true
,
},
file
:
{
text
:
s__
(
'
Vulnerability|File
'
)
},
identifiers
:
{
text
:
s__
(
'
Vulnerability|Identifiers
'
)
},
severity
:
{
text
:
s__
(
'
Vulnerability|Severity
'
)
},
confidence
:
{
text
:
s__
(
'
Vulnerability|Confidence
'
)
},
solution
:
{
text
:
s__
(
'
Vulnerability|Solution
'
)
},
links
:
{
text
:
s__
(
'
Vulnerability|Links
'
)
},
instances
:
{
text
:
s__
(
'
Vulnerability|Instances
'
)
},
},
vulnerability
:
{},
isCreatingNewIssue
:
false
,
isDismissingVulnerability
:
false
,
},
isCreatingIssue
:
false
,
isDismissingVulnerability
:
false
,
});
ee/changelogs/unreleased/6709-group-security-dashboard-vulnerabilites-fe-ee.yml
0 → 100644
View file @
9041c27c
---
title
:
Add modals and actions to the vulnerabilities in the Group security dashboard
merge_request
:
7910
author
:
type
:
added
ee/spec/javascripts/security_dashboard/components/security_dashboard_action_buttons_spec.js
deleted
100644 → 0
View file @
c3a5223b
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
component
from
'
ee/security_dashboard/components/security_dashboard_action_buttons.vue
'
;
import
{
mountComponentWithStore
}
from
'
spec/helpers/vue_mount_component_helper
'
;
describe
(
'
Security Dashboard Action Buttons
'
,
()
=>
{
let
vm
;
let
props
;
let
actions
;
beforeEach
(()
=>
{
props
=
{
vulnerability
:
{
id
:
123
}
};
actions
=
{
newIssue
:
jasmine
.
createSpy
(
'
newIssue
'
),
dismissVulnerability
:
jasmine
.
createSpy
(
'
dismissVulnerability
'
),
};
const
Component
=
Vue
.
extend
(
component
);
const
store
=
new
Vuex
.
Store
({
actions
});
vm
=
mountComponentWithStore
(
Component
,
{
props
,
store
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should render three buttons
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.btn
'
)).
toHaveLength
(
3
);
});
describe
(
'
More Info Button
'
,
()
=>
{
it
(
'
should render the More info button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-more-info
'
)).
not
.
toBeNull
();
});
});
describe
(
'
New Issue Button
'
,
()
=>
{
it
(
'
should render the New Issue button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-new-issue
'
)).
not
.
toBeNull
();
});
it
(
'
should trigger the `newIssue` action when clicked
'
,
()
=>
{
vm
.
$el
.
querySelector
(
'
.js-new-issue
'
).
click
();
expect
(
actions
.
newIssue
).
toHaveBeenCalledTimes
(
1
);
});
});
describe
(
'
Dismiss Vulnerability Button
'
,
()
=>
{
it
(
'
should render the Dismiss Vulnerability button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-dismiss-vulnerability
'
)).
not
.
toBeNull
();
});
it
(
'
should trigger the `dismissVulnerability` action when clicked
'
,
()
=>
{
vm
.
$el
.
querySelector
(
'
.js-dismiss-vulnerability
'
).
click
();
expect
(
actions
.
dismissVulnerability
).
toHaveBeenCalledTimes
(
1
);
});
});
});
ee/spec/javascripts/security_dashboard/components/security_dashboard_table_row_spec.js
View file @
9041c27c
import
Vue
from
'
vue
'
;
import
component
from
'
ee/security_dashboard/components/security_dashboard_table_row.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
createStore
from
'
ee/security_dashboard/store
'
;
import
{
mountComponentWithStore
}
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mockDataVulnerabilities
from
'
../store/vulnerabilities/data/mock_data_vulnerabilities.json
'
;
describe
(
'
Security Dashboard Table Row
'
,
()
=>
{
let
vm
;
let
props
;
const
store
=
createStore
();
const
Component
=
Vue
.
extend
(
component
);
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
when loading
'
,
()
=>
{
beforeEach
(()
=>
{
props
=
{
isLoading
:
true
};
vm
=
mountComponent
(
Component
,
props
);
vm
=
mountComponentWithStore
(
Component
,
{
store
,
props
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should display the skeleton loader
'
,
()
=>
{
...
...
@@ -33,16 +36,15 @@ describe('Security Dashboard Table Row', () => {
});
describe
(
'
when loaded
'
,
()
=>
{
beforeEach
(()
=>
{
const
vulnerability
=
{
severity
:
'
high
'
,
name
:
'
Test vulnerability
'
,
confidence
:
'
medium
'
,
project
:
{
full_name
:
'
project name
'
},
};
const
vulnerability
=
mockDataVulnerabilities
[
0
];
beforeEach
(()
=>
{
props
=
{
vulnerability
};
vm
=
mountComponent
(
Component
,
props
);
vm
=
mountComponentWithStore
(
Component
,
{
store
,
props
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should not display the skeleton loader
'
,
()
=>
{
...
...
@@ -55,6 +57,13 @@ describe('Security Dashboard Table Row', () => {
);
});
it
(
'
should render the confidence
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.table-mobile-content
'
)[
2
].
textContent
).
toContain
(
props
.
vulnerability
.
confidence
,
);
});
describe
(
'
the project name
'
,
()
=>
{
it
(
'
should render the name
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.table-mobile-content
'
)[
1
].
textContent
).
toContain
(
props
.
vulnerability
.
name
,
...
...
@@ -67,10 +76,15 @@ describe('Security Dashboard Table Row', () => {
);
});
it
(
'
should render the confidence
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.table-mobile-content
'
)[
2
].
textContent
).
toContain
(
props
.
vulnerability
.
confidence
,
);
it
(
'
should fire the openModal action when clicked
'
,
()
=>
{
spyOn
(
vm
.
$store
,
'
dispatch
'
);
vm
.
$el
.
querySelector
(
'
.js-vulnerability-info
'
).
click
();
expect
(
vm
.
$store
.
dispatch
).
toHaveBeenCalledWith
(
'
vulnerabilities/openModal
'
,
{
vulnerability
,
});
});
});
});
});
ee/spec/javascripts/security_dashboard/components/security_dashboard_table_spec.js
View file @
9041c27c
import
Vue
from
'
vue
'
;
import
MockAdapater
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
component
from
'
ee/security_dashboard/components/security_dashboard_table.vue
'
;
import
createStore
from
'
ee/security_dashboard/store
'
;
import
mockDataVulnerabilities
from
'
ee/security_dashboard/store/modules/vulnerabilities/mock_data_vulnerabilities.json
'
;
import
{
mountComponentWithStore
}
from
'
spec/helpers/vue_mount_component_helper
'
;
import
waitForPromises
from
'
spec/helpers/wait_for_promises
'
;
import
{
resetStore
}
from
'
../helpers
'
;
import
mockDataVulnerabilities
from
'
../store/vulnerabilities/data/mock_data_vulnerabilities.json
'
;
describe
(
'
Security Dashboard Table
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
component
);
...
...
ee/spec/javascripts/security_dashboard/components/vulnerability_action_buttons_spec.js
0 → 100644
View file @
9041c27c
import
Vue
from
'
vue
'
;
import
component
from
'
ee/security_dashboard/components/vulnerability_action_buttons.vue
'
;
import
createStore
from
'
ee/security_dashboard/store
'
;
import
{
mountComponentWithStore
}
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
resetStore
}
from
'
../helpers
'
;
import
mockDataVulnerabilities
from
'
../store/vulnerabilities/data/mock_data_vulnerabilities.json
'
;
describe
(
'
Security Dashboard Action Buttons
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
component
);
let
vm
;
let
store
;
let
props
;
beforeEach
(()
=>
{
store
=
createStore
();
});
afterEach
(()
=>
{
vm
.
$destroy
();
resetStore
(
store
);
});
describe
(
'
with a fresh vulnerability
'
,
()
=>
{
beforeEach
(()
=>
{
props
=
{
vulnerability
:
mockDataVulnerabilities
[
0
],
canCreateIssue
:
true
,
canDismissVulnerability
:
true
,
};
vm
=
mountComponentWithStore
(
Component
,
{
store
,
props
});
spyOn
(
vm
.
$store
,
'
dispatch
'
).
and
.
returnValue
(
Promise
.
resolve
());
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should render three buttons
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.btn
'
)).
toHaveLength
(
3
);
});
describe
(
'
More Info Button
'
,
()
=>
{
let
button
;
beforeEach
(()
=>
{
button
=
vm
.
$el
.
querySelector
(
'
.js-more-info
'
);
});
it
(
'
should render the More info button
'
,
()
=>
{
expect
(
button
).
not
.
toBeNull
();
});
it
(
'
should emit an `openModal` event when clicked
'
,
()
=>
{
button
.
click
();
expect
(
vm
.
$store
.
dispatch
).
toHaveBeenCalledWith
(
'
vulnerabilities/openModal
'
,
{
vulnerability
:
mockDataVulnerabilities
[
0
],
});
});
});
describe
(
'
Create Issue Button
'
,
()
=>
{
let
button
;
beforeEach
(()
=>
{
button
=
vm
.
$el
.
querySelector
(
'
.js-create-issue
'
);
});
it
(
'
should render the create issue button
'
,
()
=>
{
expect
(
button
).
not
.
toBeNull
();
});
it
(
'
should emit an `createIssue` event when clicked
'
,
()
=>
{
button
.
click
();
expect
(
vm
.
$store
.
dispatch
).
toHaveBeenCalledWith
(
'
vulnerabilities/createIssue
'
,
{
vulnerability
:
mockDataVulnerabilities
[
0
],
flashError
:
true
,
});
});
});
describe
(
'
Dismiss Vulnerability Button
'
,
()
=>
{
let
button
;
beforeEach
(()
=>
{
button
=
vm
.
$el
.
querySelector
(
'
.js-dismiss-vulnerability
'
);
});
it
(
'
should render the dismiss vulnerability button
'
,
()
=>
{
expect
(
button
).
not
.
toBeNull
();
});
it
(
'
should emit an `dismissVulnerability` event when clicked
'
,
()
=>
{
button
.
click
();
expect
(
vm
.
$store
.
dispatch
).
toHaveBeenCalledWith
(
'
vulnerabilities/dismissVulnerability
'
,
{
vulnerability
:
mockDataVulnerabilities
[
0
],
flashError
:
true
,
});
});
});
});
describe
(
'
with a vulnerbility that has an issue
'
,
()
=>
{
beforeEach
(()
=>
{
props
=
{
vulnerability
:
mockDataVulnerabilities
[
3
],
};
vm
=
mountComponentWithStore
(
Component
,
{
store
,
props
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should only render one button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.btn
'
)).
toHaveLength
(
1
);
});
it
(
'
should not render the create issue button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-create-issue
'
)).
toBeNull
();
});
});
describe
(
'
with a vulnerbility that has been dismissed
'
,
()
=>
{
beforeEach
(()
=>
{
props
=
{
vulnerability
:
mockDataVulnerabilities
[
2
],
};
vm
=
mountComponentWithStore
(
Component
,
{
store
,
props
});
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should only render one button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.btn
'
)).
toHaveLength
(
1
);
});
it
(
'
should not render the dismiss vulnerability button
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-dismiss-vulnerability
'
)).
toBeNull
();
});
});
});
ee/spec/javascripts/security_dashboard/store/vulnerabilities/actions_spec.js
View file @
9041c27c
This diff is collapsed.
Click to expand it.
ee/
app/assets/javascripts/security_dashboard/store/modules/vulnerabilities
/mock_data_vulnerabilities.json
→
ee/
spec/javascripts/security_dashboard/store/vulnerabilities/data
/mock_data_vulnerabilities.json
View file @
9041c27c
...
...
@@ -32,6 +32,7 @@
},
"dismissal_feedback"
:
null
,
"issue_feedback"
:
null
,
"vulnerability_feedback_url"
:
"https://example.com/vulnerability_feedback"
,
"description"
:
"The cipher does not provide data integrity update 1"
,
"solution"
:
"GCM mode introduces an HMAC into the resulting encrypted data, providing integrity of the result."
,
"location"
:
{
...
...
@@ -81,6 +82,7 @@
},
"dismissal_feedback"
:
null
,
"issue_feedback"
:
null
,
"vulnerability_feedback_url"
:
"https://example.com/vulnerability_feedback"
,
"description"
:
"The cipher does not provide data integrity update 1"
,
"solution"
:
"GCM mode introduces an HMAC into the resulting encrypted data, providing integrity of the result."
,
"location"
:
{
...
...
@@ -152,6 +154,7 @@
"project_fingerprint"
:
"4e5b6966dd100170b4b1ad599c7058cce91b57b4"
},
"issue_feedback"
:
null
,
"vulnerability_feedback_url"
:
"https://example.com/vulnerability_feedback"
,
"description"
:
"The cipher does not provide data integrity update 1"
,
"solution"
:
"GCM mode introduces an HMAC into the resulting encrypted data, providing integrity of the result."
,
"location"
:
{
...
...
@@ -224,6 +227,7 @@
"branch"
:
"master"
,
"project_fingerprint"
:
"4e5b6966dd100170b4b1ad599c7058cce91b57b4"
},
"vulnerability_feedback_url"
:
"https://example.com/vulnerability_feedback"
,
"description"
:
"The cipher does not provide data integrity update 1"
,
"solution"
:
"GCM mode introduces an HMAC into the resulting encrypted data, providing integrity of the result."
,
"location"
:
{
...
...
@@ -318,6 +322,7 @@
"branch"
:
"master"
,
"project_fingerprint"
:
"4e5b6966dd100170b4b1ad599c7058cce91b57b4"
},
"vulnerability_feedback_url"
:
"https://example.com/vulnerability_feedback"
,
"description"
:
"The cipher does not provide data integrity update 1"
,
"solution"
:
"GCM mode introduces an HMAC into the resulting encrypted data, providing integrity of the result."
,
"location"
:
{
...
...
@@ -367,6 +372,7 @@
},
"dismissal_feedback"
:
null
,
"issue_feedback"
:
null
,
"vulnerability_feedback_url"
:
"https://example.com/vulnerability_feedback"
,
"description"
:
"The cipher does not provide data integrity update 1"
,
"solution"
:
"GCM mode introduces an HMAC into the resulting encrypted data, providing integrity of the result."
,
"location"
:
{
...
...
ee/
app/assets/javascripts/security_dashboard/store/modules/vulnerabilities
/mock_data_vulnerabilities_count.json
→
ee/
spec/javascripts/security_dashboard/store/vulnerabilities/data
/mock_data_vulnerabilities_count.json
View file @
9041c27c
File moved
ee/spec/javascripts/security_dashboard/store/vulnerabilities/mutations_spec.js
View file @
9041c27c
This diff is collapsed.
Click to expand it.
locale/gitlab.pot
View file @
9041c27c
...
...
@@ -6661,13 +6661,13 @@ msgstr ""
msgid "Reports|%{failedString} and %{resolvedString}"
msgstr ""
msgid "Reports|
Clas
s"
msgid "Reports|
Action
s"
msgstr ""
msgid "Reports|C
onfidence
"
msgid "Reports|C
lass
"
msgstr ""
msgid "Reports|
Dismiss Vulnerability
"
msgid "Reports|
Confidence
"
msgstr ""
msgid "Reports|Execution time"
...
...
@@ -6676,12 +6676,6 @@ msgstr ""
msgid "Reports|Failure"
msgstr ""
msgid "Reports|More info"
msgstr ""
msgid "Reports|New Issue"
msgstr ""
msgid "Reports|Severity"
msgstr ""
...
...
@@ -7017,12 +7011,39 @@ msgstr ""
msgid "Security Reports|At this time, the security dashboard only supports SAST."
msgstr ""
msgid "Security Reports|Dismiss Vulnerability"
msgstr ""
msgid "Security Reports|More info"
msgstr ""
msgid "Security Reports|New Issue"
msgstr ""
msgid "Security Reports|Security Dashboard Documentation"
msgstr ""
msgid "Security Reports|There was an error creating the issue."
msgstr ""
msgid "Security Reports|There was an error dismissing the issue."
msgstr ""
msgid "Security Reports|There was an error dismissing the vulnerability."
msgstr ""
msgid "Security Reports|There was an error fetching the dashboard. Please try again in a few moments or contact your support team."
msgstr ""
msgid "Security Reports|There was an error undoing the dismissal."
msgstr ""
msgid "Security Reports|There was an error undoing this dismissal."
msgstr ""
msgid "Security Reports|Undo Dismissal"
msgstr ""
msgid "SecurityDashboard| The security dashboard displays the latest security report. Use it to find and fix vulnerabilities."
msgstr ""
...
...
@@ -8696,6 +8717,33 @@ msgstr ""
msgid "VisibilityLevel|Unknown"
msgstr ""
msgid "Vulnerability|Confidence"
msgstr ""
msgid "Vulnerability|Description"
msgstr ""
msgid "Vulnerability|File"
msgstr ""
msgid "Vulnerability|Identifiers"
msgstr ""
msgid "Vulnerability|Instances"
msgstr ""
msgid "Vulnerability|Links"
msgstr ""
msgid "Vulnerability|Project"
msgstr ""
msgid "Vulnerability|Severity"
msgstr ""
msgid "Vulnerability|Solution"
msgstr ""
msgid "Want to see the data? Please ask an administrator for access."
msgstr ""
...
...
@@ -9353,6 +9401,9 @@ msgstr ""
msgid "from"
msgstr ""
msgid "help"
msgstr ""
msgid "here"
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