diff options
Diffstat (limited to 'app/assets/javascripts/security_configuration/components')
5 files changed, 315 insertions, 0 deletions
diff --git a/app/assets/javascripts/security_configuration/components/app.vue b/app/assets/javascripts/security_configuration/components/app.vue new file mode 100644 index 00000000000..513a7353d28 --- /dev/null +++ b/app/assets/javascripts/security_configuration/components/app.vue @@ -0,0 +1,23 @@ +<script> +import ConfigurationTable from './configuration_table.vue'; + +export default { + components: { + ConfigurationTable, + }, +}; +</script> + +<template> + <article> + <header> + <h4 class="gl-my-5"> + {{ __('Security Configuration') }} + </h4> + <h5 class="gl-font-lg gl-mt-7"> + {{ s__('SecurityConfiguration|Testing & Compliance') }} + </h5> + </header> + <configuration-table /> + </article> +</template> diff --git a/app/assets/javascripts/security_configuration/components/configuration_table.vue b/app/assets/javascripts/security_configuration/components/configuration_table.vue new file mode 100644 index 00000000000..9475cc1781f --- /dev/null +++ b/app/assets/javascripts/security_configuration/components/configuration_table.vue @@ -0,0 +1,97 @@ +<script> +import { GlLink, GlSprintf, GlTable, GlAlert } from '@gitlab/ui'; +import { s__, sprintf } from '~/locale'; +import { + REPORT_TYPE_SAST, + REPORT_TYPE_DAST, + REPORT_TYPE_DEPENDENCY_SCANNING, + REPORT_TYPE_CONTAINER_SCANNING, + REPORT_TYPE_COVERAGE_FUZZING, + REPORT_TYPE_LICENSE_COMPLIANCE, +} from '~/vue_shared/security_reports/constants'; +import { features } from './features_constants'; +import ManageSast from './manage_sast.vue'; +import Upgrade from './upgrade.vue'; + +const borderClasses = 'gl-border-b-1! gl-border-b-solid! gl-border-gray-100!'; +const thClass = `gl-text-gray-900 gl-bg-transparent! ${borderClasses}`; + +export default { + components: { + GlLink, + GlSprintf, + GlTable, + GlAlert, + }, + data: () => ({ + features, + errorMessage: '', + }), + methods: { + getFeatureDocumentationLinkLabel(item) { + return sprintf(s__('SecurityConfiguration|Feature documentation for %{featureName}'), { + featureName: item.name, + }); + }, + onError(value) { + this.errorMessage = value; + }, + getComponentForItem(item) { + const COMPONENTS = { + [REPORT_TYPE_SAST]: ManageSast, + [REPORT_TYPE_DAST]: Upgrade, + [REPORT_TYPE_DEPENDENCY_SCANNING]: Upgrade, + [REPORT_TYPE_CONTAINER_SCANNING]: Upgrade, + [REPORT_TYPE_COVERAGE_FUZZING]: Upgrade, + [REPORT_TYPE_LICENSE_COMPLIANCE]: Upgrade, + }; + + return COMPONENTS[item.type]; + }, + }, + table: { + fields: [ + { + key: 'feature', + label: s__('SecurityConfiguration|Security Control'), + thClass, + }, + { + key: 'manage', + label: s__('SecurityConfiguration|Manage'), + thClass, + }, + ], + items: features, + }, +}; +</script> + +<template> + <div> + <gl-alert v-if="errorMessage" variant="danger" :dismissible="false"> + {{ errorMessage }} + </gl-alert> + <gl-table :items="$options.table.items" :fields="$options.table.fields" stacked="md"> + <template #cell(feature)="{ item }"> + <div class="gl-text-gray-900"> + {{ item.name }} + </div> + <div> + {{ item.description }} + <gl-link + target="_blank" + :href="item.link" + :aria-label="getFeatureDocumentationLinkLabel(item)" + > + {{ s__('SecurityConfiguration|More information') }} + </gl-link> + </div> + </template> + + <template #cell(manage)="{ item }"> + <component :is="getComponentForItem(item)" :data-testid="item.type" @error="onError" /> + </template> + </gl-table> + </div> +</template> diff --git a/app/assets/javascripts/security_configuration/components/features_constants.js b/app/assets/javascripts/security_configuration/components/features_constants.js new file mode 100644 index 00000000000..d846a2761d9 --- /dev/null +++ b/app/assets/javascripts/security_configuration/components/features_constants.js @@ -0,0 +1,112 @@ +import { helpPagePath } from '~/helpers/help_page_helper'; +import { s__ } from '~/locale'; + +import { + REPORT_TYPE_SAST, + REPORT_TYPE_DAST, + REPORT_TYPE_SECRET_DETECTION, + REPORT_TYPE_DEPENDENCY_SCANNING, + REPORT_TYPE_CONTAINER_SCANNING, + REPORT_TYPE_COVERAGE_FUZZING, + REPORT_TYPE_LICENSE_COMPLIANCE, +} from '~/vue_shared/security_reports/constants'; + +/** + * Translations & helpPagePaths for Static Security Configuration Page + */ +export const SAST_NAME = s__('Static Application Security Testing (SAST)'); +export const SAST_DESCRIPTION = s__('Analyze your source code for known vulnerabilities.'); +export const SAST_HELP_PATH = helpPagePath('user/application_security/sast/index'); + +export const DAST_NAME = s__('Dynamic Application Security Testing (DAST)'); +export const DAST_DESCRIPTION = s__('Analyze a review version of your web application.'); +export const DAST_HELP_PATH = helpPagePath('user/application_security/dast/index'); + +export const SECRET_DETECTION_NAME = s__('Secret Detection'); +export const SECRET_DETECTION_DESCRIPTION = s__( + 'Analyze your source code and git history for secrets.', +); +export const SECRET_DETECTION_HELP_PATH = helpPagePath( + 'user/application_security/secret_detection/index', +); + +export const DEPENDENCY_SCANNING_NAME = s__('Dependency Scanning'); +export const DEPENDENCY_SCANNING_DESCRIPTION = s__( + 'Analyze your dependencies for known vulnerabilities.', +); +export const DEPENDENCY_SCANNING_HELP_PATH = helpPagePath( + 'user/application_security/dependency_scanning/index', +); + +export const CONTAINER_SCANNING_NAME = s__('Container Scanning'); +export const CONTAINER_SCANNING_DESCRIPTION = s__( + 'Check your Docker images for known vulnerabilities.', +); +export const CONTAINER_SCANNING_HELP_PATH = helpPagePath( + 'user/application_security/container_scanning/index', +); + +export const COVERAGE_FUZZING_NAME = s__('Coverage Fuzzing'); +export const COVERAGE_FUZZING_DESCRIPTION = s__( + 'Find bugs in your code with coverage-guided fuzzing.', +); +export const COVERAGE_FUZZING_HELP_PATH = helpPagePath( + 'user/application_security/coverage_fuzzing/index', +); + +export const LICENSE_COMPLIANCE_NAME = s__('License Compliance'); +export const LICENSE_COMPLIANCE_DESCRIPTION = s__( + 'Search your project dependencies for their licenses and apply policies.', +); +export const LICENSE_COMPLIANCE_HELP_PATH = helpPagePath( + 'user/compliance/license_compliance/index', +); + +export const UPGRADE_CTA = s__( + 'SecurityConfiguration|Available with %{linkStart}upgrade or free trial%{linkEnd}', +); + +export const features = [ + { + name: SAST_NAME, + description: SAST_DESCRIPTION, + helpPath: SAST_HELP_PATH, + type: REPORT_TYPE_SAST, + }, + { + name: DAST_NAME, + description: DAST_DESCRIPTION, + helpPath: DAST_HELP_PATH, + type: REPORT_TYPE_DAST, + }, + { + name: SECRET_DETECTION_NAME, + description: SECRET_DETECTION_DESCRIPTION, + helpPath: SECRET_DETECTION_HELP_PATH, + type: REPORT_TYPE_SECRET_DETECTION, + }, + { + name: DEPENDENCY_SCANNING_NAME, + description: DEPENDENCY_SCANNING_DESCRIPTION, + helpPath: DEPENDENCY_SCANNING_HELP_PATH, + type: REPORT_TYPE_DEPENDENCY_SCANNING, + }, + { + name: CONTAINER_SCANNING_NAME, + description: CONTAINER_SCANNING_DESCRIPTION, + helpPath: CONTAINER_SCANNING_HELP_PATH, + type: REPORT_TYPE_CONTAINER_SCANNING, + }, + { + name: COVERAGE_FUZZING_NAME, + description: COVERAGE_FUZZING_DESCRIPTION, + helpPath: COVERAGE_FUZZING_HELP_PATH, + type: REPORT_TYPE_COVERAGE_FUZZING, + }, + { + name: LICENSE_COMPLIANCE_NAME, + description: LICENSE_COMPLIANCE_DESCRIPTION, + helpPath: LICENSE_COMPLIANCE_HELP_PATH, + type: REPORT_TYPE_LICENSE_COMPLIANCE, + }, +]; diff --git a/app/assets/javascripts/security_configuration/components/manage_sast.vue b/app/assets/javascripts/security_configuration/components/manage_sast.vue new file mode 100644 index 00000000000..5169096d563 --- /dev/null +++ b/app/assets/javascripts/security_configuration/components/manage_sast.vue @@ -0,0 +1,57 @@ +<script> +import { GlButton } from '@gitlab/ui'; +import { redirectTo } from '~/lib/utils/url_utility'; +import { s__ } from '~/locale'; +import configureSastMutation from '~/security_configuration/graphql/configure_sast.mutation.graphql'; + +export default { + components: { + GlButton, + }, + inject: { + projectPath: { + from: 'projectPath', + default: '', + }, + }, + data: () => ({ + isLoading: false, + }), + methods: { + async mutate() { + this.isLoading = true; + try { + const { data } = await this.$apollo.mutate({ + mutation: configureSastMutation, + variables: { + input: { + projectPath: this.projectPath, + configuration: { global: [], pipeline: [], analyzers: [] }, + }, + }, + }); + const { errors, successPath } = data.configureSast; + + if (errors.length > 0) { + throw new Error(errors[0]); + } + + if (!successPath) { + throw new Error(s__('SecurityConfiguration|SAST merge request creation mutation failed')); + } + + redirectTo(successPath); + } catch (e) { + this.$emit('error', e.message); + this.isLoading = false; + } + }, + }, +}; +</script> + +<template> + <gl-button :loading="isLoading" variant="success" category="secondary" @click="mutate">{{ + s__('SecurityConfiguration|Configure via Merge Request') + }}</gl-button> +</template> diff --git a/app/assets/javascripts/security_configuration/components/upgrade.vue b/app/assets/javascripts/security_configuration/components/upgrade.vue new file mode 100644 index 00000000000..166ee4ff194 --- /dev/null +++ b/app/assets/javascripts/security_configuration/components/upgrade.vue @@ -0,0 +1,26 @@ +<script> +import { GlLink, GlSprintf } from '@gitlab/ui'; +import { UPGRADE_CTA } from './features_constants'; + +export default { + components: { + GlLink, + GlSprintf, + }, + i18n: { + UPGRADE_CTA, + }, +}; +</script> + +<template> + <span> + <gl-sprintf :message="$options.i18n.UPGRADE_CTA"> + <template #link="{ content }"> + <gl-link target="_blank" href="https://about.gitlab.com/pricing/"> + {{ content }} + </gl-link> + </template> + </gl-sprintf> + </span> +</template> |