Commit d617e6e0 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'dj-dast-scanner-options' into 'master'

Add new options in Scanner Profile Form

See merge request gitlab-org/gitlab!43660
parents 5ad7a89e bdc467e2
<script>
import { SCAN_TYPE_OPTIONS } from 'ee/security_configuration/dast_scanner_profiles/constants';
import ProfileSelector from './profile_selector.vue';
import SummaryCell from './summary_cell.vue';
import { __, s__ } from '~/locale';
export default {
name: 'OnDemandScansScannerProfileSelector',
......@@ -23,6 +25,19 @@ export default {
default: '',
},
},
methods: {
getScanModeText(scanType) {
return SCAN_TYPE_OPTIONS.find(({ value }) => scanType === value)?.text;
},
getAjaxSpiderText(isEnabled) {
return isEnabled ? __('On') : __('Off');
},
getDebugMessageText(isEnabled) {
return isEnabled
? s__('DastProfiles|Show debug messages')
: s__('DastProfiles|Hide debug messages');
},
},
};
</script>
......@@ -44,7 +59,10 @@ export default {
<template #new-profile>{{ s__('OnDemandScans|Create a new scanner profile') }}</template>
<template #summary="{ profile }">
<div class="row">
<summary-cell :label="s__('DastProfiles|Scan mode')" :value="s__('DastProfiles|Passive')" />
<summary-cell
:label="s__('DastProfiles|Scan mode')"
:value="getScanModeText(profile.scanType)"
/>
</div>
<div class="row">
<summary-cell
......@@ -56,6 +74,16 @@ export default {
:value="n__('%d second', '%d seconds', profile.targetTimeout)"
/>
</div>
<div class="row">
<summary-cell
:label="s__('DastProfiles|AJAX spider')"
:value="getAjaxSpiderText(profile.useAjaxSpider)"
/>
<summary-cell
:label="s__('DastProfiles|Debug messages')"
:value="getDebugMessageText(profile.showDebugMessages)"
/>
</div>
</template>
</profile-selector>
</template>
......@@ -16,7 +16,7 @@ export default {
<template>
<div class="col-md-6">
<div class="row">
<div class="row gl-my-2">
<div class="col-md-3">{{ label }}:</div>
<div class="col-md-9">
<strong>{{ value }}</strong>
......
......@@ -24,6 +24,9 @@ query DastScannerProfiles(
profileName
spiderTimeout
targetTimeout
scanType
useAjaxSpider
showDebugMessages
editPath
}
}
......
......@@ -12,14 +12,17 @@ import {
GlIcon,
GlTooltipDirective,
GlInputGroupText,
GlFormCheckbox,
GlFormRadioGroup,
} from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility';
import { serializeFormObject, isEmptyValue } from '~/lib/utils/forms';
import dastScannerProfileCreateMutation from '../graphql/dast_scanner_profile_create.mutation.graphql';
import dastScannerProfileUpdateMutation from '../graphql/dast_scanner_profile_update.mutation.graphql';
import { SCAN_TYPE, SCAN_TYPE_OPTIONS } from '../constants';
const initField = (value, isRequired = false) => ({
const initField = (value, isRequired = true) => ({
value,
required: isRequired,
state: null,
......@@ -43,6 +46,8 @@ export default {
GlModal,
GlIcon,
GlInputGroupText,
GlFormCheckbox,
GlFormRadioGroup,
},
directives: {
GlTooltip: GlTooltipDirective,
......@@ -63,12 +68,22 @@ export default {
},
},
data() {
const { name = '', spiderTimeout = '', targetTimeout = '' } = this.profile;
const {
name = '',
spiderTimeout = '',
targetTimeout = '',
scanType = SCAN_TYPE.PASSIVE,
useAjaxSpider = false,
showDebugMessages = false,
} = this.profile;
const form = {
profileName: initField(name, true),
spiderTimeout: initField(spiderTimeout, true),
targetTimeout: initField(targetTimeout, true),
profileName: initField(name),
spiderTimeout: initField(spiderTimeout),
targetTimeout: initField(targetTimeout),
scanType: initField(scanType),
useAjaxSpider: initField(useAjaxSpider),
showDebugMessages: initField(showDebugMessages),
};
return {
......@@ -86,6 +101,7 @@ export default {
min: TARGET_TIMEOUT_MIN,
max: TARGET_TIMEOUT_MAX,
},
SCAN_TYPE_OPTIONS,
computed: {
isEdit() {
return Boolean(this.profile.id);
......@@ -113,6 +129,15 @@ export default {
targetTimeout: s__(
'DastProfiles|The maximum number of seconds allowed for the site under test to respond to a request.',
),
scanMode: s__(
'DastProfiles|Active scan will make active attacks against the target site while Passive scan will not',
),
ajaxSpider: s__(
'DastProfiles|Enable it to run the AJAX spider (in addition to the traditional spider) to crawl the target site',
),
debugMessage: s__(
'DastProfiles|Enable it to include the debug messages in DAST console output',
),
},
};
},
......@@ -237,11 +262,29 @@ export default {
/>
</gl-form-group>
<hr />
<hr class="gl-border-gray-100" />
<gl-form-group>
<template #label>
{{ s__('DastProfiles|Scan mode') }}
<gl-icon
v-gl-tooltip.hover
name="information-o"
class="gl-vertical-align-text-bottom gl-text-gray-400 gl-ml-2"
:title="i18n.tooltips.scanMode"
/>
</template>
<gl-form-radio-group
v-model="form.scanType.value"
:options="$options.SCAN_TYPE_OPTIONS"
data-testid="scan-type-option"
/>
</gl-form-group>
<div class="row">
<gl-form-group
class="col-md-6"
class="col-md-6 mb-0"
:state="form.spiderTimeout.state"
:invalid-feedback="form.spiderTimeout.feedback"
>
......@@ -273,7 +316,7 @@ export default {
</gl-form-group>
<gl-form-group
class="col-md-6"
class="col-md-6 mb-0"
:state="form.targetTimeout.state"
:invalid-feedback="form.targetTimeout.feedback"
>
......@@ -305,7 +348,41 @@ export default {
</gl-form-group>
</div>
<hr />
<hr class="gl-border-gray-100" />
<div class="row">
<gl-form-group class="col-md-6 mb-0">
<template #label>
{{ s__('DastProfiles|AJAX spider') }}
<gl-icon
v-gl-tooltip.hover
name="information-o"
class="gl-vertical-align-text-bottom gl-text-gray-400 gl-ml-2"
:title="i18n.tooltips.ajaxSpider"
/>
</template>
<gl-form-checkbox v-model="form.useAjaxSpider.value">{{
s__('DastProfiles|Turn on AJAX spider')
}}</gl-form-checkbox>
</gl-form-group>
<gl-form-group class="col-md-6 mb-0">
<template #label>
{{ s__('DastProfiles|Debug messages') }}
<gl-icon
v-gl-tooltip.hover
name="information-o"
class="gl-vertical-align-text-bottom gl-text-gray-400 gl-ml-2"
:title="i18n.tooltips.debugMessage"
/>
</template>
<gl-form-checkbox v-model="form.showDebugMessages.value">{{
s__('DastProfiles|Show debug messages')
}}</gl-form-checkbox>
</gl-form-group>
</div>
<hr class="gl-border-gray-100" />
<gl-button
type="submit"
......
import { s__ } from '~/locale';
export const SCAN_TYPE = {
ACTIVE: 'ACTIVE',
PASSIVE: 'PASSIVE',
};
export const SCAN_TYPE_OPTIONS = [
{
value: SCAN_TYPE.ACTIVE,
text: s__('DastProfiles|Active'),
},
{
value: SCAN_TYPE.PASSIVE,
text: s__('DastProfiles|Passive'),
},
];
......@@ -3,6 +3,9 @@ mutation dastScannerProfileCreate(
$profileName: String!
$spiderTimeout: Int!
$targetTimeout: Int!
$scanType: DastScanTypeEnum!
$useAjaxSpider: Boolean!
$showDebugMessages: Boolean!
) {
dastScannerProfileCreate(
input: {
......@@ -10,6 +13,9 @@ mutation dastScannerProfileCreate(
profileName: $profileName
spiderTimeout: $spiderTimeout
targetTimeout: $targetTimeout
scanType: $scanType
useAjaxSpider: $useAjaxSpider
showDebugMessages: $showDebugMessages
}
) {
errors
......
......@@ -4,6 +4,9 @@ mutation dastScannerProfileUpdate(
$profileName: String!
$spiderTimeout: Int!
$targetTimeout: Int!
$scanType: DastScanTypeEnum!
$useAjaxSpider: Boolean!
$showDebugMessages: Boolean!
) {
dastScannerProfileUpdate(
input: {
......@@ -12,6 +15,9 @@ mutation dastScannerProfileUpdate(
profileName: $profileName
spiderTimeout: $spiderTimeout
targetTimeout: $targetTimeout
scanType: $scanType
useAjaxSpider: $useAjaxSpider
showDebugMessages: $showDebugMessages
}
) {
id
......
......@@ -5,4 +5,7 @@
.js-dast-scanner-profile-form{ data: { project_full_path: @project.path_with_namespace,
profiles_library_path: project_security_configuration_dast_profiles_path(@project, anchor: 'scanner-profiles'),
scanner_profile: { id: @scanner_profile.to_global_id.to_s, name: @scanner_profile.name, spider_timeout: @scanner_profile.spider_timeout, target_timeout: @scanner_profile.target_timeout }.to_json } }
scanner_profile: { id: @scanner_profile.to_global_id.to_s, name: @scanner_profile.name,
spider_timeout: @scanner_profile.spider_timeout, target_timeout: @scanner_profile.target_timeout,
scan_type: @scanner_profile.scan_type.upcase, use_ajax_spider: @scanner_profile.use_ajax_spider,
show_debug_messages: @scanner_profile.show_debug_messages }.to_json } }
---
title: Add more options in DAST On-demand Scanner Profile
merge_request: 43660
author:
type: added
......@@ -195,7 +195,7 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
class="col-md-6"
>
<div
class="row"
class="row gl-my-2"
>
<div
class="col-md-3"
......@@ -221,7 +221,7 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
class="col-md-6"
>
<div
class="row"
class="row gl-my-2"
>
<div
class="col-md-3"
......@@ -243,7 +243,7 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
class="col-md-6"
>
<div
class="row"
class="row gl-my-2"
>
<div
class="col-md-3"
......@@ -261,6 +261,54 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
</div>
</div>
</div>
<div
class="row"
>
<div
class="col-md-6"
>
<div
class="row gl-my-2"
>
<div
class="col-md-3"
>
AJAX spider:
</div>
<div
class="col-md-9"
>
<strong>
Off
</strong>
</div>
</div>
</div>
<div
class="col-md-6"
>
<div
class="row gl-my-2"
>
<div
class="col-md-3"
>
Debug messages:
</div>
<div
class="col-md-9"
>
<strong>
Hide debug messages
</strong>
</div>
</div>
</div>
</div>
</div>
<!---->
<!---->
......
......@@ -195,7 +195,7 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = `
class="col-md-6"
>
<div
class="row"
class="row gl-my-2"
>
<div
class="col-md-3"
......
......@@ -2,7 +2,7 @@
exports[`OnDemandScansProfileSummaryCell renders properly 1`] = `
"<div class=\\"col-md-6\\">
<div class=\\"row\\">
<div class=\\"row gl-my-2\\">
<div class=\\"col-md-3\\">Row Label:</div>
<div class=\\"col-md-9\\"><strong>Row Value</strong></div>
</div>
......
......@@ -4,12 +4,18 @@ export const scannerProfiles = [
profileName: 'Scanner profile #1',
spiderTimeout: 5,
targetTimeout: 10,
scanType: 'PASSIVE',
useAjaxSpider: false,
showDebugMessages: false,
},
{
id: 'gid://gitlab/DastScannerProfile/2',
profileName: 'Scanner profile #2',
spiderTimeout: 20,
targetTimeout: 150,
scanType: 'ACTIVE',
useAjaxSpider: true,
showDebugMessages: true,
},
];
......
......@@ -6,6 +6,8 @@ import { TEST_HOST } from 'helpers/test_constants';
import DastScannerProfileForm from 'ee/security_configuration/dast_scanner_profiles/components/dast_scanner_profile_form.vue';
import dastScannerProfileCreateMutation from 'ee/security_configuration/dast_scanner_profiles/graphql/dast_scanner_profile_create.mutation.graphql';
import dastScannerProfileUpdateMutation from 'ee/security_configuration/dast_scanner_profiles/graphql/dast_scanner_profile_update.mutation.graphql';
import { SCAN_TYPE } from 'ee/security_configuration/dast_scanner_profiles/constants';
import { scannerProfiles } from 'ee_jest/on_demand_scans/mock_data';
import { redirectTo } from '~/lib/utils/url_utility';
jest.mock('~/lib/utils/url_utility', () => ({
......@@ -14,9 +16,16 @@ jest.mock('~/lib/utils/url_utility', () => ({
const projectFullPath = 'group/project';
const profilesLibraryPath = `${TEST_HOST}/${projectFullPath}/-/security/configuration/dast_profiles`;
const profileName = 'My DAST scanner profile';
const spiderTimeout = 12;
const targetTimeout = 20;
const defaultProfile = scannerProfiles[0];
const {
profileName,
spiderTimeout,
targetTimeout,
scanType,
useAjaxSpider,
showDebugMessages,
} = defaultProfile;
const defaultProps = {
profilesLibraryPath,
......@@ -27,18 +36,19 @@ describe('DAST Scanner Profile', () => {
let wrapper;
const withinComponent = () => within(wrapper.element);
const findByTestId = testId => wrapper.find(`[data-testid="${testId}"`);
const findForm = () => wrapper.find(GlForm);
const findProfileNameInput = () => wrapper.find('[data-testid="profile-name-input"]');
const findSpiderTimeoutInput = () => wrapper.find('[data-testid="spider-timeout-input"]');
const findTargetTimeoutInput = () => wrapper.find('[data-testid="target-timeout-input"]');
const findSubmitButton = () =>
wrapper.find('[data-testid="dast-scanner-profile-form-submit-button"]');
const findCancelButton = () =>
wrapper.find('[data-testid="dast-scanner-profile-form-cancel-button"]');
const findProfileNameInput = () => findByTestId('profile-name-input');
const findSpiderTimeoutInput = () => findByTestId('spider-timeout-input');
const findTargetTimeoutInput = () => findByTestId('target-timeout-input');
const findSubmitButton = () => findByTestId('dast-scanner-profile-form-submit-button');
const findCancelButton = () => findByTestId('dast-scanner-profile-form-cancel-button');
const findScanType = () => findByTestId('scan-type-option');
const findCancelModal = () => wrapper.find(GlModal);
const submitForm = () => findForm().vm.$emit('submit', { preventDefault: () => {} });
const findAlert = () => wrapper.find(GlAlert);
const submitForm = () => findForm().vm.$emit('submit', { preventDefault: () => {} });
const componentFactory = (mountFn = shallowMount) => options => {
wrapper = mountFn(
......@@ -136,9 +146,9 @@ describe('DAST Scanner Profile', () => {
});
describe.each`
title | profile | mutation | mutationVars | mutationKind
${'New scanner profile'} | ${{}} | ${dastScannerProfileCreateMutation} | ${{}} | ${'dastScannerProfileCreate'}
${'Edit scanner profile'} | ${{ id: 1, name: 'foo', spiderTimeout: 2, targetTimeout: 12 }} | ${dastScannerProfileUpdateMutation} | ${{ id: 1 }} | ${'dastScannerProfileUpdate'}
title | profile | mutation | mutationVars | mutationKind
${'New scanner profile'} | ${{}} | ${dastScannerProfileCreateMutation} | ${{}} | ${'dastScannerProfileCreate'}
${'Edit scanner profile'} | ${defaultProfile} | ${dastScannerProfileUpdateMutation} | ${{ id: defaultProfile.id }} | ${'dastScannerProfileUpdate'}
`('$title', ({ profile, title, mutation, mutationVars, mutationKind }) => {
beforeEach(() => {
createFullComponent({
......@@ -152,8 +162,9 @@ describe('DAST Scanner Profile', () => {
expect(withinComponent().getByRole('heading', { name: title })).not.toBeNull();
});
it('populates the fields with the data passed in via the profile prop', () => {
it('populates the fields with the data passed in via the profile prop or default values', () => {
expect(findProfileNameInput().element.value).toBe(profile?.name ?? '');
expect(findScanType().vm.$attrs.checked).toBe(profile?.scanType ?? SCAN_TYPE.PASSIVE);
});
describe('submission', () => {
......@@ -182,6 +193,9 @@ describe('DAST Scanner Profile', () => {
spiderTimeout,
targetTimeout,
projectFullPath,
scanType,
useAjaxSpider,
showDebugMessages,
...mutationVars,
},
});
......
......@@ -8028,6 +8028,15 @@ msgstr ""
msgid "Dashboard|Unable to add %{invalidProjects}. This dashboard is available for public projects, and private projects in groups with a Silver plan."
msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
msgid "DastProfiles|Active"
msgstr ""
msgid "DastProfiles|Active scan will make active attacks against the target site while Passive scan will not"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
msgstr ""
......@@ -8067,6 +8076,9 @@ msgstr ""
msgid "DastProfiles|Could not update the site profile. Please try again."
msgstr ""
msgid "DastProfiles|Debug messages"
msgstr ""
msgid "DastProfiles|Do you want to discard this scanner profile?"
msgstr ""
......@@ -8085,9 +8097,18 @@ msgstr ""
msgid "DastProfiles|Edit site profile"
msgstr ""
msgid "DastProfiles|Enable it to include the debug messages in DAST console output"
msgstr ""
msgid "DastProfiles|Enable it to run the AJAX spider (in addition to the traditional spider) to crawl the target site"
msgstr ""
msgid "DastProfiles|Error Details"
msgstr ""
msgid "DastProfiles|Hide debug messages"
msgstr ""
msgid "DastProfiles|Manage Profiles"
msgstr ""
......@@ -8139,6 +8160,9 @@ msgstr ""
msgid "DastProfiles|Scanner Profiles"
msgstr ""
msgid "DastProfiles|Show debug messages"
msgstr ""
msgid "DastProfiles|Site Profile"
msgstr ""
......@@ -8178,6 +8202,9 @@ msgstr ""
msgid "DastProfiles|The maximum number of seconds allowed for the site under test to respond to a request."
msgstr ""
msgid "DastProfiles|Turn on AJAX spider"
msgstr ""
msgid "DastProfiles|Validate"
msgstr ""
......@@ -17892,6 +17919,9 @@ msgstr ""
msgid "Omnibus Protected Paths throttle is active, and takes priority over these settings. From 12.4, Omnibus throttle is deprecated and will be removed in a future release. Please read the %{relative_url_link_start}Migrating Protected Paths documentation%{relative_url_link_end}."
msgstr ""
msgid "On"
msgstr ""
msgid "On track"
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment