Skip to content

Commit

Permalink
feat: add Vuln Details -> Related SBOMBs -> dependencies list (#298)
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosthe19916 authored Dec 13, 2024
1 parent 0b7425f commit d9a005a
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 34 deletions.
16 changes: 10 additions & 6 deletions client/openapi/trustd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3908,13 +3908,17 @@ components:
- $ref: '#/components/schemas/SbomHead'
- type: object
required:
- status
- purl_statuses
properties:
status:
type: array
items:
purl_statuses:
type: object
additionalProperties:
type: array
items:
$ref: '#/components/schemas/PurlSummary'
uniqueItems: true
propertyNames:
type: string
uniqueItems: true
version:
type:
- string
Expand Down Expand Up @@ -3942,4 +3946,4 @@ components:
oneOf:
- type: 'null'
- $ref: '#/components/schemas/Severity'
description: Average (arithmetic mean) severity of the vulnerability aggregated from *all* related advisories.
description: Average (arithmetic mean) severity of the vulnerability aggregated from *all* related advisories.
16 changes: 11 additions & 5 deletions client/src/app/client/schemas.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2624,14 +2624,20 @@ export const VulnerabilitySbomStatusSchema = {
},
{
type: "object",
required: ["status"],
required: ["purl_statuses"],
properties: {
status: {
type: "array",
items: {
purl_statuses: {
type: "object",
additionalProperties: {
type: "array",
items: {
$ref: "#/components/schemas/PurlSummary",
},
uniqueItems: true,
},
propertyNames: {
type: "string",
},
uniqueItems: true,
},
version: {
type: ["string", "null"],
Expand Down
4 changes: 3 additions & 1 deletion client/src/app/client/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,9 @@ export type VulnerabilityHead = {
};

export type VulnerabilitySbomStatus = SbomHead & {
status: Array<string>;
purl_statuses: {
[key: string]: Array<PurlSummary>;
};
version?: string | null;
};

Expand Down
38 changes: 24 additions & 14 deletions client/src/app/hooks/domain-controls/useSbomsOfVulnerability.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from "react";

import { VulnerabilityStatus } from "@app/api/models";
import { SbomHead, VulnerabilityAdvisorySummary } from "@app/client";
import {
PurlSummary,
VulnerabilityAdvisorySummary,
VulnerabilitySbomStatus,
} from "@app/client";
import { useFetchVulnerabilityById } from "@app/queries/vulnerabilities";

const areSbomOfVulnerabilityEqual = (
Expand All @@ -12,16 +16,18 @@ const areSbomOfVulnerabilityEqual = (
};

interface FlatSbomOfVulnerability {
sbom: SbomHead & { version: string | null };
sbom: VulnerabilitySbomStatus;
sbomStatus: VulnerabilityStatus;
advisory: VulnerabilityAdvisorySummary;
packages: PurlSummary[];
}

interface SbomOfVulnerability {
sbom: SbomHead & { version: string | null };
sbom: VulnerabilitySbomStatus;
sbomStatus: VulnerabilityStatus;
relatedPackages: {
advisory: VulnerabilityAdvisorySummary;
packages: PurlSummary[];
}[];
}

Expand All @@ -40,17 +46,19 @@ const advisoryToModels = (advisories: VulnerabilityAdvisorySummary[]) => {
return (
(advisory.sboms ?? [])
.flatMap((sbomStatuses) => {
return sbomStatuses.status.map((sbomStatus) => {
const result: FlatSbomOfVulnerability = {
sbom: {
...sbomStatuses,
version: sbomStatuses.version || null,
},
sbomStatus: sbomStatus as VulnerabilityStatus,
advisory: advisory,
};
return result;
});
return Object.entries(sbomStatuses.purl_statuses || {}).map(
([status, packages]) => {
const result: FlatSbomOfVulnerability = {
sbom: {
...sbomStatuses,
},
sbomStatus: status as VulnerabilityStatus,
advisory: advisory,
packages: packages,
};
return result;
}
);
})
// group
.reduce((prev, current) => {
Expand All @@ -69,6 +77,7 @@ const advisoryToModels = (advisories: VulnerabilityAdvisorySummary[]) => {
...existingElement.relatedPackages,
{
advisory: current.advisory,
packages: current.packages,
},
],
};
Expand All @@ -81,6 +90,7 @@ const advisoryToModels = (advisories: VulnerabilityAdvisorySummary[]) => {
relatedPackages: [
{
advisory: current.advisory,
packages: current.packages,
},
],
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export const PrimaryState: Story = {
],
name: "quarkus-bom",
version: "3.2.12.Final-redhat-00002",
status: ["affected"],
purl_statuses: {
affected: [],
},
number_of_packages: 1,
},
{
Expand All @@ -93,7 +95,9 @@ export const PrimaryState: Story = {
],
name: "quarkus-bom",
version: "3.2.11.Final-redhat-00001",
status: ["affected"],
purl_statuses: {
affected: [],
},
number_of_packages: 1,
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import { Link } from "react-router-dom";
import dayjs from "dayjs";

import { Toolbar, ToolbarContent, ToolbarItem } from "@patternfly/react-core";
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
import {
ExpandableRowContent,
Table,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@patternfly/react-table";

import { FilterType } from "@app/components/FilterToolbar";
import { SimplePagination } from "@app/components/SimplePagination";
Expand All @@ -17,7 +25,8 @@ import { VulnerabilityStatusLabel } from "@app/components/VulnerabilityStatusLab
import { useSbomsOfVulnerability } from "@app/hooks/domain-controls/useSbomsOfVulnerability";
import { useLocalTableControls } from "@app/hooks/table-controls";
import { useWithUiId } from "@app/utils/query-utils";
import { formatDate } from "@app/utils/utils";
import { decomposePurl, formatDate } from "@app/utils/utils";
import { PackageQualifiers } from "@app/components/PackageQualifiers";

interface SbomsByVulnerabilityProps {
vulnerabilityId: string;
Expand All @@ -41,7 +50,7 @@ export const SbomsByVulnerability: React.FC<SbomsByVulnerabilityProps> = ({
tableName: "sboms-table",
idProperty: "_ui_unique_id",
items: tableDataWithUiId,
isLoading: false,
isLoading: isFetching,
columnNames: {
name: "Name",
version: "Version",
Expand Down Expand Up @@ -69,7 +78,8 @@ export const SbomsByVulnerability: React.FC<SbomsByVulnerabilityProps> = ({
getItemValue: (item) => item.sbom?.name ?? "",
},
],
isExpansionEnabled: false,
isExpansionEnabled: true,
expandableVariant: "compound",
});

const {
Expand All @@ -84,6 +94,7 @@ export const SbomsByVulnerability: React.FC<SbomsByVulnerabilityProps> = ({
getThProps,
getTrProps,
getTdProps,
getExpandedContentTdProps,
},
expansionDerivedState: { isCellExpanded },
} = tableControls;
Expand Down Expand Up @@ -149,9 +160,14 @@ export const SbomsByVulnerability: React.FC<SbomsByVulnerabilityProps> = ({
</Td>
<Td
width={10}
{...getTdProps({ columnKey: "dependencies" })}
{...getTdProps({
columnKey: "dependencies",
isCompoundExpandToggle: true,
item: item,
rowIndex,
})}
>
{item?.sbom?.number_of_packages}
{item.relatedPackages.length}
</Td>
<Td width={10} {...getTdProps({ columnKey: "supplier" })}>
{item?.sbom?.authors.join(", ")}
Expand All @@ -165,6 +181,63 @@ export const SbomsByVulnerability: React.FC<SbomsByVulnerabilityProps> = ({
</Td>
</TableRowContentWithControls>
</Tr>
{isCellExpanded(item) ? (
<Tr isExpanded>
<Td
{...getExpandedContentTdProps({
item,
})}
>
<ExpandableRowContent>
{isCellExpanded(item, "dependencies") ? (
<>
<Table variant="compact">
<Thead>
<Tr>
<Th>Type</Th>
<Th>Namespace</Th>
<Th>Name</Th>
<Th>Version</Th>
<Th>Path</Th>
<Th>Qualifiers</Th>
</Tr>
</Thead>
<Tbody>
{item.relatedPackages
.flatMap((item) => item.packages)
.map((purl, index) => {
const decomposedPurl = decomposePurl(
purl.purl
);
return (
<Tr key={`${index}-purl`}>
<Td>{decomposedPurl?.type}</Td>
<Td>{decomposedPurl?.namespace}</Td>
<Td>
<Link to={`/packages/${purl.uuid}`}>
{decomposedPurl?.name}
</Link>
</Td>
<Td>{decomposedPurl?.version}</Td>
<Td>{decomposedPurl?.path}</Td>
<Td>
{decomposedPurl?.qualifiers && (
<PackageQualifiers
value={decomposedPurl?.qualifiers}
/>
)}
</Td>
</Tr>
);
})}
</Tbody>
</Table>
</>
) : null}
</ExpandableRowContent>
</Td>
</Tr>
) : null}
</Tbody>
);
})}
Expand Down

0 comments on commit d9a005a

Please sign in to comment.