Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/gmp/__tests__/gmp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ describe('Gmp tests', () => {
'results',
'role',
'roles',
'scanconfig',
'scanconfigs',
'scanner',
'scanners',
'schedule',
Expand All @@ -276,9 +278,6 @@ describe('Gmp tests', () => {
'vuln',
'vulns',
'wizard',
// registered commands (side-effect imports via registerCommand)
'scanconfig',
'scanconfigs',
])('should expose command %s', name => {
const storage = createStorage();
const session = createSession();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/* SPDX-FileCopyrightText: 2024 Greenbone AG
/* SPDX-FileCopyrightText: 2026 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {describe, test, expect} from '@gsa/testing';
import {convertPreferences, ScanConfigCommand} from 'gmp/commands/scan-configs';
import ScanConfigCommand, {
convert,
convertPreferences,
convertSelect,
} from 'gmp/commands/scan-config';
import {
createEntityResponse,
createHttp,
Expand All @@ -15,12 +19,13 @@ import {
import {
SCANCONFIG_TREND_STATIC,
SCANCONFIG_TREND_DYNAMIC,
type ScanConfigTrend,
} from 'gmp/models/scan-config';
import {YES_VALUE, NO_VALUE} from 'gmp/parser';
import {YES_VALUE, NO_VALUE, type YesNo} from 'gmp/parser';

describe('convertPreferences tests', () => {
test('should convert preferences', () => {
const prefenceValues = {
const preferenceValues = {
'foo Password:': {
id: 1,
value: undefined,
Expand All @@ -43,7 +48,7 @@ describe('convertPreferences tests', () => {
},
};

expect(convertPreferences(prefenceValues, '1.2.3')).toEqual({
expect(convertPreferences(preferenceValues, '1.2.3')).toEqual({
'file:1.2.3:4:file:foo': 'yes',
'password:1.2.3:3:password:bar': 'yes',
'preference:1.2.3:2:entry:foo Username:': 'user',
Expand All @@ -58,6 +63,45 @@ describe('convertPreferences tests', () => {
});
});

describe('convert tests', () => {
test('should convert values with prefix', () => {
const values = {
foo: 'bar',
baz: 123,
};
const prefix = 'prefix_';
const expected = {
prefix_foo: 'bar',
prefix_baz: 123,
};
expect(convert(values, prefix)).toEqual(expected);
});

test('should return empty object if values are empty', () => {
expect(convert({}, 'prefix_')).toEqual({});
});
});

describe('convertSelect tests', () => {
test('should convert select values with prefix', () => {
const values: Record<string, YesNo> = {
foo: YES_VALUE,
bar: NO_VALUE,
baz: YES_VALUE,
};
const prefix = 'select_';
const expected = {
select_foo: YES_VALUE,
select_baz: YES_VALUE,
};
expect(convertSelect(values, prefix)).toEqual(expected);
});

test('should return empty object if values are empty', () => {
expect(convertSelect({}, 'select_')).toEqual({});
});
});

describe('ScanConfigCommand tests', () => {
test('should return single config', async () => {
const response = createEntityResponse('config', {_id: 'foo'});
Expand Down Expand Up @@ -110,11 +154,11 @@ describe('ScanConfigCommand tests', () => {
test('should save a config', async () => {
const response = createActionResultResponse();
const fakeHttp = createHttp(response);
const trend = {
const trend: Record<string, ScanConfigTrend> = {
'AIX Local Security Checks': SCANCONFIG_TREND_DYNAMIC,
'Family Foo': SCANCONFIG_TREND_STATIC,
};
const select = {
const select: Record<string, YesNo> = {
'AIX Local Security Checks': YES_VALUE,
'Brute force attacks': YES_VALUE,
'Foo Family': NO_VALUE,
Expand Down Expand Up @@ -146,6 +190,29 @@ describe('ScanConfigCommand tests', () => {
});
});

test('should save a config with family trend', async () => {
const response = createActionResultResponse();
const fakeHttp = createHttp(response);
const cmd = new ScanConfigCommand(fakeHttp);

await cmd.save({
id: 'c1',
name: 'foo',
comment: 'somecomment',
familyTrend: SCANCONFIG_TREND_DYNAMIC,
});

expect(fakeHttp.request).toHaveBeenCalledWith('post', {
data: {
cmd: 'save_config',
comment: 'somecomment',
config_id: 'c1',
name: 'foo',
trend: SCANCONFIG_TREND_DYNAMIC,
},
});
});

test('should save an in use config with undefined input objects', async () => {
const response = createActionResultResponse();
const fakeHttp = createHttp(response);
Expand All @@ -171,7 +238,7 @@ describe('ScanConfigCommand tests', () => {
test('should save a config family', async () => {
const response = createActionResultResponse();
const fakeHttp = createHttp(response);
const selected = {
const selected: Record<string, YesNo> = {
'oid:1': YES_VALUE,
'oid:2': NO_VALUE,
'oid:3': YES_VALUE,
Expand Down Expand Up @@ -229,6 +296,28 @@ describe('ScanConfigCommand tests', () => {
});
});

test('should save a config nvt without timeout', async () => {
const response = createActionResultResponse();
const fakeHttp = createHttp(response);
const cmd = new ScanConfigCommand(fakeHttp);

await cmd.saveScanConfigNvt({
id: 'c1',
oid: '1.2.3',
preferenceValues: undefined,
});

expect(fakeHttp.request).toHaveBeenCalledWith('post', {
data: {
cmd: 'save_config_nvt',
config_id: 'c1',
oid: '1.2.3',
'preference:1.2.3:0:entry:timeout': '',
timeout: 0,
},
});
});

test('should request scan config family data', async () => {
const response = createResponse({
get_config_family_response: {
Expand Down
147 changes: 147 additions & 0 deletions src/gmp/commands/__tests__/scan-configs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/* SPDX-FileCopyrightText: 2026 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {describe, test, expect} from '@gsa/testing';
import ScanConfigsCommand from 'gmp/commands/scan-configs';
import {createEntitiesResponse, createHttp} from 'gmp/commands/testing';
import Filter, {ALL_FILTER} from 'gmp/models/filter';
import ScanConfig from 'gmp/models/scan-config';

describe('ScanConfigsCommand tests', () => {
test('should fetch all scan configs', async () => {
const response = createEntitiesResponse('config', [
{
_id: '1',
},
{
_id: '2',
},
]);

const fakeHttp = createHttp(response);
const cmd = new ScanConfigsCommand(fakeHttp);
const resp = await cmd.getAll();
expect(fakeHttp.request).toHaveBeenCalledWith('get', {
args: {
cmd: 'get_configs',
filter: ALL_FILTER.toFilterString(),
usage_type: 'scan',
},
});
const {data} = resp;
expect(data.length).toEqual(2);
});

test('should fetch scan configs with default params', async () => {
const response = createEntitiesResponse('config', [
{
_id: '1',
},
{
_id: '2',
},
]);

const fakeHttp = createHttp(response);
const cmd = new ScanConfigsCommand(fakeHttp);
const resp = await cmd.get();
expect(fakeHttp.request).toHaveBeenCalledWith('get', {
args: {
cmd: 'get_configs',
usage_type: 'scan',
},
});
const {data} = resp;
expect(data.length).toEqual(2);
});

test('should fetch scan configs with custom params', async () => {
const response = createEntitiesResponse('config', [
{
_id: '1',
},
{
_id: '2',
},
]);

const fakeHttp = createHttp(response);
const cmd = new ScanConfigsCommand(fakeHttp);
const resp = await cmd.get({
filter: ALL_FILTER,
details: 1,
});
expect(fakeHttp.request).toHaveBeenCalledWith('get', {
args: {
cmd: 'get_configs',
filter: ALL_FILTER.toFilterString(),
details: 1,
usage_type: 'scan',
},
});
const {data} = resp;
expect(data.length).toEqual(2);
});

test('should allow to export scan configs by filter', async () => {
const response = createEntitiesResponse('config', []);
const fakeHttp = createHttp(response);

const filter = Filter.fromString('name~foo');

const cmd = new ScanConfigsCommand(fakeHttp);
await cmd.exportByFilter(filter);
expect(fakeHttp.request).toHaveBeenCalledWith('post', {
data: {
cmd: 'bulk_export',
resource_type: 'config',
bulk_select: 0,
filter: 'name~foo',
},
});
});

test('should allow to export scan configs by ids', async () => {
const response = createEntitiesResponse('config', []);
const fakeHttp = createHttp(response);

const cmd = new ScanConfigsCommand(fakeHttp);

const ids = ['123', '456'];

await cmd.exportByIds(ids);

expect(fakeHttp.request).toHaveBeenCalledWith('post', {
data: {
'bulk_selected:123': 1,
'bulk_selected:456': 1,
cmd: 'bulk_export',
resource_type: 'config',
bulk_select: 1,
},
});
});

test('should allow to export scan configs', async () => {
const response = createEntitiesResponse('config', []);
const fakeHttp = createHttp(response);

const cmd = new ScanConfigsCommand(fakeHttp);

const entities = [new ScanConfig({id: '123'}), new ScanConfig({id: '456'})];

await cmd.export(entities);

expect(fakeHttp.request).toHaveBeenCalledWith('post', {
data: {
'bulk_selected:123': 1,
'bulk_selected:456': 1,
cmd: 'bulk_export',
resource_type: 'config',
bulk_select: 1,
},
});
});
});
9 changes: 2 additions & 7 deletions src/gmp/commands/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,19 @@ import {
convert,
convertSelect,
convertPreferences,
} from 'gmp/commands/scan-configs';
} from 'gmp/commands/scan-config';
import type Http from 'gmp/http/http';
import logger from 'gmp/log';
import {type Element} from 'gmp/models/model';
import Policy from 'gmp/models/policy';
import {
BASE_SCAN_CONFIG_ID,
type SCANCONFIG_TREND_DYNAMIC,
type SCANCONFIG_TREND_STATIC,
type ScanConfigTrend,
} from 'gmp/models/scan-config';
import {YES_VALUE, NO_VALUE, type YesNo} from 'gmp/parser';
import {forEach, map} from 'gmp/utils/array';
import {isDefined} from 'gmp/utils/identity';

type ScanConfigTrend =
| typeof SCANCONFIG_TREND_DYNAMIC
| typeof SCANCONFIG_TREND_STATIC;

interface NvtResponseEntry {
_oid: string;
cvss_base?: number;
Expand Down
Loading
Loading