Commit c00bc663 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'djadmin-meta-tag-validation' into 'master'

Add new method for DAST site validation

See merge request gitlab-org/gitlab!67945
parents 6ab56bdf cd871071
---
name: dast_meta_tag_validation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67945
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337711
milestone: '14.2'
type: development
group: group::dynamic analysis
default_enabled: false
......@@ -16,11 +16,13 @@ import download from '~/lib/utils/downloader';
import { cleanLeadingSeparator, joinPaths, stripPathTail } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
DAST_SITE_VALIDATION_MODAL_ID,
DAST_SITE_VALIDATION_HTTP_HEADER_KEY,
DAST_SITE_VALIDATION_METHOD_HTTP_HEADER,
DAST_SITE_VALIDATION_METHOD_TEXT_FILE,
DAST_SITE_VALIDATION_METHOD_META_TAG,
DAST_SITE_VALIDATION_METHODS,
} from '../constants';
import dastSiteTokenCreateMutation from '../graphql/dast_site_token_create.mutation.graphql';
......@@ -42,6 +44,7 @@ export default {
GlSkeletonLoader,
GlTruncate,
},
mixins: [glFeatureFlagMixin()],
props: {
fullPath: {
type: String,
......@@ -82,7 +85,11 @@ export default {
};
},
validationMethodOptions() {
return Object.values(DAST_SITE_VALIDATION_METHODS);
const options = Object.values(DAST_SITE_VALIDATION_METHODS);
if (!this.glFeatures.dastMetaTagValidation) {
return options.filter(({ value }) => value !== DAST_SITE_VALIDATION_METHOD_META_TAG);
}
return options;
},
urlObject() {
try {
......@@ -103,6 +110,9 @@ export default {
isHttpHeaderValidation() {
return this.validationMethod === DAST_SITE_VALIDATION_METHOD_HTTP_HEADER;
},
isMetaTagValidation() {
return this.validationMethod === DAST_SITE_VALIDATION_METHOD_META_TAG;
},
textFileName() {
return `GitLab-DAST-Site-Validation-${this.token}.txt`;
},
......@@ -112,6 +122,9 @@ export default {
httpHeader() {
return `${DAST_SITE_VALIDATION_HTTP_HEADER_KEY}: ${this.token}`;
},
metaTag() {
return `<meta name="gitlab-dast-validation" content="${this.token}">`;
},
},
watch: {
targetUrl: {
......@@ -253,6 +266,17 @@ export default {
:modal-id="modalProps.id"
/>
</gl-form-group>
<gl-form-group
v-else-if="isMetaTagValidation"
:label="s__('DastSiteValidation|Step 2 - Add following meta tag to your site')"
>
<code class="gl-p-3 gl-bg-black gl-text-white">{{ metaTag }}</code>
<modal-copy-button
:text="metaTag"
:title="s__('DastSiteValidation|Copy Meta tag to clipboard')"
:modal-id="modalProps.id"
/>
</gl-form-group>
<gl-form-group :label="locationStepLabel" class="mw-460">
<gl-form-input-group>
<template #prepend>
......
......@@ -2,6 +2,7 @@ import { s__ } from '~/locale';
export const DAST_SITE_VALIDATION_METHOD_TEXT_FILE = 'TEXT_FILE';
export const DAST_SITE_VALIDATION_METHOD_HTTP_HEADER = 'HEADER';
export const DAST_SITE_VALIDATION_METHOD_META_TAG = 'META_TAG';
export const DAST_SITE_VALIDATION_METHODS = {
[DAST_SITE_VALIDATION_METHOD_TEXT_FILE]: {
......@@ -18,6 +19,13 @@ export const DAST_SITE_VALIDATION_METHODS = {
locationStepLabel: s__('DastSiteValidation|Step 3 - Confirm header location and validate'),
},
},
[DAST_SITE_VALIDATION_METHOD_META_TAG]: {
value: DAST_SITE_VALIDATION_METHOD_META_TAG,
text: s__('DastSiteValidation|Meta tag validation'),
i18n: {
locationStepLabel: s__('DastSiteValidation|Step 3 - Confirm meta tag location and validate'),
},
},
};
export const DAST_SITE_VALIDATION_STATUS = {
......
......@@ -8,6 +8,7 @@ module Projects
before_action do
authorize_read_on_demand_scans!
push_frontend_feature_flag(:dast_failed_site_validations, @project, default_enabled: :yaml)
push_frontend_feature_flag(:dast_meta_tag_validation, @project, default_enabled: :yaml)
end
feature_category :dynamic_application_security_testing
......
......@@ -22,7 +22,7 @@ const targetUrl = 'https://example.com/';
const tokenId = '1';
const token = 'validation-token-123';
const validationMethods = ['text file', 'header'];
const validationMethods = ['text file', 'header', 'meta tag'];
const defaultProps = {
fullPath,
......@@ -57,6 +57,9 @@ describe('DastSiteValidationModal', () => {
static: true,
visible: true,
},
provide: {
glFeatures: { dastMetaTagValidation: true },
},
},
mountOptions,
{
......@@ -284,6 +287,57 @@ describe('DastSiteValidationModal', () => {
});
});
});
describe('meta tag validation', () => {
beforeEach(async () => {
createFullComponent();
await waitForPromises();
enableValidationMethod('meta tag');
});
it.each([
/step 2 - add following meta tag to your site/i,
/step 3 - confirm meta tag location and validate/i,
])('shows the correct descriptions', (descriptionText) => {
expect(withinComponent().getByText(descriptionText)).not.toBe(null);
});
it('shows a code block containing the meta key with the given token', () => {
expect(
withinComponent().getByText(`<meta name="gitlab-dast-validation" content="${token}">`, {
selector: 'code',
}),
).not.toBe(null);
});
it('shows a button that copies the meta tag to the clipboard', () => {
const clipboardButton = wrapper.find(ModalCopyButton);
expect(clipboardButton.exists()).toBe(true);
expect(clipboardButton.props()).toMatchObject({
text: `<meta name="gitlab-dast-validation" content="${token}">`,
title: 'Copy Meta tag to clipboard',
});
});
});
});
describe('with the dastMetaTagValidation feature flag disabled', () => {
beforeEach(() => {
createFullComponent({
provide: {
glFeatures: {
dastMetaTagValidation: false,
},
},
});
});
it('does not render the meta tag validation method', () => {
expect(findRadioInputForValidationMethod('meta tag')).toBe(null);
});
});
describe.each(validationMethods)('"%s" validation submission', (validationMethod) => {
......
......@@ -10438,6 +10438,9 @@ msgstr ""
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
msgid "DastSiteValidation|Copy Meta tag to clipboard"
msgstr ""
msgid "DastSiteValidation|Could not create validation token. Please try again."
msgstr ""
......@@ -10450,6 +10453,9 @@ msgstr ""
msgid "DastSiteValidation|Header validation"
msgstr ""
msgid "DastSiteValidation|Meta tag validation"
msgstr ""
msgid "DastSiteValidation|Retry validation"
msgstr ""
......@@ -10462,12 +10468,18 @@ msgstr ""
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
msgstr ""
msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
msgstr ""
msgid "DastSiteValidation|Step 2 - Add following text to the target site"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm header location and validate"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm meta tag location and validate"
msgstr ""
msgid "DastSiteValidation|Step 3 - Confirm text file location and validate"
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