Skip to content

Commit

Permalink
Fix: Display CPE Name ID and deprecation status at CPE details
Browse files Browse the repository at this point in the history
Ensure the model data is parsed correctly and contains the expected
values. Display the CPE Name ID instead of the former NVD ID at the
CPE details. Also the CPE status is not available anymore and only the
deprecation status is shown.
  • Loading branch information
bjoernricks committed Jan 29, 2025
1 parent c48623c commit 4c215ad
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 8 deletions.
59 changes: 58 additions & 1 deletion src/gmp/models/__tests__/cpe.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import Cpe from 'gmp/models/cpe';
import {isDate} from 'gmp/models/date';
import {testModel} from 'gmp/models/testing';

/* eslint-disable camelcase */

testModel(Cpe, 'cpe');

describe('CPE model tests', () => {
Expand Down Expand Up @@ -88,17 +90,72 @@ describe('CPE model tests', () => {
expect(isDate(cpe.updateTime)).toBe(true);
});

test('should parse deprecatedBy', () => {
test('should parse deprecatedBy from raw data', () => {
const cpe = Cpe.fromElement({
raw_data: {'cpe-item': {_deprecated_by: 'foo:/bar'}},
});
expect(cpe.deprecatedBy).toEqual('foo:/bar');

const cpe2 = Cpe.fromElement({
deprecated: 0,
deprecated_by: {_cpe_id: 'foo:/bar'},
raw_data: {'cpe-item': {_deprecated_by: 'foo:/baz'}},
});
expect(cpe2.deprecatedBy).toEqual('foo:/baz');
});

test('should parse deprecated', () => {
const cpe = Cpe.fromElement({
deprecated: 1,
});
expect(cpe.deprecated).toBe(true);

const cpe2 = Cpe.fromElement({
deprecated: 0,
});
expect(cpe2.deprecated).toBe(false);

const cpe3 = Cpe.fromElement({});
expect(cpe3.deprecated).toBe(false);
});

test('should parse deprecatedBy', () => {
const cpe = Cpe.fromElement({
deprecated: 1,
deprecated_by: {_cpe_id: 'foo:/bar'},
});
expect(cpe.deprecatedBy).toEqual('foo:/bar');

const cpe2 = Cpe.fromElement({
deprecated: 1,
deprecated_by: {_cpe_id: 'foo:/bar'},
raw_data: {'cpe-item': {_deprecated_by: 'foo:/baz'}},
});

expect(cpe2.deprecatedBy).toEqual('foo:/bar');
});

test('should not parse deprecatedBy', () => {
const cpe = Cpe.fromElement({raw_data: {'cpe-item': {}}});

expect(cpe.deprecatedBy).toBeUndefined();
});

test('should parse old nvd_id', () => {
const cpe = Cpe.fromElement({nvd_id: 'ABC'});

expect(cpe.cpeNameId).toEqual('ABC');
expect(cpe.nvd_id).toBeUndefined();
});

test('should parse cpeNameId', () => {
const cpe = Cpe.fromElement({cpe_name_id: 'ABC'});
const cpe2 = Cpe.fromElement({cpe_name_id: 'ABC', nvd_id: 'DEF'});

expect(cpe.cpeNameId).toEqual('ABC');
expect(cpe.cpe_name_id).toBeUndefined();

expect(cpe2.cpeNameId).toEqual('ABC');
expect(cpe2.cpe_name_id).toBeUndefined();
});
});
20 changes: 17 additions & 3 deletions src/gmp/models/cpe.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {parseSeverity, parseDate} from 'gmp/parser';
import {parseSeverity, parseDate, parseBoolean} from 'gmp/parser';
import {map} from 'gmp/utils/array';
import {isDefined} from 'gmp/utils/identity';
import {isEmpty} from 'gmp/utils/string';
Expand Down Expand Up @@ -31,7 +31,14 @@ class Cpe extends Info {
}

if (isDefined(ret.nvd_id)) {
ret.nvdId = ret.nvd_id;
// old ID from nvd just kept for backwards compatibility and should be removed in future
ret.cpeNameId = ret.nvd_id;
delete ret.nvd_id;
}

if (isDefined(ret.cpe_name_id)) {
ret.cpeNameId = ret.cpe_name_id;
delete ret.cpe_name_id;
}

if (isDefined(ret.update_time)) {
Expand All @@ -44,8 +51,15 @@ class Cpe extends Info {
* Once `raw_data` is removed from the API, this backup check can be removed.
*/

if (ret.deprecated === 1 && isDefined(ret.deprecated_by)) {
if (isDefined(ret.deprecated)) {
ret.deprecated = parseBoolean(ret.deprecated);
} else {
ret.deprecated = false;
}

if (ret.deprecated === true && isDefined(ret.deprecated_by)) {
ret.deprecatedBy = ret.deprecated_by._cpe_id;
delete ret.deprecated_by;
} else if (isDefined(ret.raw_data?.['cpe-item']?._deprecated_by)) {
ret.deprecatedBy = ret.raw_data['cpe-item']._deprecated_by;
}
Expand Down
21 changes: 17 additions & 4 deletions src/web/pages/cpes/details.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,18 @@ import InfoTable from 'web/components/table/infotable';
import TableRow from 'web/components/table/row';
import {Col} from 'web/entity/page';
import PropTypes from 'web/utils/proptypes';
import {renderYesNo} from 'web/utils/render';

const CpeDetails = ({entity, links = true}) => {
const {title, nvdId, deprecatedBy, updateTime, status, severity} = entity;
const {
title,
cpeNameId,
deprecated,
deprecatedBy,
updateTime,
status,
severity,
} = entity;
return (
<Layout flex="column" grow="1">
{!isDefined(title) && (
Expand All @@ -42,12 +51,16 @@ const CpeDetails = ({entity, links = true}) => {
<TableData>{title}</TableData>
</TableRow>
)}
{isDefined(nvdId) && (
{isDefined(cpeNameId) && (
<TableRow>
<TableData>{_('NVD ID')}</TableData>
<TableData>{nvdId}</TableData>
<TableData>{_('CPE Name ID')}</TableData>
<TableData>{cpeNameId}</TableData>
</TableRow>
)}
<TableRow>
<TableData>{_('Deprecated')}</TableData>
<TableData>{renderYesNo(deprecated)}</TableData>
</TableRow>
{isDefined(deprecatedBy) && (
<TableRow>
<TableData>{_('Deprecated By')}</TableData>
Expand Down

0 comments on commit 4c215ad

Please sign in to comment.