diff --git a/src/gmp/collection/parser.ts b/src/gmp/collection/parser.ts index fa24750745..d3c925cc90 100644 --- a/src/gmp/collection/parser.ts +++ b/src/gmp/collection/parser.ts @@ -22,13 +22,15 @@ export interface CollectionList { counts: CollectionCounts; } +export type EntitiesParseFunc = ( + element: TElement, + name: string, + modelClass: ModelClass, +) => TModel[]; + interface ParseCollectionListOptions { pluralName?: string; - entitiesParseFunc?: ( - element: TElement, - name: string, - modelClass: ModelClass, - ) => TModel[]; + entitiesParseFunc?: EntitiesParseFunc; collectionCountParseFunc?: ( element: TElement, name: string, @@ -37,7 +39,7 @@ interface ParseCollectionListOptions { filterParseFunc?: (element: FilterElement) => Filter; } -interface InfoElement { +export interface InfoElement { info?: Element[]; } @@ -68,13 +70,19 @@ interface InfoWithCounts extends InfoElement { info_count?: ElementCounts; } +export type InfoEntitiesFilterFunc = ( + value: Element, + index: number, + array: Element[], +) => boolean; + const log = logger.getLogger('gmp.collection.parser'); export function parseInfoEntities( response: InfoElement, _name: string, modelClass: ModelClass, - filterFunc: (value: Element, index: number, array: Element[]) => boolean, + filterFunc: InfoEntitiesFilterFunc, ) { if (!isArray(response.info)) { return []; diff --git a/src/gmp/commands/__tests__/cert-bund-advisories.test.ts b/src/gmp/commands/__tests__/cert-bund-advisories.test.ts new file mode 100644 index 0000000000..24cb32f205 --- /dev/null +++ b/src/gmp/commands/__tests__/cert-bund-advisories.test.ts @@ -0,0 +1,159 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import CertBundAdvisoriesCommand from 'gmp/commands/cert-bund-advisories'; +import { + createAggregatesResponse, + createHttp, + createInfoEntitiesResponse, +} from 'gmp/commands/testing'; +import CertBundAdv from 'gmp/models/cert-bund'; + +describe('CertBundAdvisoriesCommand tests', () => { + test('should fetch cert bund advisories with default params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cert_bund_adv: { + severity: 10.0, + }, + }, + { + _id: '2', + name: 'User', + cert_bund_adv: { + severity: 5.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CertBundAdvisoriesCommand(fakeHttp); + const result = await cmd.get(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'cert_bund_adv'}, + }); + expect(result.data).toEqual([ + new CertBundAdv({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + new CertBundAdv({ + id: '2', + name: 'User', + severity: 5.0, + }), + ]); + }); + + test('should fetch cert bund advisories with custom params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cert_bund_adv: { + severity: 10.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CertBundAdvisoriesCommand(fakeHttp); + const result = await cmd.get({filter: "name='Admin'"}); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'cert_bund_adv', + filter: "name='Admin'", + }, + }); + expect(result.data).toEqual([ + new CertBundAdv({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + ]); + }); + + test('should fetch all cert bund advisories', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cert_bund_adv: { + severity: 10.0, + }, + }, + { + _id: '2', + name: 'User', + cert_bund_adv: { + severity: 5.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CertBundAdvisoriesCommand(fakeHttp); + const result = await cmd.getAll(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'cert_bund_adv', + filter: 'first=1 rows=-1', + }, + }); + expect(result.data).toEqual([ + new CertBundAdv({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + new CertBundAdv({ + id: '2', + name: 'User', + severity: 5.0, + }), + ]); + }); + + test('should fetch severity aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new CertBundAdvisoriesCommand(fakeHttp); + const result = await cmd.getSeverityAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'cert_bund_adv', + group_column: 'severity', + info_type: 'cert_bund_adv', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch created aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new CertBundAdvisoriesCommand(fakeHttp); + const result = await cmd.getCreatedAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'cert_bund_adv', + group_column: 'created', + info_type: 'cert_bund_adv', + }, + }); + expect(result.data).toEqual({groups: []}); + }); +}); diff --git a/src/gmp/commands/__tests__/cert-bund-advisory.test.ts b/src/gmp/commands/__tests__/cert-bund-advisory.test.ts new file mode 100644 index 0000000000..f780d70dea --- /dev/null +++ b/src/gmp/commands/__tests__/cert-bund-advisory.test.ts @@ -0,0 +1,69 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import CertBundAdvisoryCommand from 'gmp/commands/cert-bund-advisory'; +import { + createActionResultResponse, + createHttp, + createInfoResponse, +} from 'gmp/commands/testing'; + +describe('CertBundAdvisoryCommand tests', () => { + test('should get a cert bund advisory', async () => { + const response = createInfoResponse({ + id: '123', + name: 'Test advisory', + comment: 'A test advisory', + }); + const fakeHttp = createHttp(response); + const cmd = new CertBundAdvisoryCommand(fakeHttp); + const result = await cmd.get({ + id: '123', + }); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + details: '1', + info_type: 'cert_bund_adv', + info_id: '123', + }, + }); + expect(result.data.id).toEqual('123'); + }); + + test('should allow to clone a cert bund advisory', async () => { + const response = createActionResultResponse({id: '456'}); + const fakeHttp = createHttp(response); + const cmd = new CertBundAdvisoryCommand(fakeHttp); + const result = await cmd.clone({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'clone', + details: '1', + info_type: 'cert_bund_adv', + id: '123', + resource_type: 'info', + }, + }); + expect(result.data.id).toEqual('456'); + }); + + test('should allow to delete a cert bund advisory', async () => { + const response = createActionResultResponse({id: '123'}); + const fakeHttp = createHttp(response); + const cmd = new CertBundAdvisoryCommand(fakeHttp); + const result = await cmd.delete({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'delete_info', + details: '1', + info_type: 'cert_bund_adv', + info_id: '123', + }, + }); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/gmp/commands/__tests__/cpe.test.ts b/src/gmp/commands/__tests__/cpe.test.ts new file mode 100644 index 0000000000..0fc4b21265 --- /dev/null +++ b/src/gmp/commands/__tests__/cpe.test.ts @@ -0,0 +1,70 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import CpeCommand from 'gmp/commands/cpe'; +import { + createActionResultResponse, + createHttp, + createInfoResponse, +} from 'gmp/commands/testing'; + +describe('CpeCommand tests', () => { + test('should get a cpe', async () => { + const response = createInfoResponse({ + id: '123', + name: 'Test cpe', + cpe: 'cpe:/a:test:test:1.0', + comment: 'A test cpe', + }); + const fakeHttp = createHttp(response); + const cmd = new CpeCommand(fakeHttp); + const result = await cmd.get({ + id: '123', + }); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + details: '1', + info_type: 'cpe', + info_id: '123', + }, + }); + expect(result.data.id).toEqual('123'); + }); + + test('should allow to clone a cpe', async () => { + const response = createActionResultResponse({id: '456'}); + const fakeHttp = createHttp(response); + const cmd = new CpeCommand(fakeHttp); + const result = await cmd.clone({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'clone', + details: '1', + info_type: 'cpe', + id: '123', + resource_type: 'info', + }, + }); + expect(result.data.id).toEqual('456'); + }); + + test('should allow to delete a cpe', async () => { + const response = createActionResultResponse({id: '123'}); + const fakeHttp = createHttp(response); + const cmd = new CpeCommand(fakeHttp); + const result = await cmd.delete({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'delete_info', + details: '1', + info_type: 'cpe', + info_id: '123', + }, + }); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/gmp/commands/__tests__/cpes.test.ts b/src/gmp/commands/__tests__/cpes.test.ts new file mode 100644 index 0000000000..9677391ca3 --- /dev/null +++ b/src/gmp/commands/__tests__/cpes.test.ts @@ -0,0 +1,151 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import CpesCommand from 'gmp/commands/cpes'; +import { + createAggregatesResponse, + createHttp, + createInfoEntitiesResponse, +} from 'gmp/commands/testing'; +import Cpe from 'gmp/models/cpe'; + +describe('CpesCommand tests', () => { + test('should fetch cpes with default params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cpe: { + cpe_name_id: 'cpe:/a:admin:admin:1.0', + }, + }, + { + _id: '2', + name: 'User', + cpe: { + cpe_name_id: 'cpe:/a:user:user:1.0', + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CpesCommand(fakeHttp); + const result = await cmd.get(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'cpe'}, + }); + expect(result.data).toEqual([ + new Cpe({ + id: '1', + name: 'Admin', + cpeNameId: 'cpe:/a:admin:admin:1.0', + }), + new Cpe({ + id: '2', + name: 'User', + cpeNameId: 'cpe:/a:user:user:1.0', + }), + ]); + }); + + test('should fetch cpes with custom params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cpe: { + cpe_name_id: 'cpe:/a:admin:admin:1.0', + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CpesCommand(fakeHttp); + const result = await cmd.get({filter: "name='Admin'"}); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'cpe', + filter: "name='Admin'", + }, + }); + expect(result.data).toEqual([ + new Cpe({id: '1', name: 'Admin', cpeNameId: 'cpe:/a:admin:admin:1.0'}), + ]); + }); + + test('should fetch all cpes', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cpe: { + cpe_name_id: 'cpe:/a:admin:admin:1.0', + }, + }, + { + _id: '2', + name: 'User', + cpe: { + cpe_name_id: 'cpe:/a:user:user:1.0', + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CpesCommand(fakeHttp); + const result = await cmd.getAll(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'cpe', filter: 'first=1 rows=-1'}, + }); + expect(result.data).toEqual([ + new Cpe({ + id: '1', + name: 'Admin', + cpeNameId: 'cpe:/a:admin:admin:1.0', + }), + new Cpe({ + id: '2', + name: 'User', + cpeNameId: 'cpe:/a:user:user:1.0', + }), + ]); + }); + + test('should fetch severity aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new CpesCommand(fakeHttp); + const result = await cmd.getSeverityAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'cpe', + group_column: 'severity', + info_type: 'cpe', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch created aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new CpesCommand(fakeHttp); + const result = await cmd.getCreatedAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'cpe', + group_column: 'created', + info_type: 'cpe', + }, + }); + expect(result.data).toEqual({groups: []}); + }); +}); diff --git a/src/gmp/commands/__tests__/cve.test.ts b/src/gmp/commands/__tests__/cve.test.ts new file mode 100644 index 0000000000..ff9f094dda --- /dev/null +++ b/src/gmp/commands/__tests__/cve.test.ts @@ -0,0 +1,69 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import CveCommand from 'gmp/commands/cve'; +import { + createActionResultResponse, + createHttp, + createInfoResponse, +} from 'gmp/commands/testing'; + +describe('CveCommand tests', () => { + test('should get a cve', async () => { + const response = createInfoResponse({ + id: '123', + name: 'Test cve', + comment: 'A test cve', + }); + const fakeHttp = createHttp(response); + const cmd = new CveCommand(fakeHttp); + const result = await cmd.get({ + id: '123', + }); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + details: '1', + info_type: 'cve', + info_id: '123', + }, + }); + expect(result.data.id).toEqual('123'); + }); + + test('should allow to clone a cve', async () => { + const response = createActionResultResponse({id: '456'}); + const fakeHttp = createHttp(response); + const cmd = new CveCommand(fakeHttp); + const result = await cmd.clone({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'clone', + details: '1', + info_type: 'cve', + id: '123', + resource_type: 'info', + }, + }); + expect(result.data.id).toEqual('456'); + }); + + test('should allow to delete a cve', async () => { + const response = createActionResultResponse({id: '123'}); + const fakeHttp = createHttp(response); + const cmd = new CveCommand(fakeHttp); + const result = await cmd.delete({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'delete_info', + details: '1', + info_type: 'cve', + info_id: '123', + }, + }); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/gmp/commands/__tests__/cves.test.ts b/src/gmp/commands/__tests__/cves.test.ts new file mode 100644 index 0000000000..b2ba0a98e5 --- /dev/null +++ b/src/gmp/commands/__tests__/cves.test.ts @@ -0,0 +1,151 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import CvesCommand from 'gmp/commands/cves'; +import { + createAggregatesResponse, + createHttp, + createInfoEntitiesResponse, +} from 'gmp/commands/testing'; +import Cve from 'gmp/models/cve'; + +describe('CvesCommand tests', () => { + test('should fetch cves with default params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cve: { + severity: 10.0, + }, + }, + { + _id: '2', + name: 'User', + cve: { + severity: 5.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CvesCommand(fakeHttp); + const result = await cmd.get(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'cve'}, + }); + expect(result.data).toEqual([ + new Cve({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + new Cve({ + id: '2', + name: 'User', + severity: 5.0, + }), + ]); + }); + + test('should fetch cves with custom params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cve: { + severity: 10.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CvesCommand(fakeHttp); + const result = await cmd.get({filter: "name='Admin'"}); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'cve', + filter: "name='Admin'", + }, + }); + expect(result.data).toEqual([ + new Cve({id: '1', name: 'Admin', severity: 10.0}), + ]); + }); + + test('should fetch all cves', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + cve: { + severity: 10.0, + }, + }, + { + _id: '2', + name: 'User', + cve: { + severity: 5.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new CvesCommand(fakeHttp); + const result = await cmd.getAll(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'cve', filter: 'first=1 rows=-1'}, + }); + expect(result.data).toEqual([ + new Cve({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + new Cve({ + id: '2', + name: 'User', + severity: 5.0, + }), + ]); + }); + + test('should fetch severity aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new CvesCommand(fakeHttp); + const result = await cmd.getSeverityAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'cve', + group_column: 'severity', + info_type: 'cve', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch created aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new CvesCommand(fakeHttp); + const result = await cmd.getCreatedAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'cve', + group_column: 'created', + info_type: 'cve', + }, + }); + expect(result.data).toEqual({groups: []}); + }); +}); diff --git a/src/gmp/commands/__tests__/dfn-cert-advisories.test.ts b/src/gmp/commands/__tests__/dfn-cert-advisories.test.ts new file mode 100644 index 0000000000..75493b4025 --- /dev/null +++ b/src/gmp/commands/__tests__/dfn-cert-advisories.test.ts @@ -0,0 +1,159 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import DfnCertAdvisoriesCommand from 'gmp/commands/dfn-cert-advisories'; +import { + createAggregatesResponse, + createHttp, + createInfoEntitiesResponse, +} from 'gmp/commands/testing'; +import DfnCertAdv from 'gmp/models/dfn-cert'; + +describe('DfnCertAdvisoriesCommand tests', () => { + test('should fetch dfn cert advisories with default params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + dfn_cert_adv: { + severity: 10.0, + }, + }, + { + _id: '2', + name: 'User', + dfn_cert_adv: { + severity: 5.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new DfnCertAdvisoriesCommand(fakeHttp); + const result = await cmd.get(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'dfn_cert_adv'}, + }); + expect(result.data).toEqual([ + new DfnCertAdv({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + new DfnCertAdv({ + id: '2', + name: 'User', + severity: 5.0, + }), + ]); + }); + + test('should fetch dfn cert advisories with custom params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + dfn_cert_adv: { + severity: 10.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new DfnCertAdvisoriesCommand(fakeHttp); + const result = await cmd.get({filter: "name='Admin'"}); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'dfn_cert_adv', + filter: "name='Admin'", + }, + }); + expect(result.data).toEqual([ + new DfnCertAdv({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + ]); + }); + + test('should fetch all dfn cert advisories', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + dfn_cert_adv: { + severity: 10.0, + }, + }, + { + _id: '2', + name: 'User', + dfn_cert_adv: { + severity: 5.0, + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new DfnCertAdvisoriesCommand(fakeHttp); + const result = await cmd.getAll(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'dfn_cert_adv', + filter: 'first=1 rows=-1', + }, + }); + expect(result.data).toEqual([ + new DfnCertAdv({ + id: '1', + name: 'Admin', + severity: 10.0, + }), + new DfnCertAdv({ + id: '2', + name: 'User', + severity: 5.0, + }), + ]); + }); + + test('should fetch severity aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new DfnCertAdvisoriesCommand(fakeHttp); + const result = await cmd.getSeverityAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'dfn_cert_adv', + group_column: 'severity', + info_type: 'dfn_cert_adv', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch created aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new DfnCertAdvisoriesCommand(fakeHttp); + const result = await cmd.getCreatedAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'dfn_cert_adv', + group_column: 'created', + info_type: 'dfn_cert_adv', + }, + }); + expect(result.data).toEqual({groups: []}); + }); +}); diff --git a/src/gmp/commands/__tests__/dfn-cert-advisory.test.ts b/src/gmp/commands/__tests__/dfn-cert-advisory.test.ts new file mode 100644 index 0000000000..369e73b625 --- /dev/null +++ b/src/gmp/commands/__tests__/dfn-cert-advisory.test.ts @@ -0,0 +1,69 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import DfnCertAdvisoryCommand from 'gmp/commands/dfn-cert-advisory'; +import { + createActionResultResponse, + createHttp, + createInfoResponse, +} from 'gmp/commands/testing'; + +describe('DfnCertAdvisoryCommand tests', () => { + test('should get a dfn cert advisory', async () => { + const response = createInfoResponse({ + id: '123', + name: 'Test advisory', + comment: 'A test advisory', + }); + const fakeHttp = createHttp(response); + const cmd = new DfnCertAdvisoryCommand(fakeHttp); + const result = await cmd.get({ + id: '123', + }); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + details: '1', + info_type: 'dfn_cert_adv', + info_id: '123', + }, + }); + expect(result.data.id).toEqual('123'); + }); + + test('should allow to clone a dfn cert advisory', async () => { + const response = createActionResultResponse({id: '456'}); + const fakeHttp = createHttp(response); + const cmd = new DfnCertAdvisoryCommand(fakeHttp); + const result = await cmd.clone({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'clone', + details: '1', + info_type: 'dfn_cert_adv', + id: '123', + resource_type: 'info', + }, + }); + expect(result.data.id).toEqual('456'); + }); + + test('should allow to delete a dfn cert advisory', async () => { + const response = createActionResultResponse({id: '123'}); + const fakeHttp = createHttp(response); + const cmd = new DfnCertAdvisoryCommand(fakeHttp); + const result = await cmd.delete({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'delete_info', + details: '1', + info_type: 'dfn_cert_adv', + info_id: '123', + }, + }); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/gmp/commands/__tests__/nvt.test.js b/src/gmp/commands/__tests__/nvt.test.ts similarity index 57% rename from src/gmp/commands/__tests__/nvt.test.js rename to src/gmp/commands/__tests__/nvt.test.ts index d4877ea1ee..41b1d89b25 100644 --- a/src/gmp/commands/__tests__/nvt.test.js +++ b/src/gmp/commands/__tests__/nvt.test.ts @@ -4,8 +4,12 @@ */ import {describe, test, expect} from '@gsa/testing'; -import {NvtCommand} from 'gmp/commands/nvt'; -import {createResponse, createHttp} from 'gmp/commands/testing'; +import NvtCommand from 'gmp/commands/nvt'; +import { + createResponse, + createHttp, + createActionResultResponse, +} from 'gmp/commands/testing'; describe('NvtCommand tests', () => { test('should request single nvt', async () => { @@ -60,4 +64,37 @@ describe('NvtCommand tests', () => { const {data: nvt} = resp; expect(nvt.id).toEqual('1.2.3'); }); + + test('should allow to clone a nvt', async () => { + const response = createActionResultResponse({id: '456'}); + const fakeHttp = createHttp(response); + const cmd = new NvtCommand(fakeHttp); + const result = await cmd.clone({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'clone', + details: '1', + info_type: 'nvt', + id: '123', + resource_type: 'info', + }, + }); + expect(result.data.id).toEqual('456'); + }); + + test('should allow to delete a nvt', async () => { + const response = createActionResultResponse({id: '123'}); + const fakeHttp = createHttp(response); + const cmd = new NvtCommand(fakeHttp); + const result = await cmd.delete({id: '123'}); + expect(fakeHttp.request).toHaveBeenCalledWith('post', { + data: { + cmd: 'delete_info', + details: '1', + info_type: 'nvt', + info_id: '123', + }, + }); + expect(result).toBeUndefined(); + }); }); diff --git a/src/gmp/commands/__tests__/nvts.test.ts b/src/gmp/commands/__tests__/nvts.test.ts new file mode 100644 index 0000000000..c65b08be15 --- /dev/null +++ b/src/gmp/commands/__tests__/nvts.test.ts @@ -0,0 +1,203 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {describe, test, expect} from '@gsa/testing'; +import NvtsCommand from 'gmp/commands/nvts'; +import { + createAggregatesResponse, + createHttp, + createInfoEntitiesResponse, +} from 'gmp/commands/testing'; +import Nvt from 'gmp/models/nvt'; + +describe('NvtsCommand tests', () => { + test('should fetch nvts with default params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + nvt: { + _oid: '1.2.3', + }, + }, + { + _id: '2', + name: 'User', + nvt: { + _oid: '2.3.4', + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.get(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'nvt'}, + }); + expect(result.data).toEqual([ + new Nvt({ + id: '1.2.3', + name: 'Admin', + oid: '1.2.3', + }), + new Nvt({ + id: '2.3.4', + name: 'User', + oid: '2.3.4', + }), + ]); + }); + + test('should fetch nvts with custom params', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + nvt: { + _oid: '1.2.3', + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.get({filter: "name='Admin'"}); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_info', + info_type: 'nvt', + filter: "name='Admin'", + }, + }); + expect(result.data).toEqual([ + new Nvt({id: '1.2.3', name: 'Admin', oid: '1.2.3'}), + ]); + }); + + test('should fetch all nvts', async () => { + const response = createInfoEntitiesResponse([ + { + _id: '1', + name: 'Admin', + nvt: { + _oid: '1.2.3', + }, + }, + { + _id: '2', + name: 'User', + nvt: { + _oid: '2.3.4', + }, + }, + ]); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.getAll(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: {cmd: 'get_info', info_type: 'nvt', filter: 'first=1 rows=-1'}, + }); + expect(result.data).toEqual([ + new Nvt({ + id: '1.2.3', + name: 'Admin', + oid: '1.2.3', + }), + new Nvt({ + id: '2.3.4', + name: 'User', + oid: '2.3.4', + }), + ]); + }); + + test('should fetch severity aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.getSeverityAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'nvt', + group_column: 'severity', + info_type: 'nvt', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch created aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.getCreatedAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'nvt', + group_column: 'created', + info_type: 'nvt', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch family aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.getFamilyAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'nvt', + group_column: 'family', + info_type: 'nvt', + 'data_columns:0': 'severity', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch qod aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.getQodAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'nvt', + group_column: 'qod', + info_type: 'nvt', + }, + }); + expect(result.data).toEqual({groups: []}); + }); + + test('should fetch qod type aggregates', async () => { + const response = createAggregatesResponse({}); + const fakeHttp = createHttp(response); + + const cmd = new NvtsCommand(fakeHttp); + const result = await cmd.getQodTypeAggregates(); + expect(fakeHttp.request).toHaveBeenCalledWith('get', { + args: { + cmd: 'get_aggregate', + aggregate_type: 'nvt', + group_column: 'qod_type', + info_type: 'nvt', + }, + }); + expect(result.data).toEqual({groups: []}); + }); +}); diff --git a/src/gmp/commands/cert-bund-advisories.ts b/src/gmp/commands/cert-bund-advisories.ts new file mode 100644 index 0000000000..9a721428e0 --- /dev/null +++ b/src/gmp/commands/cert-bund-advisories.ts @@ -0,0 +1,37 @@ +/* SPDX-FileCopyrightText: 2026 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntitiesCommand from 'gmp/commands/info-entities'; +import type Http from 'gmp/http/http'; +import CertBundAdv from 'gmp/models/cert-bund'; +import type Filter from 'gmp/models/filter'; +import {type Element} from 'gmp/models/model'; +import {isDefined} from 'gmp/utils/identity'; + +const infoFilter = (info: Element) => isDefined(info.cert_bund_adv); + +class CertBundAdvisoriesCommand extends InfoEntitiesCommand { + constructor(http: Http) { + super(http, 'cert_bund_adv', CertBundAdv, infoFilter); + } + + getCreatedAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'cert_bund_adv', + group_column: 'created', + filter, + }); + } + + getSeverityAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'cert_bund_adv', + group_column: 'severity', + filter, + }); + } +} + +export default CertBundAdvisoriesCommand; diff --git a/src/gmp/commands/cert-bund-advisory.ts b/src/gmp/commands/cert-bund-advisory.ts new file mode 100644 index 0000000000..721f6cb6f8 --- /dev/null +++ b/src/gmp/commands/cert-bund-advisory.ts @@ -0,0 +1,16 @@ +/* SPDX-FileCopyrightText: 2026 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntityCommand from 'gmp/commands/info-entity'; +import type Http from 'gmp/http/http'; +import CertBundAdv from 'gmp/models/cert-bund'; + +class CertBundAdvisoryCommand extends InfoEntityCommand { + constructor(http: Http) { + super(http, 'cert_bund_adv', CertBundAdv); + } +} + +export default CertBundAdvisoryCommand; diff --git a/src/gmp/commands/cert-bund.js b/src/gmp/commands/cert-bund.js deleted file mode 100644 index c06675546c..0000000000 --- a/src/gmp/commands/cert-bund.js +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import registerCommand from 'gmp/command'; -import InfoEntitiesCommand from 'gmp/commands/info-entities'; -import InfoEntityCommand from 'gmp/commands/info-entity'; -import CertBundAdv from 'gmp/models/cert-bund'; -import {isDefined} from 'gmp/utils/identity'; - -const info_filter = info => isDefined(info.cert_bund_adv); - -class CertBundCommand extends InfoEntityCommand { - constructor(http) { - super(http, 'cert_bund_adv', CertBundAdv); - } -} - -class CertBundsCommand extends InfoEntitiesCommand { - constructor(http) { - super(http, 'cert_bund_adv', CertBundAdv, info_filter); - } - - getCreatedAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'cert_bund_adv', - group_column: 'created', - filter, - }); - } - - getSeverityAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'cert_bund_adv', - group_column: 'severity', - filter, - }); - } -} - -registerCommand('certbund', CertBundCommand); -registerCommand('certbunds', CertBundsCommand); diff --git a/src/gmp/commands/cpe.ts b/src/gmp/commands/cpe.ts new file mode 100644 index 0000000000..a76a9b9bec --- /dev/null +++ b/src/gmp/commands/cpe.ts @@ -0,0 +1,16 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntityCommand from 'gmp/commands/info-entity'; +import type Http from 'gmp/http/http'; +import Cpe from 'gmp/models/cpe'; + +class CpeCommand extends InfoEntityCommand { + constructor(http: Http) { + super(http, 'cpe', Cpe); + } +} + +export default CpeCommand; diff --git a/src/gmp/commands/cpes.js b/src/gmp/commands/cpes.js deleted file mode 100644 index b8734084a1..0000000000 --- a/src/gmp/commands/cpes.js +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import registerCommand from 'gmp/command'; -import InfoEntitiesCommand from 'gmp/commands/info-entities'; -import InfoEntityCommand from 'gmp/commands/info-entity'; -import Cpe from 'gmp/models/cpe'; -import {isDefined} from 'gmp/utils/identity'; - -const info_filter = info => isDefined(info.cpe); - -class CpeCommand extends InfoEntityCommand { - constructor(http) { - super(http, 'cpe', Cpe); - } -} - -class CpesCommand extends InfoEntitiesCommand { - constructor(http) { - super(http, 'cpe', Cpe, info_filter); - } - - getCreatedAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'cpe', - group_column: 'created', - filter, - }); - } - - getSeverityAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'cpe', - group_column: 'severity', - filter, - }); - } -} - -registerCommand('cpe', CpeCommand); -registerCommand('cpes', CpesCommand); diff --git a/src/gmp/commands/cpes.ts b/src/gmp/commands/cpes.ts new file mode 100644 index 0000000000..6a2423aa61 --- /dev/null +++ b/src/gmp/commands/cpes.ts @@ -0,0 +1,37 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntitiesCommand from 'gmp/commands/info-entities'; +import type Http from 'gmp/http/http'; +import Cpe from 'gmp/models/cpe'; +import type Filter from 'gmp/models/filter'; +import {type Element} from 'gmp/models/model'; +import {isDefined} from 'gmp/utils/identity'; + +const infoFilter = (info: Element) => isDefined(info.cpe); + +class CpesCommand extends InfoEntitiesCommand { + constructor(http: Http) { + super(http, 'cpe', Cpe, infoFilter); + } + + getCreatedAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'cpe', + group_column: 'created', + filter, + }); + } + + getSeverityAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'cpe', + group_column: 'severity', + filter, + }); + } +} + +export default CpesCommand; diff --git a/src/gmp/commands/cve.ts b/src/gmp/commands/cve.ts new file mode 100644 index 0000000000..e972f41203 --- /dev/null +++ b/src/gmp/commands/cve.ts @@ -0,0 +1,16 @@ +/* SPDX-FileCopyrightText: 2025 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntityCommand from 'gmp/commands/info-entity'; +import type Http from 'gmp/http/http'; +import CVE from 'gmp/models/cve'; + +class CveCommand extends InfoEntityCommand { + constructor(http: Http) { + super(http, 'cve', CVE); + } +} + +export default CveCommand; diff --git a/src/gmp/commands/cves.js b/src/gmp/commands/cves.js deleted file mode 100644 index 3a1856ba67..0000000000 --- a/src/gmp/commands/cves.js +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import registerCommand from 'gmp/command'; -import InfoEntitiesCommand from 'gmp/commands/info-entities'; -import InfoEntityCommand from 'gmp/commands/info-entity'; -import Cve from 'gmp/models/cve'; -import {isDefined} from 'gmp/utils/identity'; - -const info_filter = info => isDefined(info.cve); - -class CveCommand extends InfoEntityCommand { - constructor(http) { - super(http, 'cve', Cve); - } -} - -class CvesCommand extends InfoEntitiesCommand { - constructor(http) { - super(http, 'cve', Cve, info_filter); - } - - getCreatedAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'cve', - group_column: 'created', - filter, - }); - } - - getSeverityAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'cve', - group_column: 'severity', - filter, - }); - } -} - -registerCommand('cve', CveCommand); -registerCommand('cves', CvesCommand); diff --git a/src/gmp/commands/cves.ts b/src/gmp/commands/cves.ts new file mode 100644 index 0000000000..f20fbf19c5 --- /dev/null +++ b/src/gmp/commands/cves.ts @@ -0,0 +1,37 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntitiesCommand from 'gmp/commands/info-entities'; +import type Http from 'gmp/http/http'; +import Cve from 'gmp/models/cve'; +import type Filter from 'gmp/models/filter'; +import {type Element} from 'gmp/models/model'; +import {isDefined} from 'gmp/utils/identity'; + +const infoFilter = (info: Element) => isDefined(info.cve); + +class CvesCommand extends InfoEntitiesCommand { + constructor(http: Http) { + super(http, 'cve', Cve, infoFilter); + } + + getCreatedAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'cve', + group_column: 'created', + filter, + }); + } + + getSeverityAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'cve', + group_column: 'severity', + filter, + }); + } +} + +export default CvesCommand; diff --git a/src/gmp/commands/dfn-cert-advisories.ts b/src/gmp/commands/dfn-cert-advisories.ts new file mode 100644 index 0000000000..a13af88e40 --- /dev/null +++ b/src/gmp/commands/dfn-cert-advisories.ts @@ -0,0 +1,37 @@ +/* SPDX-FileCopyrightText: 2026 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntitiesCommand from 'gmp/commands/info-entities'; +import type Http from 'gmp/http/http'; +import DfnCertAdv from 'gmp/models/dfn-cert'; +import type Filter from 'gmp/models/filter'; +import {type Element} from 'gmp/models/model'; +import {isDefined} from 'gmp/utils/identity'; + +const infoFilter = (info: Element) => isDefined(info.dfn_cert_adv); + +class DfnCertAdvisoriesCommand extends InfoEntitiesCommand { + constructor(http: Http) { + super(http, 'dfn_cert_adv', DfnCertAdv, infoFilter); + } + + getCreatedAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'dfn_cert_adv', + group_column: 'created', + filter, + }); + } + + getSeverityAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'dfn_cert_adv', + group_column: 'severity', + filter, + }); + } +} + +export default DfnCertAdvisoriesCommand; diff --git a/src/gmp/commands/dfn-cert-advisory.ts b/src/gmp/commands/dfn-cert-advisory.ts new file mode 100644 index 0000000000..b7ac1c6e87 --- /dev/null +++ b/src/gmp/commands/dfn-cert-advisory.ts @@ -0,0 +1,16 @@ +/* SPDX-FileCopyrightText: 2026 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntityCommand from 'gmp/commands/info-entity'; +import type Http from 'gmp/http/http'; +import DfnCertAdv from 'gmp/models/dfn-cert'; + +class DfnCertAdvisoryCommand extends InfoEntityCommand { + constructor(http: Http) { + super(http, 'dfn_cert_adv', DfnCertAdv); + } +} + +export default DfnCertAdvisoryCommand; diff --git a/src/gmp/commands/dfn-cert.js b/src/gmp/commands/dfn-cert.js deleted file mode 100644 index 47007c8cd0..0000000000 --- a/src/gmp/commands/dfn-cert.js +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import registerCommand from 'gmp/command'; -import InfoEntitiesCommand from 'gmp/commands/info-entities'; -import InfoEntityCommand from 'gmp/commands/info-entity'; -import DfnCertAdv from 'gmp/models/dfn-cert'; -import {isDefined} from 'gmp/utils/identity'; - -const info_filter = info => isDefined(info.dfn_cert_adv); - -class DfnCertAdvCommand extends InfoEntityCommand { - constructor(http) { - super(http, 'dfn_cert_adv', DfnCertAdv); - } -} - -class DfnCertAdvsCommand extends InfoEntitiesCommand { - constructor(http) { - super(http, 'dfn_cert_adv', DfnCertAdv, info_filter); - } - - getCreatedAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'dfn_cert_adv', - group_column: 'created', - filter, - }); - } - - getSeverityAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'dfn_cert_adv', - group_column: 'severity', - filter, - }); - } -} - -registerCommand('dfncert', DfnCertAdvCommand); -registerCommand('dfncerts', DfnCertAdvsCommand); diff --git a/src/gmp/commands/entities.ts b/src/gmp/commands/entities.ts index 4e423f3da4..69c373d9bd 100644 --- a/src/gmp/commands/entities.ts +++ b/src/gmp/commands/entities.ts @@ -110,10 +110,10 @@ abstract class EntitiesCommand< TEntitiesResponse extends Element = Element, TRoot extends Element = Element, > extends HttpCommand { - private readonly clazz: ModelClass; + protected readonly clazz: ModelClass; readonly name: string; - constructor(http: Http, name: string, clazz: ModelClass) { + constructor(http: Http, name: string, clazz: ModelClass) { super(http, {cmd: 'get_' + name + 's'}); this.clazz = clazz; diff --git a/src/gmp/commands/info-entities.js b/src/gmp/commands/info-entities.js deleted file mode 100644 index 6d37e6eaea..0000000000 --- a/src/gmp/commands/info-entities.js +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import { - parseCollectionList, - parseInfoEntities, - parseInfoCounts, -} from 'gmp/collection/parser'; -import EntitiesCommand from 'gmp/commands/entities'; - -class InfoEntitiesCommand extends EntitiesCommand { - constructor(http, name, clazz, entities_filter_func) { - super(http, 'info', clazz); - this.setDefaultParam('cmd', 'get_info'); - this.setDefaultParam('info_type', name); - this.entities_filter_func = entities_filter_func; - - this.parseInfoEntities = this.parseInfoEntities.bind(this); - } - - getEntitiesResponse(root) { - return root.get_info.get_info_response; - } - - parseInfoEntities(response, name, modelclass) { - return parseInfoEntities( - response, - name, - modelclass, - this.entities_filter_func, - ); - } - - getCollectionListFromRoot(root, meta) { - const response = this.getEntitiesResponse(root); - return parseCollectionList(response, this.name, this.clazz, { - meta, - entitiesParseFunc: this.parseInfoEntities, - collectionCountParseFunc: parseInfoCounts, - }); - } -} - -export default InfoEntitiesCommand; diff --git a/src/gmp/commands/info-entities.ts b/src/gmp/commands/info-entities.ts new file mode 100644 index 0000000000..7c0139698c --- /dev/null +++ b/src/gmp/commands/info-entities.ts @@ -0,0 +1,64 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { + parseCollectionList, + parseInfoEntities, + parseInfoCounts, + type ModelClass, + type InfoEntitiesFilterFunc, + type InfoElement, +} from 'gmp/collection/parser'; +import EntitiesCommand from 'gmp/commands/entities'; +import {type InfoType} from 'gmp/commands/info-entity'; +import type Http from 'gmp/http/http'; +import {type default as Model, type Element} from 'gmp/models/model'; + +class InfoEntitiesCommand< + TModel extends Model, +> extends EntitiesCommand { + private readonly entitiesFilterFunc: InfoEntitiesFilterFunc; + + constructor( + http: Http, + infoType: InfoType, + model: ModelClass, + entitiesFilterFunc: InfoEntitiesFilterFunc, + ) { + super(http, 'info', model); + this.setDefaultParam('cmd', 'get_info'); + this.setDefaultParam('info_type', infoType); + this.entitiesFilterFunc = entitiesFilterFunc; + + this.parseInfoEntities = this.parseInfoEntities.bind(this); + } + + getEntitiesResponse(root) { + return root.get_info.get_info_response; + } + + parseInfoEntities( + response: InfoElement, + name: string, + modelClass: ModelClass, + ) { + return parseInfoEntities( + response, + name, + modelClass, + this.entitiesFilterFunc, + ); + } + + getCollectionListFromRoot(root: Element) { + const response = this.getEntitiesResponse(root); + return parseCollectionList(response, this.name, this.clazz, { + entitiesParseFunc: this.parseInfoEntities, + collectionCountParseFunc: parseInfoCounts, + }); + } +} + +export default InfoEntitiesCommand; diff --git a/src/gmp/commands/info-entity.js b/src/gmp/commands/info-entity.js deleted file mode 100644 index fe4c748dfd..0000000000 --- a/src/gmp/commands/info-entity.js +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import EntityCommand from 'gmp/commands/entity'; - -class InfoEntityCommand extends EntityCommand { - constructor(http, info_type, model) { - super(http, 'info', model); - this.setDefaultParam('info_type', info_type); - this.setDefaultParam('details', '1'); - } - - getElementFromRoot(root) { - /* return the first info element from the response - * the second info element is for the counts */ - return root.get_info.get_info_response.info[0]; - } -} - -export default InfoEntityCommand; diff --git a/src/gmp/commands/info-entity.ts b/src/gmp/commands/info-entity.ts new file mode 100644 index 0000000000..52353d5f85 --- /dev/null +++ b/src/gmp/commands/info-entity.ts @@ -0,0 +1,29 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {type ModelClass} from 'gmp/collection/parser'; +import EntityCommand from 'gmp/commands/entity'; +import type Http from 'gmp/http/http'; +import {type XmlResponseData} from 'gmp/http/transform/fast-xml'; +import type Model from 'gmp/models/model'; + +export type InfoType = 'nvt' | 'cve' | 'cpe' | 'dfn_cert_adv' | 'cert_bund_adv'; + +class InfoEntityCommand extends EntityCommand { + constructor(http: Http, infoType: InfoType, model: ModelClass) { + super(http, 'info', model); + this.setDefaultParam('info_type', infoType); + this.setDefaultParam('details', '1'); + } + + getElementFromRoot(root: XmlResponseData): XmlResponseData { + /* return the first info element from the response + * the second info element is for the counts */ + // @ts-expect-error + return root.get_info.get_info_response.info[0]; + } +} + +export default InfoEntityCommand; diff --git a/src/gmp/commands/nvt.js b/src/gmp/commands/nvt.js deleted file mode 100644 index a6ecbd9d7b..0000000000 --- a/src/gmp/commands/nvt.js +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Greenbone AG - * - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import registerCommand from 'gmp/command'; -import InfoEntitiesCommand from 'gmp/commands/info-entities'; -import InfoEntityCommand from 'gmp/commands/info-entity'; -import Nvt from 'gmp/models/nvt'; -import {isDefined} from 'gmp/utils/identity'; - -const info_filter = info => isDefined(info.nvt); - -export class NvtCommand extends InfoEntityCommand { - constructor(http) { - super(http, 'nvt', Nvt); - } - - getConfigNvt({oid, configId}) { - return this.httpGetWithTransform( - { - cmd: 'get_config_nvt', - config_id: configId, - oid, - }, - {includeDefaultParams: false}, - ).then(response => { - const {data} = response; - const config_resp = data.get_config_nvt_response; - - const nvt = Nvt.fromElement(config_resp.get_nvts_response); - - return response.setData(nvt); - }); - } -} - -class NvtsCommand extends InfoEntitiesCommand { - constructor(http) { - super(http, 'nvt', Nvt, info_filter); - } - - getFamilyAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'nvt', - group_column: 'family', - filter, - dataColumns: ['severity'], - }); - } - - getSeverityAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'nvt', - group_column: 'severity', - filter, - }); - } - - getQodAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'nvt', - group_column: 'qod', - filter, - }); - } - - getQodTypeAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'nvt', - group_column: 'qod_type', - filter, - }); - } - - getCreatedAggregates({filter} = {}) { - return this.getAggregates({ - aggregate_type: 'nvt', - group_column: 'created', - filter, - }); - } -} - -registerCommand('nvt', NvtCommand); -registerCommand('nvts', NvtsCommand); diff --git a/src/gmp/commands/nvt.ts b/src/gmp/commands/nvt.ts new file mode 100644 index 0000000000..9c306ac83c --- /dev/null +++ b/src/gmp/commands/nvt.ts @@ -0,0 +1,32 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntityCommand from 'gmp/commands/info-entity'; +import type Http from 'gmp/http/http'; +import Nvt from 'gmp/models/nvt'; + +class NvtCommand extends InfoEntityCommand { + constructor(http: Http) { + super(http, 'nvt', Nvt); + } + + async getConfigNvt({oid, configId}: {oid: string; configId: string}) { + const response = await this.httpGetWithTransform( + { + cmd: 'get_config_nvt', + config_id: configId, + oid, + }, + {includeDefaultParams: false}, + ); + const {data} = response; + const configResponse = data.get_config_nvt_response; + // @ts-expect-error + const nvt = Nvt.fromElement(configResponse.get_nvts_response); + return response.setData(nvt); + } +} + +export default NvtCommand; diff --git a/src/gmp/commands/nvts.ts b/src/gmp/commands/nvts.ts new file mode 100644 index 0000000000..ede81f3105 --- /dev/null +++ b/src/gmp/commands/nvts.ts @@ -0,0 +1,62 @@ +/* SPDX-FileCopyrightText: 2026 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import InfoEntitiesCommand from 'gmp/commands/info-entities'; +import type Http from 'gmp/http/http'; +import type Filter from 'gmp/models/filter'; +import {type Element} from 'gmp/models/model'; +import Nvt from 'gmp/models/nvt'; +import {isDefined} from 'gmp/utils/identity'; + +const infoFilter = (info: Element) => isDefined(info.nvt); + +class NvtsCommand extends InfoEntitiesCommand { + constructor(http: Http) { + super(http, 'nvt', Nvt, infoFilter); + } + + getFamilyAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'nvt', + group_column: 'family', + filter, + dataColumns: ['severity'], + }); + } + + getSeverityAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'nvt', + group_column: 'severity', + filter, + }); + } + + getQodAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'nvt', + group_column: 'qod', + filter, + }); + } + + getQodTypeAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'nvt', + group_column: 'qod_type', + filter, + }); + } + + getCreatedAggregates({filter}: {filter?: Filter} = {}) { + return this.getAggregates({ + aggregate_type: 'nvt', + group_column: 'created', + filter, + }); + } +} + +export default NvtsCommand; diff --git a/src/gmp/commands/testing.ts b/src/gmp/commands/testing.ts index 150a24e061..92c5d380be 100644 --- a/src/gmp/commands/testing.ts +++ b/src/gmp/commands/testing.ts @@ -34,13 +34,27 @@ export const createResponse = (data: TData = {} as TData) => envelope: data, }); -export const createEntitiesResponse = (name: string, entities: Element[]) => +export const createEntitiesResponse = ( + name: string, + entities: Element[], + { + getName = `get_${name}s`, + responseName = `get_${name}s_response`, + pluralName = `${name}s`, + countName = `${name}_count`, + }: { + getName?: string; + responseName?: string; + pluralName?: string; + countName?: string; + } = {}, +) => createResponse({ - [`get_${name}s`]: { - [`get_${name}s_response`]: { + [getName]: { + [responseName]: { [name]: entities, - [`${name}s`]: entitiesRange, - [`${name}_count`]: createEntitiesCounts(entities), + [pluralName]: entitiesRange, + [countName]: createEntitiesCounts(entities), }, }, }); @@ -86,6 +100,17 @@ export const createAggregatesResponse = (data = {}) => }, }); +export const createInfoResponse = (infoData: Element) => + createEntityResponse('info', [infoData] as unknown as Element, { + responseName: 'get_info_response', + }); + +export const createInfoEntitiesResponse = (entities: Element[]) => + createEntitiesResponse('info', entities, { + getName: 'get_info', + responseName: 'get_info_response', + }); + export const createHttp = ( response?: TData | Response, ) => diff --git a/src/gmp/gmp.ts b/src/gmp/gmp.ts index 600e0579a1..0972308a6a 100644 --- a/src/gmp/gmp.ts +++ b/src/gmp/gmp.ts @@ -6,16 +6,11 @@ import 'gmp/commands/alerts'; import 'gmp/commands/audits'; import 'gmp/commands/audit-reports'; -import 'gmp/commands/cert-bund'; -import 'gmp/commands/cpes'; -import 'gmp/commands/cves'; -import 'gmp/commands/dfn-cert'; import 'gmp/commands/filters'; import 'gmp/commands/groups'; import 'gmp/commands/hosts'; import 'gmp/commands/license'; import 'gmp/commands/notes'; -import 'gmp/commands/nvt'; import 'gmp/commands/nvt-families'; import 'gmp/commands/os'; import 'gmp/commands/overrides'; @@ -37,13 +32,23 @@ import AgentInstallerCommand from 'gmp/commands/agent-installer'; import AgentInstallersCommand from 'gmp/commands/agent-installers'; import AgentsCommand from 'gmp/commands/agents'; import AuthenticationCommand from 'gmp/commands/auth'; +import CertBundAdvisoriesCommand from 'gmp/commands/cert-bund-advisories'; +import CertBundAdvisoryCommand from 'gmp/commands/cert-bund-advisory'; +import CpeCommand from 'gmp/commands/cpe'; +import CpesCommand from 'gmp/commands/cpes'; import CredentialCommand from 'gmp/commands/credential'; import CredentialStoreCommand from 'gmp/commands/credential-store'; import CredentialStoresCommand from 'gmp/commands/credential-stores'; import CredentialsCommand from 'gmp/commands/credentials'; +import CveCommand from 'gmp/commands/cve'; +import CvesCommand from 'gmp/commands/cves'; import DashboardCommand from 'gmp/commands/dashboards'; +import DfnCertAdvisoriesCommand from 'gmp/commands/dfn-cert-advisories'; +import DfnCertAdvisoryCommand from 'gmp/commands/dfn-cert-advisory'; import FeedStatusCommand from 'gmp/commands/feed-status'; import LoginCommand from 'gmp/commands/login'; +import NvtCommand from 'gmp/commands/nvt'; +import NvtsCommand from 'gmp/commands/nvts'; import OciImageTargetCommand from 'gmp/commands/oci-image-target'; import OciImageTargetsCommand from 'gmp/commands/oci-image-targets'; import PerformanceCommand from 'gmp/commands/performance'; @@ -94,12 +99,22 @@ class Gmp { readonly agentinstaller: AgentInstallerCommand; readonly agentinstallers: AgentInstallersCommand; readonly auth: AuthenticationCommand; + readonly certbund: CertBundAdvisoryCommand; + readonly certbunds: CertBundAdvisoriesCommand; readonly credential: CredentialCommand; readonly credentials: CredentialsCommand; + readonly cpe: CpeCommand; + readonly cpes: CpesCommand; readonly credentialstore: CredentialStoreCommand; readonly credentialstores: CredentialStoresCommand; + readonly cve: CveCommand; + readonly cves: CvesCommand; readonly dashboard: DashboardCommand; + readonly dfncert: DfnCertAdvisoryCommand; + readonly dfncerts: DfnCertAdvisoriesCommand; readonly feedstatus: FeedStatusCommand; + readonly nvt: NvtCommand; + readonly nvts: NvtsCommand; readonly ociimagetarget: OciImageTargetCommand; readonly ociimagetargets: OciImageTargetsCommand; readonly performance: PerformanceCommand; @@ -147,12 +162,22 @@ class Gmp { this.agentinstaller = new AgentInstallerCommand(this.http); this.agentinstallers = new AgentInstallersCommand(this.http); this.auth = new AuthenticationCommand(this.http); + this.certbund = new CertBundAdvisoryCommand(this.http); + this.certbunds = new CertBundAdvisoriesCommand(this.http); this.credential = new CredentialCommand(this.http); this.credentials = new CredentialsCommand(this.http); + this.cpe = new CpeCommand(this.http); + this.cpes = new CpesCommand(this.http); this.credentialstore = new CredentialStoreCommand(this.http); this.credentialstores = new CredentialStoresCommand(this.http); + this.cve = new CveCommand(this.http); + this.cves = new CvesCommand(this.http); this.dashboard = new DashboardCommand(this.http); + this.dfncert = new DfnCertAdvisoryCommand(this.http); + this.dfncerts = new DfnCertAdvisoriesCommand(this.http); this.feedstatus = new FeedStatusCommand(this.http); + this.nvt = new NvtCommand(this.http); + this.nvts = new NvtsCommand(this.http); this.ociimagetarget = new OciImageTargetCommand(this.http); this.ociimagetargets = new OciImageTargetsCommand(this.http); this.performance = new PerformanceCommand(this.http);