Skip to content

Commit

Permalink
feat(cve): added option to exclude from returned search results a giv…
Browse files Browse the repository at this point in the history
…en string

Signed-off-by: Laurentiu Niculae <[email protected]>
  • Loading branch information
laurentiuNiculae committed Jan 23, 2024
1 parent 5bf7d56 commit 3df115f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 11 deletions.
5 changes: 4 additions & 1 deletion src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,16 @@ const endpoints = {
`/v2/_zot/ext/search?query={ExpandedRepoInfo(repo:"${name}"){Images {Manifests {Digest Platform {Os Arch} Size} Vulnerabilities {MaxSeverity Count} Tag LastUpdated Vendor IsDeletable } Summary {Name LastUpdated Size Platforms {Os Arch} Vendors IsStarred IsBookmarked NewestImage {RepoName IsSigned SignatureInfo { Tool IsTrusted Author } Vulnerabilities {MaxSeverity Count} Manifests {Digest} Tag Vendor Title Documentation DownloadCount Source Description Licenses}}}}`,
detailedImageInfo: (name, tag) =>
`/v2/_zot/ext/search?query={Image(image: "${name}:${tag}"){RepoName IsSigned SignatureInfo { Tool IsTrusted Author } Vulnerabilities {MaxSeverity Count} Referrers {MediaType ArtifactType Size Digest Annotations{Key Value}} Tag Manifests {History {Layer {Size Digest} HistoryDescription {CreatedBy EmptyLayer}} Digest ConfigDigest LastUpdated Size Platform {Os Arch}} Vendor Licenses }}`,
vulnerabilitiesForRepo: (name, { pageNumber = 1, pageSize = 15 }, searchTerm = '') => {
vulnerabilitiesForRepo: (name, { pageNumber = 1, pageSize = 15 }, searchTerm = '', excludedTerm = '') => {
let query = `/v2/_zot/ext/search?query={CVEListForImage(image: "${name}", requestedPage: {limit:${pageSize} offset:${
(pageNumber - 1) * pageSize
}}`;
if (!isEmpty(searchTerm)) {
query += `, searchedCVE: "${searchTerm}"`;
}
if (!isEmpty(excludedTerm)) {
query += `, excludedCVE: "${excludedTerm}"`;

Check warning on line 101 in src/api.js

View check run for this annotation

Codecov / codecov/patch

src/api.js#L101

Added line #L101 was not covered by tests
}
return `${query}){Tag Page {TotalCount ItemCount} CVEList {Id Title Description Severity PackageList {Name InstalledVersion FixedVersion}} Summary {Count UnknownCount LowCount MediumCount HighCount CriticalCount}}}`;
},
allVulnerabilitiesForRepo: (name) =>
Expand Down
74 changes: 64 additions & 10 deletions src/components/Tag/Tabs/VulnerabilitiesDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import exportFromJSON from 'export-from-json';
import ViewHeadlineIcon from '@mui/icons-material/ViewHeadline';
import ViewAgendaIcon from '@mui/icons-material/ViewAgenda';

import { KeyboardArrowDown, KeyboardArrowRight } from '@mui/icons-material';
import Collapse from '@mui/material/Collapse';

import VulnerabilitiyCard from '../../Shared/VulnerabilityCard';
import VulnerabilityCountCard from '../../Shared/VulnerabilityCountCard';

Expand Down Expand Up @@ -122,6 +125,21 @@ const useStyles = makeStyles((theme) => ({
padding: '0.3rem',
display: 'flex',
justifyContent: 'left'
},
dropdownArrowBox: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
},
dropdownText: {
color: '#1479FF',
fontSize: '1.5rem',
fontWeight: '600',
cursor: 'pointer',
textAlign: 'center'
},
test: {
width: '95%'
}
}));

Expand All @@ -135,8 +153,11 @@ function VulnerabilitiesDetails(props) {
const abortController = useMemo(() => new AbortController(), []);
const { name, tag, digest, platform } = props;

const [openExcludeSearch, setOpenExcludeSearch] = useState(false);

// pagination props
const [cveFilter, setCveFilter] = useState('');
const [cveExcludeFilter, setCveExcludeFilter] = useState('');
const [pageNumber, setPageNumber] = useState(1);
const [isEndOfList, setIsEndOfList] = useState(false);
const listBottom = useRef(null);
Expand All @@ -156,7 +177,8 @@ function VulnerabilitiesDetails(props) {
`${host()}${endpoints.vulnerabilitiesForRepo(
getCVERequestName(),
{ pageNumber, pageSize: EXPLORE_PAGE_SIZE },
cveFilter
cveFilter,
cveExcludeFilter
)}`,
abortController.signal
)
Expand Down Expand Up @@ -255,7 +277,17 @@ function VulnerabilitiesDetails(props) {
setAnchorExport(null);
};

const handleExpandCVESearch = () => {
setOpenExcludeSearch((openExcludeSearch) => !openExcludeSearch);

Check warning on line 281 in src/components/Tag/Tabs/VulnerabilitiesDetails.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tag/Tabs/VulnerabilitiesDetails.jsx#L281

Added line #L281 was not covered by tests
};

const handleCveExcludeFilterChange = (e) => {
const { value } = e.target;
setCveExcludeFilter(value);

Check warning on line 286 in src/components/Tag/Tabs/VulnerabilitiesDetails.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tag/Tabs/VulnerabilitiesDetails.jsx#L285-L286

Added lines #L285 - L286 were not covered by tests
};

const debouncedChangeHandler = useMemo(() => debounce(handleCveFilterChange, 300));
const debouncedExcludeFilterChangeHandler = useMemo(() => debounce(handleCveExcludeFilterChange, 300));

useEffect(() => {
getPaginatedCVEs();
Expand Down Expand Up @@ -289,12 +321,13 @@ function VulnerabilitiesDetails(props) {
useEffect(() => {
if (isLoading) return;
resetPagination();
}, [cveFilter]);
}, [cveFilter, cveExcludeFilter]);

useEffect(() => {
return () => {
abortController.abort();
debouncedChangeHandler.cancel();
debouncedExcludeFilterChangeHandler.cancel();
};
}, []);

Expand Down Expand Up @@ -417,15 +450,36 @@ function VulnerabilitiesDetails(props) {
</Menu>
</Stack>
{renderCVESummary()}
<Stack className={classes.search}>
<InputBase
placeholder={'Search'}
classes={{ root: classes.searchInputBase, input: classes.input }}
onChange={debouncedChangeHandler}
/>
<div className={classes.searchIcon}>
<SearchIcon />
<Stack direction="row">
<div className={classes.dropdownArrowBox} onClick={handleExpandCVESearch}>
{!openExcludeSearch ? (
<KeyboardArrowRight className={classes.dropdownText} />
) : (
<KeyboardArrowDown className={classes.dropdownText} />

Check warning on line 458 in src/components/Tag/Tabs/VulnerabilitiesDetails.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tag/Tabs/VulnerabilitiesDetails.jsx#L458

Added line #L458 was not covered by tests
)}
</div>
<Stack className={classes.test} direction="column" spacing="0.25em">
<Stack className={classes.search}>
<InputBase
placeholder={'Search'}
classes={{ root: classes.searchInputBase, input: classes.input }}
onChange={debouncedChangeHandler}
/>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
</Stack>

<Collapse in={openExcludeSearch} timeout="auto" unmountOnExit>
<Stack className={classes.search}>
<InputBase
placeholder={'Exclude'}
classes={{ root: classes.searchInputBase, input: classes.input }}
onChange={debouncedExcludeFilterChangeHandler}
/>
</Stack>
</Collapse>
</Stack>
</Stack>
{renderCVEs()}
{renderListBottom()}
Expand Down

0 comments on commit 3df115f

Please sign in to comment.