Skip to content

Commit

Permalink
Match advisories to backend modeling
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosthe19916 committed Apr 22, 2024
1 parent 005b0b5 commit ca90c32
Show file tree
Hide file tree
Showing 19 changed files with 486 additions and 286 deletions.
14 changes: 8 additions & 6 deletions client/src/app/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export interface HubPaginatedResult<T> {

// Base

export interface CVEBase {
id: string;
export interface VulnerabilityBase {
vulnerability_id: string;
title: string;
description: string;
severity: Severity;
Expand Down Expand Up @@ -67,10 +67,12 @@ export interface SBOMBase {
}

export interface AdvisoryBase {
id: string;
identifier: string;
severity: Severity;
published: string;
modified: string;
title: string;
sha256: string;
metadata: {
category: string;
publisher: {
Expand All @@ -97,20 +99,20 @@ export interface AdvisoryBase {
export type Severity = "low" | "moderate" | "important" | "critical";

export interface Advisory extends AdvisoryBase {
cves: CVEBase[];
vulnerabilities: VulnerabilityBase[];
}

// CVE

export interface CVE extends CVEBase {
export interface CVE extends VulnerabilityBase {
related_sboms: SBOMBase[];
related_advisories: AdvisoryBase[];
}

// Package

export interface Package extends PackageBase {
related_cves: CVEBase[];
related_cves: VulnerabilityBase[];
related_sboms: SBOMBase[];
}

Expand Down
5 changes: 2 additions & 3 deletions client/src/app/api/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import {

const API = "/api";

export const ADVISORIES = API + "/advisories";
export const ADVISORIES_SEARCH = API + "/v1/search/advisory";
export const ADVISORIES = API + "/v1/advisory";
export const CVES = API + "/cves";
export const SBOMS = API + "/sboms";
export const PACKAGES = API + "/packages";
Expand Down Expand Up @@ -44,7 +43,7 @@ export const getHubPaginatedResult = <T>(
//

export const getAdvisories = (params: HubRequestParams = {}) => {
return getHubPaginatedResult<Advisory>(ADVISORIES_SEARCH, params);
return getHubPaginatedResult<Advisory>(ADVISORIES, params);
};

export const getAdvisoryById = (id: number | string) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,16 @@ export const serializeFilterForHub = (filter: HubFilter): string => {
const { field, operator, value } = filter;
const joinedValue =
typeof value === "string"
? wrapInQuotesAndEscape(value)
? value
: typeof value === "number"
? `"${value}"`
: `(${value.list
.map(wrapInQuotesAndEscape)
.join(value.operator === "OR" ? "|" : ",")})`;
return `${field}${operator}${joinedValue}`;
? `"${value}"`
: `(${value.list.join(value.operator === "OR" ? "|" : ",")})`;

if (!field) {
return joinedValue;
} else {
return `${field}${operator}${joinedValue}`;
}
};

/**
Expand All @@ -183,9 +186,6 @@ export const serializeFilterRequestParamsForHub = (
) => {
const { filters } = deserializedParams;
if (filters) {
serializedParams.append(
"filter",
filters.map(serializeFilterForHub).join(",")
);
serializedParams.append("q", filters.map(serializeFilterForHub).join(","));
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ export const serializeSortRequestParamsForHub = (
const { sort } = deserializedParams;
if (sort) {
const { field, direction } = sort;
serializedParams.append("sort", `${direction}:${field}`);
serializedParams.append("sort", `${field}:${direction}`);
}
};
93 changes: 17 additions & 76 deletions client/src/app/pages/advisory-details/advisory-details.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
import React from "react";
import ReactMarkdown from "react-markdown";
import { Link } from "react-router-dom";

import {
Breadcrumb,
BreadcrumbItem,
PageSection,
Stack,
StackItem,
TextContent,
} from "@patternfly/react-core";

import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing";

import DetailsPage from "@patternfly/react-component-groups/dist/dynamic/DetailsPage";
import DownloadIcon from "@patternfly/react-icons/dist/esm/icons/download-icon";

import { PathParam, useRouteParams } from "@app/Routes";
import { LoadingWrapper } from "@app/components/LoadingWrapper";
import { SeverityShieldAndText } from "@app/components/SeverityShieldAndText";
import { markdownPFComponents } from "@app/components/markdownPFComponents";

import { useDownload } from "@app/hooks/useDownload";
import { useFetchAdvisoryById } from "@app/queries/advisories";

import { Overview } from "./overview";
import { Source } from "./source";
import { CVEs } from "./cves";
import { Vulnerabilities } from "./vulnerabilities";

export const AdvisoryDetails: React.FC = () => {
const advisoryId = useRouteParams(PathParam.ADVISORY_ID);
const { advisory, isFetching, fetchError } = useFetchAdvisoryById(advisoryId);

const { downloadAdvisory } = useDownload();

return (
<>
<PageSection variant="light">
Expand All @@ -49,33 +36,18 @@ export const AdvisoryDetails: React.FC = () => {
</Breadcrumb>
}
pageHeading={{
title: advisoryId ?? "",
label: advisory
? {
children: (
<SeverityShieldAndText
value={advisory.severity}
/>
),
isCompact: true,
}
: undefined,
title: advisory?.identifier ?? "",
// label: advisory
// ? {
// children: (
// <SeverityShieldAndText
// value={advisory.severity}
// />
// ),
// isCompact: true,
// }
// : undefined,
}}
actionButtons={[
{
children: (
<>
<DownloadIcon /> Download
</>
),
onClick: () => {
if (advisoryId) {
downloadAdvisory(advisoryId);
}
},
variant: "secondary",
},
]}
tabs={[
{
eventKey: "overview",
Expand All @@ -92,52 +64,21 @@ export const AdvisoryDetails: React.FC = () => {
),
},
{
eventKey: "notes",
title: "Notes",
children: (
<div className="pf-v5-u-m-md">
<LoadingWrapper
isFetching={isFetching}
fetchError={fetchError}
>
<TextContent className={spacing.mbMd}>
<Stack hasGutter>
{advisory?.metadata.notes.map((e, index) => (
<StackItem key={index}>
<ReactMarkdown components={markdownPFComponents}>
{e}
</ReactMarkdown>
</StackItem>
))}
</Stack>
</TextContent>
</LoadingWrapper>
</div>
),
},
{
eventKey: "cves",
title: "CVEs",
eventKey: "vulnerabilities",
title: "Vulnerabilities",
children: (
<div className="pf-v5-u-m-md">
<LoadingWrapper
isFetching={isFetching}
fetchError={fetchError}
>
<CVEs cves={advisory?.cves || []} />
<Vulnerabilities
vulnerabilities={advisory?.vulnerabilities || []}
/>
</LoadingWrapper>
</div>
),
},
{
eventKey: "source",
title: "Source",
children: (
<div className="pf-v5-u-m-md">
{advisoryId && <Source advisoryId={advisoryId} />}
</div>
),
},
]}
/>
</PageSection>
Expand Down
40 changes: 24 additions & 16 deletions client/src/app/pages/advisory-details/overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,14 @@ import {
DescriptionListTerm,
Grid,
GridItem,
List,
ListItem,
Stack,
StackItem,
} from "@patternfly/react-core";
import ExternalLinkAltIcon from "@patternfly/react-icons/dist/esm/icons/external-link-alt-icon";

import dayjs from "dayjs";

import { Advisory } from "@app/api/models";
import { RENDER_DATE_FORMAT } from "@app/Constants";
import { SeverityShieldAndText } from "@app/components/SeverityShieldAndText";
import { Advisory } from "@app/api/models";

interface OverviewProps {
advisory: Advisory;
Expand All @@ -35,22 +31,34 @@ export const Overview: React.FC<OverviewProps> = ({ advisory }) => {
<Grid hasGutter>
<GridItem md={4}>
<Card isFullHeight>
<CardTitle>Overview</CardTitle>
<CardTitle>General view</CardTitle>
<CardBody>
<DescriptionList>
<DescriptionListGroup>
<DescriptionListTerm>Title</DescriptionListTerm>
<DescriptionListDescription>
{advisory.cves.map((e) => e.title)}
{advisory.title}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>Category</DescriptionListTerm>
<DescriptionListTerm>Published</DescriptionListTerm>
<DescriptionListDescription>
{advisory.metadata.category}
{dayjs(advisory.published).format(RENDER_DATE_FORMAT)}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>Modified</DescriptionListTerm>
<DescriptionListDescription>
{dayjs(advisory.modified).format(RENDER_DATE_FORMAT)}
</DescriptionListDescription>
</DescriptionListGroup>
{/* <DescriptionListGroup>
<DescriptionListTerm>Category</DescriptionListTerm>
<DescriptionListDescription>
{advisory.metadata.category}
</DescriptionListDescription>
</DescriptionListGroup> */}
{/* <DescriptionListGroup>
<DescriptionListTerm>
Aggregate severity
</DescriptionListTerm>
Expand All @@ -59,12 +67,12 @@ export const Overview: React.FC<OverviewProps> = ({ advisory }) => {
value={advisory.severity}
/>
</DescriptionListDescription>
</DescriptionListGroup>
</DescriptionListGroup> */}
</DescriptionList>
</CardBody>
</Card>
</GridItem>
<GridItem md={4}>
{/* <GridItem md={4}>
<Card isFullHeight>
<CardTitle>Publisher</CardTitle>
<CardBody>
Expand Down Expand Up @@ -98,8 +106,8 @@ export const Overview: React.FC<OverviewProps> = ({ advisory }) => {
</DescriptionList>
</CardBody>
</Card>
</GridItem>
<GridItem md={4}>
</GridItem> */}
{/* <GridItem md={4}>
<Card isFullHeight>
<CardTitle>Tracking</CardTitle>
<CardBody>
Expand Down Expand Up @@ -133,10 +141,10 @@ export const Overview: React.FC<OverviewProps> = ({ advisory }) => {
</DescriptionList>
</CardBody>
</Card>
</GridItem>
</GridItem> */}
</Grid>
</StackItem>
<StackItem>
{/* <StackItem>
<Grid hasGutter>
<GridItem md={4}>
<Card isFullHeight>
Expand All @@ -161,7 +169,7 @@ export const Overview: React.FC<OverviewProps> = ({ advisory }) => {
</Card>
</GridItem>
</Grid>
</StackItem>
</StackItem> */}
</Stack>
</>
);
Expand Down
Loading

0 comments on commit ca90c32

Please sign in to comment.