Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVEs without errata feature #1908

Merged
merged 9 commits into from
Aug 4, 2023
Merged
8 changes: 7 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"CVEsReport.filters.advisoryAvailable": "{prefix} advisory <b>{values}</b>",
"CVEsReport.filters.businessRisk": "{prefix} business risk of <b>{values}</b>",
"CVEsReport.filters.osVersion": "{prefix} which apply to <b>{values}</b>",
"CVEsReport.filters.securityRule": "{prefix} <b>{values}</b>",
Expand All @@ -8,11 +9,13 @@
"CVEsReport.subheaderExploit": "Of the identified CVEs, <b>{knownExploitCount, plural, one {# CVE} other {# CVEs}}</b> {knownExploitCount, plural, one {has} other {have}} a known exploit.",
"actions": "Actions",
"advisory": "Advisory",
"advisoryColumnTooltip": "CVEs with the Security rule label will appear in this list regardless of whether or not an advisory is available. For standard CVEs, advisories may not exist for all major/minor versions of RHEL. Click on the CVE to determine which OS versions have supported advisories.",
"advisoryName": "Advisory name",
"advisoryTooltip": "An advisory is not available. For more information, view this CVE in the {link}",
"affectsSystems": "Systems",
"ansibleRemediationTooltip": "You can create Ansible Playbooks and remediate your systems with Remediation application",
"associatedCves": "Associated CVEs:",
"available": "Available",
"businessRisk": "Business risk",
"businessRiskHighToLow": "Business risk: High to Low",
"businessRiskLowToHigh": "Business risk: Low to High",
Expand Down Expand Up @@ -109,7 +112,8 @@
"emptyState.notConnected.buttonText": "Learn how to activate the Insights client",
"emptyState.notConnected.titleText": "This system isn’t connected to Insights yet",
"emptyState.prodSecLink": "Red Hat Product Security",
"emptyState.thereShouldBeCVE": "As of today, Insights Vulnerability shows CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}",
"emptyState.thereShouldBeCVE": "Currently, you are only viewing CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please adjust your settings and search again. Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}",
"emptyState.thereShouldBeCVE.noErrata": "Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}",
"emptyState.thisSystemShouldHaveCVEs": "If you think this system has applicable CVEs or would like more information, contact {prodSecLink}.",
"emptyStateSystem.enableAnalysis": "Enable Vulnerability analysis",
"emptyStateSystemDisabled.body": "Vulnerability analysis on this system has been disabled. It is not being evaluated for potential vulnerabilities by Red Hat Insights.",
Expand Down Expand Up @@ -156,6 +160,7 @@
"filter.withoutSecurityRule": "Does not have security rule",
"filterByAffectedSystems": "Filter by {count, plural, =-1 {affected systems} one {# system} other {# systems}}",
"hasKnownExploit": "Has a known exploit",
"hideCvesWithoutAdvisories": "Hide CVEs without Advisories",
"high": "High",
"impactList.critical": "Critical",
"impactList.high": "High",
Expand Down Expand Up @@ -282,6 +287,7 @@
"selectPage": "Select page ({count, plural, one {# item} other {# items}})",
"severityHighToLow": "Severity: High to Low",
"severityLowToHigh": "Severity: Low to High",
"showCvesWithoutAdvisories": "Show CVEs without Advisories",
"status": "Status",
"systemKebab.disableAnalysis": "Disable Vulnerability analysis on {count, plural, one {system} other {systems}}",
"systemKebab.enableAnalysis": "Enable Vulnerability analysis on {count, plural, one {system} other {systems}}",
Expand Down
36 changes: 19 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@redhat-cloud-services/frontend-components-translations": "^3.2.4",
"@redhat-cloud-services/frontend-components-utilities": "^3.7.0",
"@redhat-cloud-services/host-inventory-client": "^1.0.116",
"@redhat-cloud-services/vulnerabilities-client": "^1.0.116",
"@redhat-cloud-services/vulnerabilities-client": "^1.2.5",
"@scalprum/react-core": "^0.1.9",
"@unleash/proxy-client-react": "^3.6.0",
"axios": "^1.4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ exports[`Empty states should render EmptyStateNoCVEs 1`] = `
<EmptyStateNoCVEs
secondParagraph={
{
"defaultMessage": "As of today, Insights Vulnerability shows CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}",
"defaultMessage": "Currently, you are only viewing CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please adjust your settings and search again. Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}",
"description": "Paragraph for empty state component advising to contact support when there is a problem",
"id": "emptyState.thereShouldBeCVE",
}
Expand Down Expand Up @@ -238,7 +238,7 @@ exports[`Empty states should render EmptyStateNoCVEs 1`] = `
data-pf-content={true}
>
<FormattedMessage
defaultMessage="As of today, Insights Vulnerability shows CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}"
defaultMessage="Currently, you are only viewing CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please adjust your settings and search again. Please check the {cveDatabaseLink} or if you would like more information, contact {prodSecLink}"
description="Paragraph for empty state component advising to contact support when there is a problem"
id="emptyState.thereShouldBeCVE"
values={
Expand Down Expand Up @@ -280,7 +280,7 @@ exports[`Empty states should render EmptyStateNoCVEs 1`] = `
}
}
>
As of today, Insights Vulnerability shows CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please check the
Currently, you are only viewing CVEs with Errata. It is possible the CVE you are searching for does not yet have an associated Errata. Please adjust your settings and search again. Please check the
<a
href="https://access.redhat.com/security/security-updates/#/cve"
key=".$.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { conditionalFilterType } from '@redhat-cloud-services/frontend-components/ConditionalFilter';
import { ADVISORY_AVAILABILITY_FILTER_OPTIONS } from '../../../../Helpers/constants';
import { intl } from '../../../../Utilities/IntlProvider';
import messages from '../../../../Messages';

const AdvisoryAvailabilityFilter = (apply, currentFilter = {}) => {
let { advisory_available: currentValue } = currentFilter;

const filterByAdvisoryAvailability = values => {
apply({
advisory_available: values.length > 0 ? values?.join(',') : undefined,
page: 1
});
};

return {
label: intl.formatMessage(messages.advisory),
type: conditionalFilterType.checkbox,
key: 'advisory_available',
filterValues: {
onChange: (event, value) => {
filterByAdvisoryAvailability(value);
},
items: ADVISORY_AVAILABILITY_FILTER_OPTIONS.map(({ label, value }) => ({ label, value })),
value: currentValue?.split(',')
}
};
};

export default AdvisoryAvailabilityFilter;
22 changes: 15 additions & 7 deletions src/Components/SmartComponents/CVEs/CVEs.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ export const CVEs = ({ rbac }) => {
const [CveBusinessRiskModal, setBusinessRiskModal] = useState(() => () => null);
const [isFirstLoad, setFirstLoad] = useState(true);

const [[canEditStatusOrBusinessRisk, canEditPairStatus, canExport, canReadVulnerabilityResults], isRbacLoading] = rbac;
const [[
canEditStatusOrBusinessRisk,
canEditPairStatus,
canExport,
canReadVulnerabilityResults,
canToggleCvesWithoutErrata
], isRbacLoading] = rbac;

const cveList = useSelector(
({ CVEsStore }) => CVEsStore.cveList
Expand Down Expand Up @@ -132,7 +138,7 @@ export const CVEs = ({ rbac }) => {

if (!cves.errors) {
return (
isRbacLoading ? <Spinner centered/> : canReadVulnerabilityResults ?
isRbacLoading ? <Spinner centered /> : canReadVulnerabilityResults ?
(
<CVETableContext.Provider
value={{
Expand All @@ -152,16 +158,17 @@ export const CVEs = ({ rbac }) => {
}
}}
>
<CveBusinessRiskModal/>
<CveStatusModal/>
<CveBusinessRiskModal />
<CveStatusModal />

{ ColumnManagementModal }
{ColumnManagementModal}

<Stack>
<StackItem>
<CVEsTableToolbar
canEditStatusOrBusinessRisk={canEditStatusOrBusinessRisk}
canExport={canExport}
canToggleCvesWithoutErrata={canToggleCvesWithoutErrata}
/>
</StackItem>
<StackItem>
Expand All @@ -175,7 +182,7 @@ export const CVEs = ({ rbac }) => {
) : <NotAuthorized serviceName={SERVICE_NAME} />
);
} else {
return <ErrorHandler code={cves.errors.status}/>;
return <ErrorHandler code={cves.errors.status} />;
}
};

Expand All @@ -188,7 +195,8 @@ const CVEsWithRbac = () => {
PERMISSIONS.setCveStatusAndBusinessRisk,
PERMISSIONS.setPairStatus,
PERMISSIONS.basicReporting,
PERMISSIONS.readVulnerabilityResults
PERMISSIONS.readVulnerabilityResults,
PERMISSIONS.toggleCvesWithoutErrata
]);

return <CVEs rbac={rbac} />;
Expand Down
9 changes: 8 additions & 1 deletion src/Components/SmartComponents/CVEs/CVEsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ const CVEsTableWithContext = ({ context, header, canEditStatusOrBusinessRisk })
cells: [
{
props: { colSpan: header?.length },
title: <EmptyStateNoCVEs secondParagraph={messages.emptyStateThereShouldBeCVEs} />
title:
<EmptyStateNoCVEs
secondParagraph={
context.cves.meta.cves_without_errata
? messages.emptyStateThereShouldBeCVEsNoErrata
: messages.emptyStateThereShouldBeCVEs
}
/>
}
]
}]);
Expand Down
34 changes: 29 additions & 5 deletions src/Components/SmartComponents/CVEs/CVEsTableToolbar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable camelcase */
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import propTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import messages from '../../../Messages';
Expand All @@ -15,6 +15,7 @@ import securityRuleFilter from '../../PresentationalComponents/Filters/PrimaryTo
import businessRiskFilter from '../../PresentationalComponents/Filters/PrimaryToolbarFilters/BusinessRiskFilter';
import knownExploitFilter from '../../PresentationalComponents/Filters/PrimaryToolbarFilters/KnownExploitFilter';
import statusFilter from '../../PresentationalComponents/Filters/PrimaryToolbarFilters/StatusFilter';
import advisoryAvailabilityFilter from '../../PresentationalComponents/Filters/PrimaryToolbarFilters/AdvisoryAvailabilityFilter';
import { kebabItemDownloadPDF } from '../../PresentationalComponents/Kebab/KebabItems';
import DownloadCVEsReport from '../Reports/DownloadCVEsReport';
import {
Expand All @@ -32,15 +33,25 @@ import {
RULE_PRESENCE_OPTIONS
} from '../../../Helpers/constants';
import { fetchCvesIds } from '../../../Store/Actions/Actions';
import { setCvesWithoutErrata } from '../../../Helpers/APIHelper';

const CVEsTableToolbarWithContext = ({ context, canEditStatusOrBusinessRisk, canExport, intl }) => {
const CVEsTableToolbarWithContext = ({ context, canEditStatusOrBusinessRisk, canExport, canToggleCvesWithoutErrata, intl }) => {
const [exportPDF, setExportPDF] = useState(false);

const { cves, params, methods, selectedCves } = context;
const { isLoading } = cves;

const { filter } = params;
const selectedCvesCount = selectedCves && selectedCves.length;

const [showCvesWithoutErrata, setShowCvesWithoutErrata] = useState(false);

useEffect(() => {
if (!isLoading) {
setShowCvesWithoutErrata(cves?.meta?.cves_without_errata);
}
}, [cves?.meta?.cves_without_errata, isLoading]);

const selectOptions = selectAllCheckbox({
selectedItems: selectedCves,
selectorHandler: methods.selectCves,
Expand Down Expand Up @@ -86,7 +97,18 @@ const CVEsTableToolbarWithContext = ({ context, canEditStatusOrBusinessRisk, can
{
label: intl.formatMessage(messages.columnManagementModalTitle),
onClick: () => methods.setColumnManagementModalOpen(true)
}
},
...canToggleCvesWithoutErrata ? [(
showCvesWithoutErrata ?
{
label: intl.formatMessage(messages.hideCvesWithoutAdvisories),
onClick: () => setCvesWithoutErrata(false).then(() => methods.apply({ page: 1 }))
} :
{
label: intl.formatMessage(messages.showCvesWithoutAdvisories),
onClick: () => setCvesWithoutErrata(true).then(() => methods.apply({ page: 1 }))
}
)] : []
];

return (
Expand Down Expand Up @@ -128,7 +150,8 @@ const CVEsTableToolbarWithContext = ({ context, canEditStatusOrBusinessRisk, can
businessRiskFilter(methods.apply, params),
affectingFilter(methods.apply, params),
publishDateFilter(methods.apply, params),
statusFilter(methods.apply, params)
statusFilter(methods.apply, params),
...showCvesWithoutErrata ? [advisoryAvailabilityFilter(methods.apply, params)] : []
]
}}
activeFiltersConfig={{
Expand Down Expand Up @@ -161,7 +184,8 @@ CVEsTableToolbarWithContext.propTypes = {
context: propTypes.object,
intl: propTypes.object,
canEditStatusOrBusinessRisk: propTypes.bool,
canExport: propTypes.bool
canExport: propTypes.bool,
canToggleCvesWithoutErrata: propTypes.bool
};

CVEsTableToolbarWithContext.defaultProps = {
Expand Down
Loading
Loading