Commit ec218553 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '280559-remove-dast-site-profile-validation' into 'master'

Remove validation from DAST site profile form

See merge request gitlab-org/gitlab!47701
parents f0b673bc d9cfd07d
<script> <script>
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { import { GlAlert, GlButton, GlForm, GlFormGroup, GlFormInput, GlModal } from '@gitlab/ui';
GlAlert,
GlButton,
GlCollapse,
GlForm,
GlFormGroup,
GlFormInput,
GlModal,
GlToggle,
} from '@gitlab/ui';
import { initFormField } from 'ee/security_configuration/utils'; import { initFormField } from 'ee/security_configuration/utils';
import * as Sentry from '~/sentry/wrapper'; import * as Sentry from '~/sentry/wrapper';
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import { serializeFormObject } from '~/lib/utils/forms'; import { serializeFormObject } from '~/lib/utils/forms';
import { fetchPolicies } from '~/lib/graphql';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import validation from '~/vue_shared/directives/validation'; import validation from '~/vue_shared/directives/validation';
import DastSiteValidation from './dast_site_validation.vue';
import dastSiteProfileCreateMutation from '../graphql/dast_site_profile_create.mutation.graphql'; import dastSiteProfileCreateMutation from '../graphql/dast_site_profile_create.mutation.graphql';
import dastSiteProfileUpdateMutation from '../graphql/dast_site_profile_update.mutation.graphql'; import dastSiteProfileUpdateMutation from '../graphql/dast_site_profile_update.mutation.graphql';
import dastSiteTokenCreateMutation from '../graphql/dast_site_token_create.mutation.graphql';
import dastSiteValidationQuery from '../graphql/dast_site_validation.query.graphql';
import { DAST_SITE_VALIDATION_STATUS, DAST_SITE_VALIDATION_POLL_INTERVAL } from '../constants';
const { PENDING, INPROGRESS, PASSED, FAILED } = DAST_SITE_VALIDATION_STATUS;
export default { export default {
name: 'DastSiteProfileForm', name: 'DastSiteProfileForm',
components: { components: {
GlAlert, GlAlert,
GlButton, GlButton,
GlCollapse,
GlForm, GlForm,
GlFormGroup, GlFormGroup,
GlFormInput, GlFormInput,
GlModal, GlModal,
GlToggle,
DastSiteValidation,
}, },
directives: { directives: {
validation: validation(), validation: validation(),
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
fullPath: { fullPath: {
type: String, type: String,
...@@ -72,18 +51,12 @@ export default { ...@@ -72,18 +51,12 @@ export default {
}; };
return { return {
fetchValidationTimeout: null,
form, form,
initialFormValues: serializeFormObject(form.fields), initialFormValues: serializeFormObject(form.fields),
isFetchingValidationStatus: false,
isValidatingSite: false,
isLoading: false, isLoading: false,
hasAlert: false, hasAlert: false,
tokenId: null, tokenId: null,
token: null, token: null,
isSiteValidationActive: false,
isSiteValidationTouched: false,
validationStatus: null,
errorMessage: '', errorMessage: '',
errors: [], errors: [],
}; };
...@@ -92,9 +65,6 @@ export default { ...@@ -92,9 +65,6 @@ export default {
isEdit() { isEdit() {
return Boolean(this.siteProfile?.id); return Boolean(this.siteProfile?.id);
}, },
isSiteValidationDisabled() {
return !this.form.fields.targetUrl.state || this.validationStatusMatches(INPROGRESS);
},
i18n() { i18n() {
const { isEdit } = this; const { isEdit } = this;
return { return {
...@@ -111,163 +81,18 @@ export default { ...@@ -111,163 +81,18 @@ export default {
okTitle: __('Discard'), okTitle: __('Discard'),
cancelTitle: __('Cancel'), cancelTitle: __('Cancel'),
}, },
siteValidation: {
validationStatusFetchError: s__(
'DastProfiles|Could not retrieve site validation status. Please refresh the page, or try again later.',
),
createTokenError: s__(
'DastProfiles|Could not create site validation token. Please refresh the page, or try again later.',
),
},
}; };
}, },
formTouched() { formTouched() {
return !isEqual(serializeFormObject(this.form.fields), this.initialFormValues); return !isEqual(serializeFormObject(this.form.fields), this.initialFormValues);
}, },
isSubmitDisabled() {
return (
this.validationStatusMatches(INPROGRESS) ||
(this.isSiteValidationActive && !this.validationStatusMatches(PASSED))
);
},
showValidationSection() {
return (
this.isSiteValidationActive &&
!this.isValidatingSite &&
![INPROGRESS, PASSED].some(this.validationStatusMatches)
);
},
siteValidationStatusDescription() {
const descriptions = {
[PENDING]: { text: s__('DastProfiles|Site must be validated to run an active scan.') },
[INPROGRESS]: {
text: s__('DastProfiles|Validation is in progress...'),
},
[PASSED]: {
text: s__(
'DastProfiles|Validation succeeded. Both active and passive scans can be run against the target site.',
),
cssClass: 'gl-text-green-500',
},
[FAILED]: {
text: s__('DastProfiles|Validation failed. Please try again.'),
cssClass: 'gl-text-red-500',
dismissed: this.isSiteValidationTouched,
},
};
const defaultDescription = descriptions[PENDING];
const currentStatusDescription = descriptions[this.validationStatus];
return currentStatusDescription && !currentStatusDescription.dismissed
? currentStatusDescription
: defaultDescription;
},
}, },
async mounted() { async mounted() {
if (this.isEdit) { if (this.isEdit) {
this.form.showValidation = true; this.form.showValidation = true;
if (this.glFeatures.securityOnDemandScansSiteValidation) {
await this.fetchValidationStatus();
this.isSiteValidationActive = this.validationStatusMatches(PASSED);
} }
}
},
destroyed() {
clearTimeout(this.fetchValidationTimeout);
this.fetchValidationTimeout = null;
}, },
methods: { methods: {
async validateSite(validate) {
this.isSiteValidationActive = validate;
this.isSiteValidationTouched = true;
this.tokenId = null;
this.token = null;
if (!validate) {
this.validationStatus = null;
} else {
try {
this.isValidatingSite = true;
await this.fetchValidationStatus();
if (![PASSED, INPROGRESS].some(this.validationStatusMatches)) {
await this.createValidationToken();
}
} catch (exception) {
this.captureException(exception);
this.isSiteValidationActive = false;
} finally {
this.isValidatingSite = false;
}
}
},
validationStatusMatches(status) {
return this.validationStatus === status;
},
async fetchValidationStatus() {
this.isFetchingValidationStatus = true;
try {
const {
data: {
project: { dastSiteValidation },
},
} = await this.$apollo.query({
query: dastSiteValidationQuery,
variables: {
fullPath: this.fullPath,
targetUrl: this.form.fields.targetUrl.value,
},
fetchPolicy: fetchPolicies.NETWORK_ONLY,
});
this.validationStatus = dastSiteValidation?.status || null;
if (this.validationStatusMatches(INPROGRESS)) {
await new Promise(resolve => {
this.fetchValidationTimeout = setTimeout(resolve, DAST_SITE_VALIDATION_POLL_INTERVAL);
});
await this.fetchValidationStatus();
}
} catch (exception) {
this.showErrors({
message: this.i18n.siteValidation.validationStatusFetchError,
});
throw new Error(exception);
} finally {
this.isFetchingValidationStatus = false;
}
},
async createValidationToken() {
const errorMessage = this.i18n.siteValidation.createTokenError;
try {
const {
data: {
dastSiteTokenCreate: { id, token, errors = [] },
},
} = await this.$apollo.mutate({
mutation: dastSiteTokenCreateMutation,
variables: {
fullPath: this.fullPath,
targetUrl: this.form.fields.targetUrl.value,
},
});
if (errors.length) {
this.showErrors({ message: errorMessage, errors });
} else {
this.tokenId = id;
this.token = token;
}
} catch (exception) {
this.showErrors({ message: errorMessage });
throw new Error(exception);
}
},
onSubmit() { onSubmit() {
this.form.showValidation = true; this.form.showValidation = true;
...@@ -317,9 +142,6 @@ export default { ...@@ -317,9 +142,6 @@ export default {
this.$refs[this.$options.modalId].show(); this.$refs[this.$options.modalId].show();
} }
}, },
onValidationSuccess() {
this.validationStatus = PASSED;
},
discard() { discard() {
redirectTo(this.profilesLibraryPath); redirectTo(this.profilesLibraryPath);
}, },
...@@ -381,11 +203,6 @@ export default { ...@@ -381,11 +203,6 @@ export default {
<gl-form-group <gl-form-group
data-testid="target-url-input-group" data-testid="target-url-input-group"
:invalid-feedback="form.fields.targetUrl.feedback" :invalid-feedback="form.fields.targetUrl.feedback"
:description="
isSiteValidationActive && !isValidatingSite
? s__('DastProfiles|Validation must be turned off to change the target URL')
: null
"
:label="s__('DastProfiles|Target URL')" :label="s__('DastProfiles|Target URL')"
> >
<gl-form-input <gl-form-input
...@@ -397,44 +214,9 @@ export default { ...@@ -397,44 +214,9 @@ export default {
required required
type="url" type="url"
:state="form.fields.targetUrl.state" :state="form.fields.targetUrl.state"
:disabled="isSiteValidationActive"
/>
</gl-form-group>
<template v-if="glFeatures.securityOnDemandScansSiteValidation">
<gl-form-group :label="s__('DastProfiles|Validate target site')">
<template #description>
<p
v-if="siteValidationStatusDescription.text"
class="gl-mt-3"
:class="siteValidationStatusDescription.cssClass"
data-testid="siteValidationStatusDescription"
>
{{ siteValidationStatusDescription.text }}
</p>
</template>
<gl-toggle
data-testid="dast-site-validation-toggle"
:value="isSiteValidationActive"
:disabled="isSiteValidationDisabled"
:is-loading="
!isSiteValidationDisabled && (isFetchingValidationStatus || isValidatingSite)
"
@change="validateSite"
/> />
</gl-form-group> </gl-form-group>
<gl-collapse :visible="showValidationSection">
<dast-site-validation
:full-path="fullPath"
:token-id="tokenId"
:token="token"
:target-url="form.fields.targetUrl.value"
@success="onValidationSuccess"
/>
</gl-collapse>
</template>
<hr /> <hr />
<div class="gl-mt-6 gl-pt-6"> <div class="gl-mt-6 gl-pt-6">
...@@ -443,7 +225,6 @@ export default { ...@@ -443,7 +225,6 @@ export default {
variant="success" variant="success"
class="js-no-auto-disable" class="js-no-auto-disable"
data-testid="dast-site-profile-form-submit-button" data-testid="dast-site-profile-form-submit-button"
:disabled="isSubmitDisabled"
:loading="isLoading" :loading="isLoading"
> >
{{ s__('DastProfiles|Save profile') }} {{ s__('DastProfiles|Save profile') }}
......
...@@ -8413,9 +8413,6 @@ msgstr "" ...@@ -8413,9 +8413,6 @@ msgstr ""
msgid "DastProfiles|Copy HTTP header to clipboard" msgid "DastProfiles|Copy HTTP header to clipboard"
msgstr "" msgstr ""
msgid "DastProfiles|Could not create site validation token. Please refresh the page, or try again later."
msgstr ""
msgid "DastProfiles|Could not create the scanner profile. Please try again." msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "" msgstr ""
...@@ -8440,9 +8437,6 @@ msgstr "" ...@@ -8440,9 +8437,6 @@ msgstr ""
msgid "DastProfiles|Could not fetch site profiles. Please refresh the page, or try again later." msgid "DastProfiles|Could not fetch site profiles. Please refresh the page, or try again later."
msgstr "" msgstr ""
msgid "DastProfiles|Could not retrieve site validation status. Please refresh the page, or try again later."
msgstr ""
msgid "DastProfiles|Could not update the scanner profile. Please try again." msgid "DastProfiles|Could not update the scanner profile. Please try again."
msgstr "" msgstr ""
...@@ -8557,9 +8551,6 @@ msgstr "" ...@@ -8557,9 +8551,6 @@ msgstr ""
msgid "DastProfiles|Site is not validated yet, please follow the steps." msgid "DastProfiles|Site is not validated yet, please follow the steps."
msgstr "" msgstr ""
msgid "DastProfiles|Site must be validated to run an active scan."
msgstr ""
msgid "DastProfiles|Spider timeout" msgid "DastProfiles|Spider timeout"
msgstr "" msgstr ""
...@@ -8605,27 +8596,12 @@ msgstr "" ...@@ -8605,27 +8596,12 @@ msgstr ""
msgid "DastProfiles|Validate" msgid "DastProfiles|Validate"
msgstr "" msgstr ""
msgid "DastProfiles|Validate target site"
msgstr ""
msgid "DastProfiles|Validating..." msgid "DastProfiles|Validating..."
msgstr "" msgstr ""
msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method." msgid "DastProfiles|Validation failed, please make sure that you follow the steps above with the chosen method."
msgstr "" msgstr ""
msgid "DastProfiles|Validation failed. Please try again."
msgstr ""
msgid "DastProfiles|Validation is in progress..."
msgstr ""
msgid "DastProfiles|Validation must be turned off to change the target URL"
msgstr ""
msgid "DastProfiles|Validation succeeded. Both active and passive scans can be run against the target site."
msgstr ""
msgid "Data is still calculating..." msgid "Data is still calculating..."
msgstr "" 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