From d7205d0c632dbc372bd263b72f6e59a3eb4b86be Mon Sep 17 00:00:00 2001 From: Saif Chaudhry Date: Wed, 19 Jan 2022 19:40:59 -0800 Subject: [PATCH 1/4] refactoring: using the new GraphQL resolver to get vuln requests for image vulns --- .../DeferredCVEs/DeferredCVEActionsColumn.tsx | 4 +- .../DeferredCVEs/DeferredCVEs.tsx | 5 +- .../DeferredCVEs/DeferredCVEsTable.tsx | 10 ++- .../FalsePositiveCVEActionsColumns.tsx | 4 +- .../FalsePositiveCVEs/FalsePositiveCVEs.tsx | 5 +- .../FalsePositiveCVEsTable.tsx | 6 +- .../ObservedCVEs/ObservedCVEs.tsx | 2 +- .../ObservedCVEs/ObservedCVEsTable.tsx | 2 +- .../imageVulnerabilities.graphql.ts | 66 +++++++++++++++++-- .../RiskAcceptance/useImageVulnerabilities.ts | 43 +----------- .../utils/imageVulnerabilitiesUtils.ts | 25 ------- 11 files changed, 78 insertions(+), 94 deletions(-) delete mode 100644 ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/imageVulnerabilitiesUtils.ts diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEActionsColumn.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEActionsColumn.tsx index ed90df2204088..d48322267d555 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEActionsColumn.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEActionsColumn.tsx @@ -1,10 +1,10 @@ import React, { ReactElement } from 'react'; import { ActionsColumn } from '@patternfly/react-table'; import { DeferredCVEsToBeAssessed } from './types'; -import { VulnerabilityWithRequest } from '../imageVulnerabilities.graphql'; +import { Vulnerability } from '../imageVulnerabilities.graphql'; export type DeferredCVEActionsColumnProps = { - row: VulnerabilityWithRequest; + row: Vulnerability; setVulnsToBeAssessed: React.Dispatch>; canReobserveCVE: boolean; }; diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEs.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEs.tsx index 2ce7fb7198068..202d07974977b 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEs.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferredCVEs/DeferredCVEs.tsx @@ -6,7 +6,6 @@ import { Bullseye, Spinner } from '@patternfly/react-core'; import usePagination from 'hooks/patternfly/usePagination'; import DeferredCVEsTable from './DeferredCVEsTable'; import useImageVulnerabilities from '../useImageVulnerabilities'; -import { VulnerabilityWithRequest } from '../imageVulnerabilities.graphql'; type DeferredCVEsProps = { imageId: string; @@ -22,7 +21,7 @@ function DeferredCVEs({ imageId }: DeferredCVEsProps): ReactElement { offset: (page - 1) * perPage, sortOption: { field: 'cve', - reversed: false, + reversed: true, }, }, }); @@ -36,7 +35,7 @@ function DeferredCVEs({ imageId }: DeferredCVEsProps): ReactElement { } const itemCount = data?.image?.vulnCount || 0; - const rows = (data?.image?.vulns || []) as VulnerabilityWithRequest[]; + const rows = data?.image?.vulns || []; return ( void; @@ -49,7 +49,7 @@ function DeferredCVEsTable({ onSelectAll, onClearAll, getSelectedIds, - } = useTableSelection(rows); + } = useTableSelection(rows); const [vulnsToBeAssessed, setVulnsToBeAssessed] = useState(null); const { undoVulnRequests } = useRiskAcceptance({ requestIDs: vulnsToBeAssessed?.requestIDs || [], @@ -161,9 +161,7 @@ function DeferredCVEsTable({ ) : ( 'N/A' diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEActionsColumns.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEActionsColumns.tsx index e993df03d5d54..b63dd7a2460c4 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEActionsColumns.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEActionsColumns.tsx @@ -1,10 +1,10 @@ import React, { ReactElement } from 'react'; import { ActionsColumn } from '@patternfly/react-table'; import { FalsePositiveCVEsToBeAssessed } from './types'; -import { VulnerabilityWithRequest } from '../imageVulnerabilities.graphql'; +import { Vulnerability } from '../imageVulnerabilities.graphql'; export type FalsePositiveCVEActionsColumnProps = { - row: VulnerabilityWithRequest; + row: Vulnerability; setVulnsToBeAssessed: React.Dispatch>; canReobserveCVE: boolean; }; diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEs.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEs.tsx index 6facc3d987deb..3bc21b7d476ba 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEs.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/FalsePositiveCVEs/FalsePositiveCVEs.tsx @@ -6,7 +6,6 @@ import { Bullseye, Spinner } from '@patternfly/react-core'; import usePagination from 'hooks/patternfly/usePagination'; import FalsePositiveCVEsTable from './FalsePositiveCVEsTable'; import useImageVulnerabilities from '../useImageVulnerabilities'; -import { VulnerabilityWithRequest } from '../imageVulnerabilities.graphql'; type FalsePositiveCVEsProps = { imageId: string; @@ -22,7 +21,7 @@ function FalsePositiveCVEs({ imageId }: FalsePositiveCVEsProps): ReactElement { offset: (page - 1) * perPage, sortOption: { field: 'cve', - reversed: false, + reversed: true, }, }, }); @@ -36,7 +35,7 @@ function FalsePositiveCVEs({ imageId }: FalsePositiveCVEsProps): ReactElement { } const itemCount = data?.image?.vulnCount || 0; - const rows = (data?.image?.vulns || []) as VulnerabilityWithRequest[]; + const rows = data?.image?.vulns || []; return ( void; @@ -48,7 +48,7 @@ function FalsePositiveCVEsTable({ onSelectAll, onClearAll, getSelectedIds, - } = useTableSelection(rows); + } = useTableSelection(rows); const [vulnsToBeAssessed, setVulnsToBeAssessed] = useState(null); const { undoVulnRequests } = useRiskAcceptance({ requestIDs: vulnsToBeAssessed?.requestIDs || [], diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEs.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEs.tsx index fe5b00960a2c2..30a1ddd59c6fa 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEs.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEs.tsx @@ -21,7 +21,7 @@ function ObservedCVEs({ imageId }: ObservedCVEsProps): ReactElement { offset: (page - 1) * perPage, sortOption: { field: 'cve', - reversed: false, + reversed: true, }, }, }); diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx index 28c4542622d59..912702a5b7aa7 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx @@ -197,7 +197,7 @@ function ObservedCVEsTable({ {row.cve} - {row.vulnerabilityRequest && ( + {row.vulnerabilityRequest.id && ( new Date()); - const [data, setData] = useState(); - const client = useApolloClient(); const { loading: isLoading, - data: vulnsData, + data, error, } = useQuery( GET_IMAGE_VULNERABILITIES, @@ -30,44 +23,10 @@ function useImageVulnerabilities({ imageId, vulnsQuery, pagination }) { } ); - useEffect(() => { - if (vulnsData) { - const cves = vulnsData.image.vulns.map((vuln) => vuln.cve).join(','); - const queryObj = vulnsData.image.vulns.length - ? { - CVE: cves, - 'Expired Request': 'false', - } - : {}; - const vulnRequestsQuery = queryService.objectToWhereClause( - queryObj, - encodeURIComponent('+') - ); - fetchVulnRequests({ query: vulnRequestsQuery }) - .then((vulnRequests) => { - const { vulns } = vulnsData.image; - const newVulns = combineVulnsWithVulnRequests(vulns, vulnRequests); - const newVulnsData: GetImageVulnerabilitiesData = { - image: { - name: vulnsData.image.name, - vulns: newVulns, - vulnCount: vulnsData.image.vulnCount, - }, - }; - setData(newVulnsData); - }) - .catch(() => { - // @TODO: Handle error - }); - } - // since sometimes when we refetch, the vulns data won't change, we need another indicator for refecthing - }, [vulnsData, lastTimeRefetched]); - async function refetchQuery() { await client.refetchQueries({ include: [GET_IMAGE_VULNERABILITIES], }); - setLastTimeRefetched(new Date()); } return { isLoading, data, error, refetchQuery }; diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/imageVulnerabilitiesUtils.ts b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/imageVulnerabilitiesUtils.ts deleted file mode 100644 index 76b774abd6e2d..0000000000000 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/imageVulnerabilitiesUtils.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { VulnerabilityRequest } from 'types/vuln_request.proto'; -import { Vulnerability } from '../imageVulnerabilities.graphql'; - -export function combineVulnsWithVulnRequests( - vulns: Vulnerability[], - vulnRequests: VulnerabilityRequest[] -) { - // create a map of cve->vulnRequest - const cveToVulnRequestMap = vulnRequests.reduce((acc, vulnRequest) => { - const cve = vulnRequest.cves.ids[0]; - acc[cve] = vulnRequest; - return acc; - }, {} as Record); - // iterate through the vulns and add the vulnRequest if it exists for the specified cve - const modifiedVulns = - vulns.map((vuln) => { - const modifiedVuln = { ...vuln }; - if (cveToVulnRequestMap[vuln.cve]) { - modifiedVuln.vulnerabilityRequest = cveToVulnRequestMap[vuln.cve]; - } - return modifiedVuln; - }) || []; - return modifiedVulns; -} From 20de2334e87548bb9d928cac07c050e8a73436b3 Mon Sep 17 00:00:00 2001 From: Saif Chaudhry Date: Wed, 19 Jan 2022 20:23:01 -0800 Subject: [PATCH 2/4] fixes --- .../VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx | 4 +++- .../VulnRequestedAction/VulnRequestedAction.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx index c1087a692768a..8c8ab2da6832f 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx @@ -28,7 +28,9 @@ function DeferralExpirationDate({ : deferralReq; if (expiresWhenFixed) { expirationDate = 'When fixed'; - } else if (expiresOn) { + // The backend returns the following date when the deferral request is indefinitely + // We should ideally return a null + } else if (expiresOn && expiresOn !== '1970-01-01T00:00:00Z') { expirationDate = getDate(expiresOn); } else { expirationDate = 'Never'; diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx index 0d8f27b42a06a..5195bb2b12a21 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx @@ -41,7 +41,9 @@ function VulnRequestedAction({ : deferralReq; if (expiresWhenFixed) { action = '(until fixed)'; - } else if (expiresOn) { + // The backend returns the following date when the deferral request is indefinitely + // We should ideally return a null + } else if (expiresOn && expiresOn !== '1970-01-01T00:00:00Z') { const expiresOnDistance = getDistanceStrict(expiresOn, currentDate, { partialMethod: 'ceil', unit: 'd', From cca47be095d66b5bfbeb06f89ace93b87a525e03 Mon Sep 17 00:00:00 2001 From: Saif Chaudhry Date: Wed, 19 Jan 2022 21:11:51 -0800 Subject: [PATCH 3/4] fixes --- .../VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx | 4 +--- .../RiskAcceptance/ObservedCVEs/useDeferVulnerability.ts | 2 +- .../VulnRequestedAction/VulnRequestedAction.tsx | 4 +--- .../VulnMgmt/RiskAcceptance/useRiskAcceptance.ts | 8 +------- .../VulnMgmt/RiskAcceptance/utils/vulnRequestFormUtils.ts | 2 +- .../RiskAcceptance/vulnerabilityRequests.graphql.ts | 2 +- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx index 8c8ab2da6832f..c1087a692768a 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/DeferralExpirationDate.tsx @@ -28,9 +28,7 @@ function DeferralExpirationDate({ : deferralReq; if (expiresWhenFixed) { expirationDate = 'When fixed'; - // The backend returns the following date when the deferral request is indefinitely - // We should ideally return a null - } else if (expiresOn && expiresOn !== '1970-01-01T00:00:00Z') { + } else if (expiresOn) { expirationDate = getDate(expiresOn); } else { expirationDate = 'Never'; diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/useDeferVulnerability.ts b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/useDeferVulnerability.ts index e3f010829c7d7..a86a2b6a17d68 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/useDeferVulnerability.ts +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/useDeferVulnerability.ts @@ -31,7 +31,7 @@ function useDeferVulnerability({ cveIDs, registry, remote, tag }: UseDeferVulner }; if (expiresOn) { request.expiresOn = expiresOn; - } else { + } else if (expiresWhenFixed) { request.expiresWhenFixed = expiresWhenFixed; } const variables = { request }; diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx index 5195bb2b12a21..0d8f27b42a06a 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/VulnRequestedAction/VulnRequestedAction.tsx @@ -41,9 +41,7 @@ function VulnRequestedAction({ : deferralReq; if (expiresWhenFixed) { action = '(until fixed)'; - // The backend returns the following date when the deferral request is indefinitely - // We should ideally return a null - } else if (expiresOn && expiresOn !== '1970-01-01T00:00:00Z') { + } else if (expiresOn) { const expiresOnDistance = getDistanceStrict(expiresOn, currentDate, { partialMethod: 'ceil', unit: 'd', diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/useRiskAcceptance.ts b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/useRiskAcceptance.ts index 534a696fa0c11..c7202cb44578c 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/useRiskAcceptance.ts +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/useRiskAcceptance.ts @@ -89,15 +89,9 @@ function useRiskAcceptance({ requestIDs }: UseRiskAcceptance) { function updateVulnRequests(formValues) { const { comment } = formValues; - let expiry = {}; const expiresWhenFixed = getExpiresWhenFixedValue(formValues.expiresOn); const expiresOn = getExpiresOnValue(formValues.expiresOn); - if (expiresWhenFixed) { - expiry = { ...expiry, expiresWhenFixed }; - } - if (expiresOn !== undefined) { - expiry = { ...expiry, expiresOn }; - } + const expiry = { expiresOn, expiresWhenFixed }; const promises = requestIDs.map((requestID) => { const variables: UpdateVulnerabilityRequest = { diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/vulnRequestFormUtils.ts b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/vulnRequestFormUtils.ts index 93b8ed755838f..c4984c3057fdf 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/vulnRequestFormUtils.ts +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/utils/vulnRequestFormUtils.ts @@ -16,7 +16,7 @@ export function getExpiresOnValue(expiresOn: ExpiresOn): string | number | undef } else if (expiresOn === '90 days') { value = addDaysToDate(new Date(), 90); } else if (expiresOn === 'Indefinitely') { - value = 0; + value = undefined; } return value; } diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/vulnerabilityRequests.graphql.ts b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/vulnerabilityRequests.graphql.ts index bfcb17ab57713..0b684d964a797 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/vulnerabilityRequests.graphql.ts +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/vulnerabilityRequests.graphql.ts @@ -168,7 +168,7 @@ export type UpdateVulnerabilityRequest = { comment: string; expiry: { expiresWhenFixed?: boolean; - expiresOn?: string; // graphql.Time format (2021-12-03T18:25:39.397427643Z) + expiresOn?: string | number | undefined; // graphql.Time format (2021-12-03T18:25:39.397427643Z) }; }; From 9b1622f49cced39dc19edd88cfddfff3c8c51823 Mon Sep 17 00:00:00 2001 From: Saif Chaudhry Date: Thu, 20 Jan 2022 09:55:06 -0800 Subject: [PATCH 4/4] addressing comments --- .../RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx | 2 +- .../RiskAcceptance/ObservedCVEs/useDeferVulnerability.ts | 3 ++- .../VulnMgmt/RiskAcceptance/utils/vulnRequestFormUtils.ts | 6 +++--- .../RiskAcceptance/vulnerabilityRequests.graphql.ts | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx index 912702a5b7aa7..46e152d46eaaa 100644 --- a/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx +++ b/ui/apps/platform/src/Containers/VulnMgmt/RiskAcceptance/ObservedCVEs/ObservedCVEsTable.tsx @@ -197,7 +197,7 @@ function ObservedCVEsTable({ {row.cve} - {row.vulnerabilityRequest.id && ( + {row.vulnerabilityRequest?.id && (