From 26e3acd2a6558ec0e9ba3c17a5e0261522b510ff Mon Sep 17 00:00:00 2001 From: Jannik Lehmann <jlehmann@gitlab.com> Date: Fri, 6 Aug 2021 21:10:16 +0000 Subject: [PATCH] Remove security configuration page feature flags --- .../projects/security/configuration/index.js | 4 +- .../security_configuration/components/app.vue | 211 ++++++++++++++++- .../components/configuration_table.vue | 109 --------- .../components/constants.js | 70 +----- .../components/redesigned_app.vue | 216 ------------------ .../components/upgrade.vue | 32 --- .../security_configuration/index.js | 39 +--- .../security/configuration_controller.rb | 4 - .../security/configuration/show.html.haml | 3 +- .../security_configuration_redesign.yml | 8 - .../security_configuration_redesign_ee.yml | 8 - .../configuration/index.md | 122 +++------- .../projects/security/configuration/index.js | 13 +- .../security_configuration/components/app.vue | 162 ------------- .../components/auto_fix_settings.vue | 138 ----------- .../components/configuration_table.vue | 118 ---------- .../components/feature_status.vue | 30 --- .../components/manage_dast_profiles.vue | 21 -- .../components/manage_feature.vue | 39 ---- .../components/manage_generic.vue | 42 ---- .../components/status_dast_profiles.vue | 13 -- .../components/status_generic.vue | 36 --- .../components/status_view_history.vue | 46 ---- .../security_configuration/index.js | 64 ------ .../security/configuration_controller.rb | 4 - .../security/configuration/show.html.haml | 3 +- .../user_views_security_configuration_spec.rb | 86 +------ .../components/app_spec.js | 185 --------------- .../components/auto_fix_settings_spec.js | 178 --------------- .../components/configuration_table_spec.js | 85 ------- .../components/feature_status_spec.js | 75 ------ .../components/helpers.js | 11 - .../components/manage_dast_profiles_spec.js | 27 --- .../components/manage_feature_spec.js | 95 -------- .../components/manage_generic_spec.js | 49 ---- .../components/status_dast_profiles_spec.js | 24 -- .../components/status_generic_spec.js | 37 --- .../components/status_view_history_spec.js | 60 ----- locale/gitlab.pot | 63 ----- .../security_configuration/app_spec.js | 27 --- .../{redesigned_app_spec.js => app_spec.js} | 10 +- .../configuration_table_spec.js | 52 ----- .../security_configuration/upgrade_spec.js | 30 --- 43 files changed, 255 insertions(+), 2394 deletions(-) delete mode 100644 app/assets/javascripts/security_configuration/components/configuration_table.vue delete mode 100644 app/assets/javascripts/security_configuration/components/redesigned_app.vue delete mode 100644 app/assets/javascripts/security_configuration/components/upgrade.vue delete mode 100644 config/feature_flags/development/security_configuration_redesign.yml delete mode 100644 config/feature_flags/development/security_configuration_redesign_ee.yml delete mode 100644 ee/app/assets/javascripts/security_configuration/components/app.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/auto_fix_settings.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/configuration_table.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/feature_status.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/manage_dast_profiles.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/manage_feature.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/manage_generic.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/status_dast_profiles.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/status_generic.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/components/status_view_history.vue delete mode 100644 ee/app/assets/javascripts/security_configuration/index.js delete mode 100644 ee/spec/frontend/security_configuration/components/app_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/auto_fix_settings_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/configuration_table_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/feature_status_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/helpers.js delete mode 100644 ee/spec/frontend/security_configuration/components/manage_dast_profiles_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/manage_feature_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/manage_generic_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/status_dast_profiles_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/status_generic_spec.js delete mode 100644 ee/spec/frontend/security_configuration/components/status_view_history_spec.js delete mode 100644 spec/frontend/security_configuration/app_spec.js rename spec/frontend/security_configuration/components/{redesigned_app_spec.js => app_spec.js} (97%) delete mode 100644 spec/frontend/security_configuration/configuration_table_spec.js delete mode 100644 spec/frontend/security_configuration/upgrade_spec.js diff --git a/app/assets/javascripts/pages/projects/security/configuration/index.js b/app/assets/javascripts/pages/projects/security/configuration/index.js index 8bba3d7af5420..5f801501b2f5f 100644 --- a/app/assets/javascripts/pages/projects/security/configuration/index.js +++ b/app/assets/javascripts/pages/projects/security/configuration/index.js @@ -1,3 +1,3 @@ -import { initCESecurityConfiguration } from '~/security_configuration'; +import { initSecurityConfiguration } from '~/security_configuration'; -initCESecurityConfiguration(document.querySelector('#js-security-configuration-static')); +initSecurityConfiguration(document.querySelector('#js-security-configuration-static')); diff --git a/app/assets/javascripts/security_configuration/components/app.vue b/app/assets/javascripts/security_configuration/components/app.vue index 513a7353d28c5..6c70a8c33dbae 100644 --- a/app/assets/javascripts/security_configuration/components/app.vue +++ b/app/assets/javascripts/security_configuration/components/app.vue @@ -1,23 +1,216 @@ <script> -import ConfigurationTable from './configuration_table.vue'; +import { GlTab, GlTabs, GlSprintf, GlLink } from '@gitlab/ui'; +import { __, s__ } from '~/locale'; +import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; +import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue'; +import AutoDevOpsAlert from './auto_dev_ops_alert.vue'; +import AutoDevOpsEnabledAlert from './auto_dev_ops_enabled_alert.vue'; +import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY } from './constants'; +import FeatureCard from './feature_card.vue'; +import SectionLayout from './section_layout.vue'; +import UpgradeBanner from './upgrade_banner.vue'; + +export const i18n = { + compliance: s__('SecurityConfiguration|Compliance'), + configurationHistory: s__('SecurityConfiguration|Configuration history'), + securityTesting: s__('SecurityConfiguration|Security testing'), + latestPipelineDescription: s__( + `SecurityConfiguration|The status of the tools only applies to the + default branch and is based on the %{linkStart}latest pipeline%{linkEnd}.`, + ), + description: s__( + `SecurityConfiguration|Once you've enabled a scan for the default branch, + any subsequent feature branch you create will include the scan.`, + ), + securityConfiguration: __('Security Configuration'), +}; export default { + i18n, components: { - ConfigurationTable, + AutoDevOpsAlert, + AutoDevOpsEnabledAlert, + FeatureCard, + GlLink, + GlSprintf, + GlTab, + GlTabs, + LocalStorageSync, + SectionLayout, + UpgradeBanner, + UserCalloutDismisser, + }, + inject: ['projectPath'], + props: { + augmentedSecurityFeatures: { + type: Array, + required: true, + }, + augmentedComplianceFeatures: { + type: Array, + required: true, + }, + gitlabCiPresent: { + type: Boolean, + required: false, + default: false, + }, + autoDevopsEnabled: { + type: Boolean, + required: false, + default: false, + }, + canEnableAutoDevops: { + type: Boolean, + required: false, + default: false, + }, + gitlabCiHistoryPath: { + type: String, + required: false, + default: '', + }, + latestPipelinePath: { + type: String, + required: false, + default: '', + }, + }, + data() { + return { + autoDevopsEnabledAlertDismissedProjects: [], + }; + }, + computed: { + canUpgrade() { + return [...this.augmentedSecurityFeatures, ...this.augmentedComplianceFeatures].some( + ({ available }) => !available, + ); + }, + canViewCiHistory() { + return Boolean(this.gitlabCiPresent && this.gitlabCiHistoryPath); + }, + shouldShowDevopsAlert() { + return !this.autoDevopsEnabled && !this.gitlabCiPresent && this.canEnableAutoDevops; + }, + shouldShowAutoDevopsEnabledAlert() { + return ( + this.autoDevopsEnabled && + !this.autoDevopsEnabledAlertDismissedProjects.includes(this.projectPath) + ); + }, + }, + methods: { + dismissAutoDevopsEnabledAlert() { + const dismissedProjects = new Set(this.autoDevopsEnabledAlertDismissedProjects); + dismissedProjects.add(this.projectPath); + this.autoDevopsEnabledAlertDismissedProjects = Array.from(dismissedProjects); + }, }, + autoDevopsEnabledAlertStorageKey: AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY, }; </script> <template> <article> + <local-storage-sync + v-model="autoDevopsEnabledAlertDismissedProjects" + :storage-key="$options.autoDevopsEnabledAlertStorageKey" + as-json + /> + + <user-callout-dismisser + v-if="shouldShowDevopsAlert" + feature-name="security_configuration_devops_alert" + > + <template #default="{ dismiss, shouldShowCallout }"> + <auto-dev-ops-alert v-if="shouldShowCallout" class="gl-mt-3" @dismiss="dismiss" /> + </template> + </user-callout-dismisser> <header> - <h4 class="gl-my-5"> - {{ __('Security Configuration') }} - </h4> - <h5 class="gl-font-lg gl-mt-7"> - {{ s__('SecurityConfiguration|Testing & Compliance') }} - </h5> + <h1 class="gl-font-size-h1">{{ $options.i18n.securityConfiguration }}</h1> </header> - <configuration-table /> + <user-callout-dismisser v-if="canUpgrade" feature-name="security_configuration_upgrade_banner"> + <template #default="{ dismiss, shouldShowCallout }"> + <upgrade-banner v-if="shouldShowCallout" @close="dismiss" /> + </template> + </user-callout-dismisser> + + <gl-tabs content-class="gl-pt-0"> + <gl-tab data-testid="security-testing-tab" :title="$options.i18n.securityTesting"> + <auto-dev-ops-enabled-alert + v-if="shouldShowAutoDevopsEnabledAlert" + class="gl-mt-3" + @dismiss="dismissAutoDevopsEnabledAlert" + /> + + <section-layout :heading="$options.i18n.securityTesting"> + <template #description> + <p> + <span data-testid="latest-pipeline-info-security"> + <gl-sprintf + v-if="latestPipelinePath" + :message="$options.i18n.latestPipelineDescription" + > + <template #link="{ content }"> + <gl-link :href="latestPipelinePath">{{ content }}</gl-link> + </template> + </gl-sprintf> + </span> + + {{ $options.i18n.description }} + </p> + <p v-if="canViewCiHistory"> + <gl-link data-testid="security-view-history-link" :href="gitlabCiHistoryPath">{{ + $options.i18n.configurationHistory + }}</gl-link> + </p> + </template> + + <template #features> + <feature-card + v-for="feature in augmentedSecurityFeatures" + :key="feature.type" + data-testid="security-testing-card" + :feature="feature" + class="gl-mb-6" + /> + </template> + </section-layout> + </gl-tab> + <gl-tab data-testid="compliance-testing-tab" :title="$options.i18n.compliance"> + <section-layout :heading="$options.i18n.compliance"> + <template #description> + <p> + <span data-testid="latest-pipeline-info-compliance"> + <gl-sprintf + v-if="latestPipelinePath" + :message="$options.i18n.latestPipelineDescription" + > + <template #link="{ content }"> + <gl-link :href="latestPipelinePath">{{ content }}</gl-link> + </template> + </gl-sprintf> + </span> + + {{ $options.i18n.description }} + </p> + <p v-if="canViewCiHistory"> + <gl-link data-testid="compliance-view-history-link" :href="gitlabCiHistoryPath">{{ + $options.i18n.configurationHistory + }}</gl-link> + </p> + </template> + <template #features> + <feature-card + v-for="feature in augmentedComplianceFeatures" + :key="feature.type" + :feature="feature" + class="gl-mb-6" + /> + </template> + </section-layout> + </gl-tab> + </gl-tabs> </article> </template> diff --git a/app/assets/javascripts/security_configuration/components/configuration_table.vue b/app/assets/javascripts/security_configuration/components/configuration_table.vue deleted file mode 100644 index 7f250bf1365be..0000000000000 --- a/app/assets/javascripts/security_configuration/components/configuration_table.vue +++ /dev/null @@ -1,109 +0,0 @@ -<script> -import { GlLink, GlTable, GlAlert } from '@gitlab/ui'; -import { s__, sprintf } from '~/locale'; -import ManageViaMR from '~/vue_shared/security_configuration/components/manage_via_mr.vue'; -import { - REPORT_TYPE_SAST, - REPORT_TYPE_DAST, - REPORT_TYPE_DAST_PROFILES, - REPORT_TYPE_DEPENDENCY_SCANNING, - REPORT_TYPE_CONTAINER_SCANNING, - REPORT_TYPE_CLUSTER_IMAGE_SCANNING, - REPORT_TYPE_COVERAGE_FUZZING, - REPORT_TYPE_API_FUZZING, - REPORT_TYPE_LICENSE_COMPLIANCE, -} from '~/vue_shared/security_reports/constants'; - -import { scanners } from './constants'; -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, - GlTable, - GlAlert, - }, - data() { - return { - 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]: ManageViaMR, - [REPORT_TYPE_DAST]: Upgrade, - [REPORT_TYPE_DAST_PROFILES]: Upgrade, - [REPORT_TYPE_DEPENDENCY_SCANNING]: Upgrade, - [REPORT_TYPE_CONTAINER_SCANNING]: Upgrade, - [REPORT_TYPE_CLUSTER_IMAGE_SCANNING]: Upgrade, - [REPORT_TYPE_COVERAGE_FUZZING]: Upgrade, - [REPORT_TYPE_API_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: scanners, - }, -}; -</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" - data-testid="help-link" - :href="item.helpPath" - :aria-label="getFeatureDocumentationLinkLabel(item)" - > - {{ s__('SecurityConfiguration|More information') }} - </gl-link> - </div> - </template> - - <template #cell(manage)="{ item }"> - <component - :is="getComponentForItem(item)" - :feature="item" - :data-testid="item.type" - @error="onError" - /> - </template> - </gl-table> - </div> -</template> diff --git a/app/assets/javascripts/security_configuration/components/constants.js b/app/assets/javascripts/security_configuration/components/constants.js index fda18fb8009cc..44bb1bb1af8bb 100644 --- a/app/assets/javascripts/security_configuration/components/constants.js +++ b/app/assets/javascripts/security_configuration/components/constants.js @@ -18,8 +18,9 @@ import configureSastMutation from '../graphql/configure_sast.mutation.graphql'; import configureSecretDetectionMutation from '../graphql/configure_secret_detection.mutation.graphql'; /** - * Translations & helpPagePaths for Static Security Configuration Page + * Translations & helpPagePaths for Security Configuration Page */ + export const SAST_NAME = __('Static Application Security Testing (SAST)'); export const SAST_SHORT_NAME = s__('ciReport|SAST'); export const SAST_DESCRIPTION = __('Analyze your source code for known vulnerabilities.'); @@ -115,73 +116,6 @@ 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 scanners = [ - { - 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: DAST_PROFILES_NAME, - description: DAST_PROFILES_DESCRIPTION, - helpPath: DAST_PROFILES_HELP_PATH, - type: REPORT_TYPE_DAST_PROFILES, - }, - { - 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: CLUSTER_IMAGE_SCANNING_NAME, - description: CLUSTER_IMAGE_SCANNING_DESCRIPTION, - helpPath: CLUSTER_IMAGE_SCANNING_HELP_PATH, - type: REPORT_TYPE_CLUSTER_IMAGE_SCANNING, - }, - { - name: SECRET_DETECTION_NAME, - description: SECRET_DETECTION_DESCRIPTION, - helpPath: SECRET_DETECTION_HELP_PATH, - type: REPORT_TYPE_SECRET_DETECTION, - }, - { - name: COVERAGE_FUZZING_NAME, - description: COVERAGE_FUZZING_DESCRIPTION, - helpPath: COVERAGE_FUZZING_HELP_PATH, - type: REPORT_TYPE_COVERAGE_FUZZING, - }, - { - name: API_FUZZING_NAME, - description: API_FUZZING_DESCRIPTION, - helpPath: API_FUZZING_HELP_PATH, - type: REPORT_TYPE_API_FUZZING, - }, - { - name: LICENSE_COMPLIANCE_NAME, - description: LICENSE_COMPLIANCE_DESCRIPTION, - helpPath: LICENSE_COMPLIANCE_HELP_PATH, - type: REPORT_TYPE_LICENSE_COMPLIANCE, - }, -]; - export const securityFeatures = [ { name: SAST_NAME, diff --git a/app/assets/javascripts/security_configuration/components/redesigned_app.vue b/app/assets/javascripts/security_configuration/components/redesigned_app.vue deleted file mode 100644 index 6c70a8c33dbae..0000000000000 --- a/app/assets/javascripts/security_configuration/components/redesigned_app.vue +++ /dev/null @@ -1,216 +0,0 @@ -<script> -import { GlTab, GlTabs, GlSprintf, GlLink } from '@gitlab/ui'; -import { __, s__ } from '~/locale'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; -import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue'; -import AutoDevOpsAlert from './auto_dev_ops_alert.vue'; -import AutoDevOpsEnabledAlert from './auto_dev_ops_enabled_alert.vue'; -import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY } from './constants'; -import FeatureCard from './feature_card.vue'; -import SectionLayout from './section_layout.vue'; -import UpgradeBanner from './upgrade_banner.vue'; - -export const i18n = { - compliance: s__('SecurityConfiguration|Compliance'), - configurationHistory: s__('SecurityConfiguration|Configuration history'), - securityTesting: s__('SecurityConfiguration|Security testing'), - latestPipelineDescription: s__( - `SecurityConfiguration|The status of the tools only applies to the - default branch and is based on the %{linkStart}latest pipeline%{linkEnd}.`, - ), - description: s__( - `SecurityConfiguration|Once you've enabled a scan for the default branch, - any subsequent feature branch you create will include the scan.`, - ), - securityConfiguration: __('Security Configuration'), -}; - -export default { - i18n, - components: { - AutoDevOpsAlert, - AutoDevOpsEnabledAlert, - FeatureCard, - GlLink, - GlSprintf, - GlTab, - GlTabs, - LocalStorageSync, - SectionLayout, - UpgradeBanner, - UserCalloutDismisser, - }, - inject: ['projectPath'], - props: { - augmentedSecurityFeatures: { - type: Array, - required: true, - }, - augmentedComplianceFeatures: { - type: Array, - required: true, - }, - gitlabCiPresent: { - type: Boolean, - required: false, - default: false, - }, - autoDevopsEnabled: { - type: Boolean, - required: false, - default: false, - }, - canEnableAutoDevops: { - type: Boolean, - required: false, - default: false, - }, - gitlabCiHistoryPath: { - type: String, - required: false, - default: '', - }, - latestPipelinePath: { - type: String, - required: false, - default: '', - }, - }, - data() { - return { - autoDevopsEnabledAlertDismissedProjects: [], - }; - }, - computed: { - canUpgrade() { - return [...this.augmentedSecurityFeatures, ...this.augmentedComplianceFeatures].some( - ({ available }) => !available, - ); - }, - canViewCiHistory() { - return Boolean(this.gitlabCiPresent && this.gitlabCiHistoryPath); - }, - shouldShowDevopsAlert() { - return !this.autoDevopsEnabled && !this.gitlabCiPresent && this.canEnableAutoDevops; - }, - shouldShowAutoDevopsEnabledAlert() { - return ( - this.autoDevopsEnabled && - !this.autoDevopsEnabledAlertDismissedProjects.includes(this.projectPath) - ); - }, - }, - methods: { - dismissAutoDevopsEnabledAlert() { - const dismissedProjects = new Set(this.autoDevopsEnabledAlertDismissedProjects); - dismissedProjects.add(this.projectPath); - this.autoDevopsEnabledAlertDismissedProjects = Array.from(dismissedProjects); - }, - }, - autoDevopsEnabledAlertStorageKey: AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY, -}; -</script> - -<template> - <article> - <local-storage-sync - v-model="autoDevopsEnabledAlertDismissedProjects" - :storage-key="$options.autoDevopsEnabledAlertStorageKey" - as-json - /> - - <user-callout-dismisser - v-if="shouldShowDevopsAlert" - feature-name="security_configuration_devops_alert" - > - <template #default="{ dismiss, shouldShowCallout }"> - <auto-dev-ops-alert v-if="shouldShowCallout" class="gl-mt-3" @dismiss="dismiss" /> - </template> - </user-callout-dismisser> - <header> - <h1 class="gl-font-size-h1">{{ $options.i18n.securityConfiguration }}</h1> - </header> - <user-callout-dismisser v-if="canUpgrade" feature-name="security_configuration_upgrade_banner"> - <template #default="{ dismiss, shouldShowCallout }"> - <upgrade-banner v-if="shouldShowCallout" @close="dismiss" /> - </template> - </user-callout-dismisser> - - <gl-tabs content-class="gl-pt-0"> - <gl-tab data-testid="security-testing-tab" :title="$options.i18n.securityTesting"> - <auto-dev-ops-enabled-alert - v-if="shouldShowAutoDevopsEnabledAlert" - class="gl-mt-3" - @dismiss="dismissAutoDevopsEnabledAlert" - /> - - <section-layout :heading="$options.i18n.securityTesting"> - <template #description> - <p> - <span data-testid="latest-pipeline-info-security"> - <gl-sprintf - v-if="latestPipelinePath" - :message="$options.i18n.latestPipelineDescription" - > - <template #link="{ content }"> - <gl-link :href="latestPipelinePath">{{ content }}</gl-link> - </template> - </gl-sprintf> - </span> - - {{ $options.i18n.description }} - </p> - <p v-if="canViewCiHistory"> - <gl-link data-testid="security-view-history-link" :href="gitlabCiHistoryPath">{{ - $options.i18n.configurationHistory - }}</gl-link> - </p> - </template> - - <template #features> - <feature-card - v-for="feature in augmentedSecurityFeatures" - :key="feature.type" - data-testid="security-testing-card" - :feature="feature" - class="gl-mb-6" - /> - </template> - </section-layout> - </gl-tab> - <gl-tab data-testid="compliance-testing-tab" :title="$options.i18n.compliance"> - <section-layout :heading="$options.i18n.compliance"> - <template #description> - <p> - <span data-testid="latest-pipeline-info-compliance"> - <gl-sprintf - v-if="latestPipelinePath" - :message="$options.i18n.latestPipelineDescription" - > - <template #link="{ content }"> - <gl-link :href="latestPipelinePath">{{ content }}</gl-link> - </template> - </gl-sprintf> - </span> - - {{ $options.i18n.description }} - </p> - <p v-if="canViewCiHistory"> - <gl-link data-testid="compliance-view-history-link" :href="gitlabCiHistoryPath">{{ - $options.i18n.configurationHistory - }}</gl-link> - </p> - </template> - <template #features> - <feature-card - v-for="feature in augmentedComplianceFeatures" - :key="feature.type" - :feature="feature" - class="gl-mb-6" - /> - </template> - </section-layout> - </gl-tab> - </gl-tabs> - </article> -</template> diff --git a/app/assets/javascripts/security_configuration/components/upgrade.vue b/app/assets/javascripts/security_configuration/components/upgrade.vue deleted file mode 100644 index 2541c29224aff..0000000000000 --- a/app/assets/javascripts/security_configuration/components/upgrade.vue +++ /dev/null @@ -1,32 +0,0 @@ -<script> -import { GlLink, GlSprintf } from '@gitlab/ui'; -import { UPGRADE_CTA } from './constants'; - -export default { - components: { - GlLink, - GlSprintf, - }, - inject: { - upgradePath: { - from: 'upgradePath', - default: '#', - }, - }, - i18n: { - UPGRADE_CTA, - }, -}; -</script> - -<template> - <span> - <gl-sprintf :message="$options.i18n.UPGRADE_CTA"> - <template #link="{ content }"> - <gl-link target="_blank" :href="upgradePath"> - {{ content }} - </gl-link> - </template> - </gl-sprintf> - </span> -</template> diff --git a/app/assets/javascripts/security_configuration/index.js b/app/assets/javascripts/security_configuration/index.js index f05bd79258e64..a8623b468f285 100644 --- a/app/assets/javascripts/security_configuration/index.js +++ b/app/assets/javascripts/security_configuration/index.js @@ -4,10 +4,13 @@ import createDefaultClient from '~/lib/graphql'; import { parseBooleanDataAttributes } from '~/lib/utils/dom_utils'; import SecurityConfigurationApp from './components/app.vue'; import { securityFeatures, complianceFeatures } from './components/constants'; -import RedesignedSecurityConfigurationApp from './components/redesigned_app.vue'; import { augmentFeatures } from './utils'; -export const initRedesignedSecurityConfiguration = (el) => { +export const initSecurityConfiguration = (el) => { + if (!el) { + return null; + } + Vue.use(VueApollo); const apolloProvider = new VueApollo({ @@ -40,7 +43,7 @@ export const initRedesignedSecurityConfiguration = (el) => { autoDevopsPath, }, render(createElement) { - return createElement(RedesignedSecurityConfigurationApp, { + return createElement(SecurityConfigurationApp, { props: { augmentedComplianceFeatures, augmentedSecurityFeatures, @@ -56,33 +59,3 @@ export const initRedesignedSecurityConfiguration = (el) => { }, }); }; - -export const initCESecurityConfiguration = (el) => { - if (!el) { - return null; - } - - if (gon.features?.securityConfigurationRedesign) { - return initRedesignedSecurityConfiguration(el); - } - - Vue.use(VueApollo); - - const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), - }); - - const { projectPath, upgradePath } = el.dataset; - - return new Vue({ - el, - apolloProvider, - provide: { - projectPath, - upgradePath, - }, - render(createElement) { - return createElement(SecurityConfigurationApp); - }, - }); -}; diff --git a/app/controllers/projects/security/configuration_controller.rb b/app/controllers/projects/security/configuration_controller.rb index 3a473bb67e096..19de157357acf 100644 --- a/app/controllers/projects/security/configuration_controller.rb +++ b/app/controllers/projects/security/configuration_controller.rb @@ -7,10 +7,6 @@ class ConfigurationController < Projects::ApplicationController feature_category :static_application_security_testing - before_action only: [:show] do - push_frontend_feature_flag(:security_configuration_redesign, project, default_enabled: :yaml) - end - def show render_403 unless can?(current_user, :read_security_configuration, project) end diff --git a/app/views/projects/security/configuration/show.html.haml b/app/views/projects/security/configuration/show.html.haml index d4a85893fa43e..e8ac572df1d0d 100644 --- a/app/views/projects/security/configuration/show.html.haml +++ b/app/views/projects/security/configuration/show.html.haml @@ -1,6 +1,5 @@ - breadcrumb_title _("Security Configuration") - page_title _("Security Configuration") -- redesign_enabled = ::Feature.enabled?(:security_configuration_redesign, @project, default_enabled: :yaml) -- @content_class = "limit-container-width" unless fluid_layout || !redesign_enabled +- @content_class = "limit-container-width" unless fluid_layout #js-security-configuration-static{ data: { project_path: @project.full_path, upgrade_path: security_upgrade_path } } diff --git a/config/feature_flags/development/security_configuration_redesign.yml b/config/feature_flags/development/security_configuration_redesign.yml deleted file mode 100644 index 16627191edcaf..0000000000000 --- a/config/feature_flags/development/security_configuration_redesign.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: security_configuration_redesign -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62285 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331614 -milestone: '14.0' -type: development -group: group::static analysis -default_enabled: false diff --git a/config/feature_flags/development/security_configuration_redesign_ee.yml b/config/feature_flags/development/security_configuration_redesign_ee.yml deleted file mode 100644 index bf981b65c7f3e..0000000000000 --- a/config/feature_flags/development/security_configuration_redesign_ee.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: security_configuration_redesign_ee -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65171 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336077 -milestone: '14.1' -type: development -group: group::analyzer frontend -default_enabled: false diff --git a/doc/user/application_security/configuration/index.md b/doc/user/application_security/configuration/index.md index 3cc88a40b6f2b..664fcd9b72fa0 100644 --- a/doc/user/application_security/configuration/index.md +++ b/doc/user/application_security/configuration/index.md @@ -11,9 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - SAST configuration was [enabled](https://gitlab.com/groups/gitlab-org/-/epics/3659) in 13.3 and [improved](https://gitlab.com/gitlab-org/gitlab/-/issues/232862) in 13.4. **(ULTIMATE)** > - DAST Profiles feature was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40474) in 13.4. **(ULTIMATE)** > - A simplified version was made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/294076) in GitLab 13.10. - -WARNING: -This feature might not be available to you. Check the **version history** note above for details. +> - [Redesigned](https://gitlab.com/gitlab-org/gitlab/-/issues/326926) in 14.2. The Security Configuration page displays what security scans are available, links to documentation and also simple enablement tools for the current project. @@ -22,35 +20,37 @@ then in the left sidebar go to **Security & Compliance > Configuration**. For each security control the page displays: -- **Security Control:** Name, description, and a documentation link. -- **Manage:** A management option or a documentation link. - -## UI redesign - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326926) in 14.0 for GitLab Free and Premium, behind a feature flag, disabled by default. -> - Enabled on GitLab.com for Free & Premium. -> - Recommended for production use. -> - It can be enabled or disabled for a single project. -> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-ui-redesign). **(FREE SELF)** -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333109) in 14.1 for GitLab Ultimate, behind a feature flag, disabled by default. -> - Disabled on GitLab.com. -> - Not recommended for production use. -> - It can be enabled or disabled for a single project. -> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-ui-redesign-for-ultimate). **(ULTIMATE SELF)** +- Its name, description and a documentation link. +- Whether or not it is available. +- A configuration button or a link to its configuration guide. -WARNING: -This feature might not be available to you. Check the **version history** note above for details. +## Security testing -The Security Configuration page has been redesigned in GitLab Free and Premium. -The same functionality exists as before, but presented in a more extensible -way. +You can configure the following security controls: -For each security control the page displays: +- Auto DevOps + - Click **Enable Auto DevOps** on the alert to enable it for the current project. For more details, see [Auto DevOps](../../../topics/autodevops/index.md). +- SAST + - Click **Enable SAST** to use SAST for the current project. For more details, see [Configure SAST in the UI](../sast/index.md#configure-sast-in-the-ui). +- DAST **(ULTIMATE)** + - Click **Enable DAST** to use DAST for the current Project. To manage the available DAST profiles used for on-demand scans Click **Manage Scans**. For more details, see [DAST on-demand scans](../dast/index.md#on-demand-scans). +- Dependency Scanning **(ULTIMATE)** + - Select **Configure via Merge Request** to create a merge request with the changes required to + enable Dependency Scanning. For more details, see [Enable Dependency Scanning via an automatic merge request](../dependency_scanning/index.md#enable-dependency-scanning-via-an-automatic-merge-request). -- Its name, description and a documentation link. -- Whether or not it is available. -- A configuration button or a link to its configuration guide. +- Container Scanning **(ULTIMATE)** + - Can be configured via `.gitlab-ci.yml`. For more details, see [Container Scanning](../../../user/application_security/container_scanning/index.md#configuration). +- Cluster Image Scanning **(ULTIMATE)** + - Can be configured via `.gitlab-ci.yml`. For more details, see [Cluster Image Scanning](../../../user/application_security/cluster_image_scanning/#configuration). +- Secret Detection + - Select **Configure via Merge Request** to create a merge request with the changes required to + enable Secret Detection. For more details, see [Enable Secret Detection via an automatic merge request](../secret_detection/index.md#enable-secret-detection-via-an-automatic-merge-request). +- API Fuzzing **(ULTIMATE)** + - Click **Enable API Fuzzing** to use API Fuzzing for the current Project. For more details, see [API Fuzzing](../../../user/application_security/api_fuzzing/index.md#enable-web-api-fuzzing). +- Coverage Fuzzing **(ULTIMATE)** + - Can be configured via `.gitlab-ci.yml`. For more details, see [Coverage Fuzzing](../../../user/application_security/coverage_fuzzing/index.md#configuration). + ## Status **(ULTIMATE)** > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20711) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6. @@ -63,71 +63,11 @@ _enabled_. If the latest pipeline used [Auto DevOps](../../../topics/autodevops/index.md), all security features are configured by default. -For SAST, click **View history** to see the `.gitlab-ci.yml` file's history. +Click **View history** to see the `.gitlab-ci.yml` file's history. -## Manage **(ULTIMATE)** +## Compliance **(ULTIMATE)** You can configure the following security controls: -- Auto DevOps - - Click **Enable Auto DevOps** to enable it for the current project. For more details, see [Auto DevOps](../../../topics/autodevops/index.md). -- SAST - - Click either **Enable** or **Configure** to use SAST for the current project. For more details, see [Configure SAST in the UI](../sast/index.md#configure-sast-in-the-ui). -- DAST Profiles - - Click **Manage** to manage the available DAST profiles used for on-demand scans. For more details, see [DAST on-demand scans](../dast/index.md#on-demand-scans). -- Secret Detection - - Select **Configure via Merge Request** to create a merge request with the changes required to - enable Secret Detection. For more details, see [Enable Secret Detection via an automatic merge request](../secret_detection/index.md#enable-secret-detection-via-an-automatic-merge-request). -- Dependency Scanning - - Select **Configure via Merge Request** to create a merge request with the changes required to - enable Dependency Scanning. For more details, see [Enable Dependency Scanning via an automatic merge request](../dependency_scanning/index.md#enable-dependency-scanning-via-an-automatic-merge-request). - -## Enable or disable UI redesign **(FREE SELF)** - -The Security Configuration redesign is under development, but is ready for -production use. It is deployed behind a feature flag that is **disabled by -default**. -[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md) can enable it. - -To enable it: - -```ruby -# For the instance -Feature.enable(:security_configuration_redesign) -# For a single project -Feature.enable(:security_configuration_redesign, Project.find(<project id>)) -``` - -To disable it: - -```ruby -# For the instance -Feature.disable(:security_configuration_redesign) -# For a single project -Feature.disable(:security_configuration_redesign, Project.find(<project id>)) -``` - -## Enable or disable UI redesign for Ultimate **(ULTIMATE SELF)** - -The Security Configuration redesign is under development, and is not ready for -production use. It is deployed behind a feature flag that is **disabled by -default**. -[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md) can enable it. - -To enable it: - -```ruby -# For the instance -Feature.enable(:security_configuration_redesign_ee) -# For a single project -Feature.enable(:security_configuration_redesign_ee, Project.find(<project id>)) -``` - -To disable it: - -```ruby -# For the instance -Feature.disable(:security_configuration_redesign_ee) -# For a single project -Feature.disable(:security_configuration_redesign_ee, Project.find(<project id>)) -``` +- License Compliance **(ULTIMATE)** + - Can be configured via `.gitlab-ci.yml`. For more details, see [License Compliance](../../../user/compliance/license_compliance/index.md#configuration). diff --git a/ee/app/assets/javascripts/pages/projects/security/configuration/index.js b/ee/app/assets/javascripts/pages/projects/security/configuration/index.js index 420c704f98133..091d4363b11b9 100644 --- a/ee/app/assets/javascripts/pages/projects/security/configuration/index.js +++ b/ee/app/assets/javascripts/pages/projects/security/configuration/index.js @@ -1,10 +1,7 @@ -import { initSecurityConfiguration } from 'ee/security_configuration'; -import { initCESecurityConfiguration } from '~/security_configuration'; +import { initSecurityConfiguration } from '~/security_configuration'; -const el = document.querySelector('#js-security-configuration'); +const el = + document.querySelector('#js-security-configuration') || + document.querySelector('#js-security-configuration-static'); -if (el) { - initSecurityConfiguration(el); -} else { - initCESecurityConfiguration(document.querySelector('#js-security-configuration-static')); -} +initSecurityConfiguration(el); diff --git a/ee/app/assets/javascripts/security_configuration/components/app.vue b/ee/app/assets/javascripts/security_configuration/components/app.vue deleted file mode 100644 index 4e63daad88a63..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/app.vue +++ /dev/null @@ -1,162 +0,0 @@ -<script> -import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui'; -import { parseBoolean } from '~/lib/utils/common_utils'; -import { s__, __ } from '~/locale'; -import { scanners } from '~/security_configuration/components/constants'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import AutoFixSettings from './auto_fix_settings.vue'; -import ConfigurationTable from './configuration_table.vue'; - -export default { - components: { - GlAlert, - GlLink, - GlSprintf, - AutoFixSettings, - LocalStorageSync, - ConfigurationTable, - }, - mixins: [glFeatureFlagsMixin()], - props: { - autoDevopsEnabled: { - type: Boolean, - required: false, - default: false, - }, - autoDevopsHelpPagePath: { - type: String, - required: true, - }, - latestPipelinePath: { - type: String, - required: false, - default: '', - }, - features: { - type: Array, - required: true, - }, - autoFixSettingsProps: { - type: Object, - required: true, - }, - gitlabCiPresent: { - type: Boolean, - required: false, - default: false, - }, - gitlabCiHistoryPath: { - type: String, - required: false, - default: '', - }, - autoDevopsPath: { - type: String, - required: false, - default: '', - }, - canEnableAutoDevops: { - type: Boolean, - required: false, - default: false, - }, - }, - data() { - return { - autoDevopsAlertDismissed: 'false', - }; - }, - computed: { - devopsMessage() { - return this.autoDevopsEnabled - ? __( - 'Several security scans are enabled because %{linkStart}Auto DevOps%{linkEnd} is enabled on this project', - ) - : __( - `The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan.`, - ); - }, - devopsUrl() { - return this.autoDevopsEnabled ? this.autoDevopsHelpPagePath : this.latestPipelinePath; - }, - shouldShowAutoDevopsAlert() { - return Boolean( - !parseBoolean(this.autoDevopsAlertDismissed) && - !this.autoDevopsEnabled && - !this.gitlabCiPresent && - this.canEnableAutoDevops, - ); - }, - featuresForDisplay() { - const featuresByType = this.features.reduce((acc, feature) => { - acc[feature.type] = feature; - return acc; - }, {}); - - return scanners.map((scanner) => { - const feature = featuresByType[scanner.type] ?? {}; - - return { - ...feature, - ...scanner, - }; - }); - }, - }, - methods: { - dismissAutoDevopsAlert() { - this.autoDevopsAlertDismissed = 'true'; - }, - }, - autoDevopsAlertMessage: s__(` - SecurityConfiguration|You can quickly enable all security scanning tools by - enabling %{linkStart}Auto DevOps%{linkEnd}.`), - autoDevopsAlertStorageKey: 'security_configuration_auto_devops_dismissed', -}; -</script> - -<template> - <article> - <header> - <h4 class="my-3">{{ __('Security Configuration') }}</h4> - <h5 class="gl-font-lg mt-5">{{ s__('SecurityConfiguration|Testing & Compliance') }}</h5> - <p> - <gl-sprintf :message="devopsMessage"> - <template #link="{ content }"> - <gl-link ref="pipelinesLink" :href="devopsUrl" target="_blank">{{ content }}</gl-link> - </template> - </gl-sprintf> - </p> - </header> - - <local-storage-sync - v-model="autoDevopsAlertDismissed" - :storage-key="$options.autoDevopsAlertStorageKey" - /> - - <gl-alert - v-if="shouldShowAutoDevopsAlert" - :title="__('Auto DevOps')" - :primary-button-text="__('Enable Auto DevOps')" - :primary-button-link="autoDevopsPath" - class="gl-mb-5" - @dismiss="dismissAutoDevopsAlert" - > - <gl-sprintf :message="$options.autoDevopsAlertMessage"> - <template #link="{ content }"> - <gl-link :href="autoDevopsHelpPagePath" v-text="content" /> - </template> - </gl-sprintf> - </gl-alert> - - <configuration-table - :features="featuresForDisplay" - :auto-devops-enabled="autoDevopsEnabled" - :gitlab-ci-present="gitlabCiPresent" - :gitlab-ci-history-path="gitlabCiHistoryPath" - /> - - <auto-fix-settings v-if="glFeatures.securityAutoFix" v-bind="autoFixSettingsProps" /> - </article> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/auto_fix_settings.vue b/ee/app/assets/javascripts/security_configuration/components/auto_fix_settings.vue deleted file mode 100644 index 35c9fcc2b01ad..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/auto_fix_settings.vue +++ /dev/null @@ -1,138 +0,0 @@ -<script> -import { GlIcon, GlLink, GlCard, GlFormCheckbox, GlSprintf } from '@gitlab/ui'; -import * as Sentry from '@sentry/browser'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; -import { __ } from '~/locale'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; - -export default { - components: { - GlIcon, - GlLink, - GlCard, - GlFormCheckbox, - GlSprintf, - }, - mixins: [glFeatureFlagsMixin()], - props: { - autoFixEnabled: { - type: Object, - required: true, - }, - autoFixHelpPath: { - type: String, - required: true, - }, - autoFixUserPath: { - type: String, - required: true, - }, - containerScanningHelpPath: { - type: String, - required: true, - }, - dependencyScanningHelpPath: { - type: String, - required: true, - }, - toggleAutofixSettingEndpoint: { - type: String, - required: true, - }, - canToggleAutoFixSettings: { - type: Boolean, - required: true, - }, - }, - data() { - // In this first iteration, the auto-fix settings is toggled for all features at once via a - // single checkbox. The line below is a temporary workaround to initialize the setting's state - // until we have distinct checkboxes for each auto-fixable feature. - const autoFixEnabled = Object.values(this.autoFixEnabled).some((enabled) => enabled); - return { - autoFixEnabledLocal: autoFixEnabled, - isChecked: autoFixEnabled, - autoFixStatusLoading: false, - }; - }, - computed: { - hasAutoFixDisabled() { - return !this.canToggleAutoFixSettings || this.autoFixStatusLoading; - }, - }, - methods: { - toggleAutoFix(enabled) { - this.autoFixStatusLoading = true; - return axios - .post(this.toggleAutofixSettingEndpoint, { - // When we have distinct checkboxes for each feature, we'll need to pass the feature being - // toggled to the API. It's not required for now as all features are being toggled at once. - feature: '', - enabled, - }) - .then(() => { - this.autoFixEnabledLocal = enabled; - this.isChecked = enabled; - }) - .catch((e) => { - Sentry.captureException(e); - createFlash({ - message: __( - 'Something went wrong while toggling auto-fix settings, please try again later.', - ), - }); - this.isChecked = !enabled; - }) - .finally(() => { - this.autoFixStatusLoading = false; - }); - }, - }, -}; -</script> - -<template> - <section> - <h4 class="gl-h4 gl-my-5"> - {{ __('Suggested Solutions') }} - <gl-link - target="_blank" - :href="autoFixHelpPath" - :aria-label="__('Suggested solutions help link')" - > - <gl-icon name="question" /> - </gl-link> - </h4> - <gl-card> - <gl-form-checkbox v-model="isChecked" :disabled="hasAutoFixDisabled" @change="toggleAutoFix"> - {{ - __('Automatically create merge requests for vulnerabilities that have fixes available.') - }} - <template #help>{{ __('Available for dependency and container scanning') }}</template> - </gl-form-checkbox> - <footer class="gl-bg-blue-100 gl-px-5 gl-py-3"> - <gl-sprintf - :message=" - __( - '%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}.', - ) - " - > - <template #containerScanningLink="{ content }"> - <gl-link :href="containerScanningHelpPath">{{ content }}</gl-link> - </template> - <template #dependencyScanningLink="{ content }"> - <gl-link :href="dependencyScanningHelpPath">{{ content }}</gl-link> - </template> - <template #securityBotLink="{ content }"> - <gl-link :href="autoFixUserPath">{{ content }}</gl-link> - </template> - <template #moreInfoLink="{ content }"> - <gl-link :href="autoFixHelpPath">{{ content }}</gl-link> - </template> - </gl-sprintf> - </footer> - </gl-card> - </section> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/configuration_table.vue b/ee/app/assets/javascripts/security_configuration/components/configuration_table.vue deleted file mode 100644 index 6e58f039a3692..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/configuration_table.vue +++ /dev/null @@ -1,118 +0,0 @@ -<script> -import { GlAlert, GlLink, GlTable } from '@gitlab/ui'; -import { s__, sprintf } from '~/locale'; -import FeatureStatus from './feature_status.vue'; -import ManageFeature from './manage_feature.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: { - GlAlert, - GlLink, - GlTable, - FeatureStatus, - ManageFeature, - }, - props: { - features: { - type: Array, - required: true, - }, - autoDevopsEnabled: { - type: Boolean, - required: false, - default: false, - }, - gitlabCiPresent: { - type: Boolean, - required: false, - default: false, - }, - gitlabCiHistoryPath: { - type: String, - required: false, - default: '', - }, - }, - data() { - return { - errorMessage: '', - }; - }, - methods: { - getFeatureDocumentationLinkLabel(item) { - return sprintf(this.$options.i18n.docsLinkLabel, { - featureName: item.name, - }); - }, - onError(value) { - this.errorMessage = value; - }, - }, - fields: [ - { - key: 'description', - label: s__('SecurityConfiguration|Security Control'), - thClass, - }, - { - key: 'status', - label: s__('SecurityConfiguration|Status'), - thClass, - }, - { - key: 'manage', - label: s__('SecurityConfiguration|Manage'), - thClass, - }, - ], - i18n: { - docsLinkLabel: s__('SecurityConfiguration|Feature documentation for %{featureName}'), - docsLinkText: s__('SecurityConfiguration|More information'), - }, -}; -</script> - -<template> - <div> - <gl-alert v-if="errorMessage" variant="danger" :dismissible="false"> - {{ errorMessage }} - </gl-alert> - <gl-table - :items="features" - :fields="$options.fields" - stacked="md" - :tbody-tr-attr="{ 'data-testid': 'security-scanner-row' }" - > - <template #cell(description)="{ item }"> - <div class="gl-text-gray-900">{{ item.name }}</div> - <div> - {{ item.description }} - <gl-link - target="_blank" - :href="item.helpPath" - :aria-label="getFeatureDocumentationLinkLabel(item)" - > - {{ $options.i18n.docsLinkText }} - </gl-link> - </div> - </template> - - <template #cell(status)="{ item }"> - <feature-status - :feature="item" - :gitlab-ci-present="gitlabCiPresent" - :gitlab-ci-history-path="gitlabCiHistoryPath" - :auto-devops-enabled="autoDevopsEnabled" - :data-qa-selector="`${item.type}_status`" - /> - </template> - - <template #cell(manage)="{ item }"> - <manage-feature :feature="item" @error="onError" /> - </template> - </gl-table> - </div> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/feature_status.vue b/ee/app/assets/javascripts/security_configuration/components/feature_status.vue deleted file mode 100644 index e2c167706a591..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/feature_status.vue +++ /dev/null @@ -1,30 +0,0 @@ -<script> -import { propsUnion } from '~/vue_shared/components/lib/utils/props_utils'; -import { - REPORT_TYPE_SAST, - REPORT_TYPE_DAST_PROFILES, - REPORT_TYPE_SECRET_DETECTION, -} from '~/vue_shared/security_reports/constants'; -import StatusDastProfiles from './status_dast_profiles.vue'; -import StatusGeneric from './status_generic.vue'; -import StatusViewHistory from './status_view_history.vue'; - -const scannerComponentMap = { - [REPORT_TYPE_SAST]: StatusViewHistory, - [REPORT_TYPE_DAST_PROFILES]: StatusDastProfiles, - [REPORT_TYPE_SECRET_DETECTION]: StatusViewHistory, -}; - -export default { - props: propsUnion([StatusGeneric, ...Object.values(scannerComponentMap)]), - computed: { - statusComponent() { - return scannerComponentMap[this.feature.type] ?? StatusGeneric; - }, - }, -}; -</script> - -<template> - <component :is="statusComponent" v-bind="$props" /> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/manage_dast_profiles.vue b/ee/app/assets/javascripts/security_configuration/components/manage_dast_profiles.vue deleted file mode 100644 index 9f14477930a54..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/manage_dast_profiles.vue +++ /dev/null @@ -1,21 +0,0 @@ -<script> -import { GlButton } from '@gitlab/ui'; - -export default { - components: { - GlButton, - }, - props: { - feature: { - type: Object, - required: true, - }, - }, -}; -</script> - -<template> - <gl-button :href="feature.configuration_path" data-testid="manage-button">{{ - s__('SecurityConfiguration|Manage') - }}</gl-button> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/manage_feature.vue b/ee/app/assets/javascripts/security_configuration/components/manage_feature.vue deleted file mode 100644 index bc12d3487a211..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/manage_feature.vue +++ /dev/null @@ -1,39 +0,0 @@ -<script> -import { propsUnion } from '~/vue_shared/components/lib/utils/props_utils'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue'; -import { - REPORT_TYPE_DAST_PROFILES, - REPORT_TYPE_DEPENDENCY_SCANNING, - REPORT_TYPE_SECRET_DETECTION, -} from '~/vue_shared/security_reports/constants'; -import ManageDastProfiles from './manage_dast_profiles.vue'; -import ManageGeneric from './manage_generic.vue'; - -const scannerComponentMap = { - [REPORT_TYPE_DAST_PROFILES]: ManageDastProfiles, - [REPORT_TYPE_DEPENDENCY_SCANNING]: ManageViaMr, - [REPORT_TYPE_SECRET_DETECTION]: ManageViaMr, -}; - -export default { - mixins: [glFeatureFlagMixin()], - props: propsUnion([ManageGeneric, ...Object.values(scannerComponentMap)]), - computed: { - filteredScannerComponentMap() { - const scannerComponentMapCopy = { ...scannerComponentMap }; - if (!this.glFeatures.secDependencyScanningUiEnable) { - delete scannerComponentMapCopy[REPORT_TYPE_DEPENDENCY_SCANNING]; - } - return scannerComponentMapCopy; - }, - manageComponent() { - return this.filteredScannerComponentMap[this.feature.type] ?? ManageGeneric; - }, - }, -}; -</script> - -<template> - <component :is="manageComponent" v-bind="$props" @error="$emit('error', $event)" /> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/manage_generic.vue b/ee/app/assets/javascripts/security_configuration/components/manage_generic.vue deleted file mode 100644 index 111ee06674958..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/manage_generic.vue +++ /dev/null @@ -1,42 +0,0 @@ -<script> -import { GlButton } from '@gitlab/ui'; - -export default { - components: { - GlButton, - }, - props: { - feature: { - type: Object, - required: true, - }, - }, - computed: { - canConfigure() { - return Boolean(this.feature.configuration_path && this.feature.configured); - }, - canEnable() { - return Boolean(this.feature.configuration_path && !this.feature.configured); - }, - }, -}; -</script> - -<template> - <gl-button - v-if="canConfigure" - :href="feature.configuration_path" - data-testid="configure-button" - >{{ s__('SecurityConfiguration|Configure') }}</gl-button - > - - <gl-button - v-else-if="canEnable" - variant="confirm" - category="primary" - :href="feature.configuration_path" - data-testid="enable-button" - :data-qa-selector="`${feature.type}_enable_button`" - >{{ s__('SecurityConfiguration|Enable') }}</gl-button - > -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/status_dast_profiles.vue b/ee/app/assets/javascripts/security_configuration/components/status_dast_profiles.vue deleted file mode 100644 index 5bf07a6889115..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/status_dast_profiles.vue +++ /dev/null @@ -1,13 +0,0 @@ -<script> -import { s__ } from '~/locale'; - -export default { - i18n: { - availableForOnDemand: s__('SecurityConfiguration|Available for on-demand DAST'), - }, -}; -</script> - -<template> - <div>{{ $options.i18n.availableForOnDemand }}</div> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/status_generic.vue b/ee/app/assets/javascripts/security_configuration/components/status_generic.vue deleted file mode 100644 index a6366a54bd424..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/status_generic.vue +++ /dev/null @@ -1,36 +0,0 @@ -<script> -import { s__ } from '~/locale'; - -export default { - props: { - feature: { - type: Object, - required: true, - }, - autoDevopsEnabled: { - type: Boolean, - required: true, - }, - }, - computed: { - status() { - if (this.feature.configured) { - return this.autoDevopsEnabled - ? this.$options.i18n.enabledWithAutoDevOps - : this.$options.i18n.enabled; - } - - return this.$options.i18n.notEnabled; - }, - }, - i18n: { - enabled: s__('SecurityConfiguration|Enabled'), - enabledWithAutoDevOps: s__('SecurityConfiguration|Enabled with Auto DevOps'), - notEnabled: s__('SecurityConfiguration|Not enabled'), - }, -}; -</script> - -<template> - <div>{{ status }}</div> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/components/status_view_history.vue b/ee/app/assets/javascripts/security_configuration/components/status_view_history.vue deleted file mode 100644 index b908964e8d27f..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/components/status_view_history.vue +++ /dev/null @@ -1,46 +0,0 @@ -<script> -import { GlLink } from '@gitlab/ui'; -import StatusGeneric from './status_generic.vue'; - -export default { - components: { - GlLink, - StatusGeneric, - }, - props: { - feature: { - type: Object, - required: true, - }, - autoDevopsEnabled: { - type: Boolean, - required: true, - }, - gitlabCiPresent: { - type: Boolean, - required: false, - default: false, - }, - gitlabCiHistoryPath: { - type: String, - required: false, - default: '', - }, - }, - computed: { - canViewCiHistory() { - return this.feature.configured && this.gitlabCiPresent; - }, - }, -}; -</script> - -<template> - <div> - <status-generic :feature="feature" :auto-devops-enabled="autoDevopsEnabled" /> - - <gl-link v-if="canViewCiHistory" :href="gitlabCiHistoryPath">{{ - s__('SecurityConfiguration|View history') - }}</gl-link> - </div> -</template> diff --git a/ee/app/assets/javascripts/security_configuration/index.js b/ee/app/assets/javascripts/security_configuration/index.js deleted file mode 100644 index dee53e28a0d78..0000000000000 --- a/ee/app/assets/javascripts/security_configuration/index.js +++ /dev/null @@ -1,64 +0,0 @@ -import Vue from 'vue'; -import { parseBooleanDataAttributes } from '~/lib/utils/dom_utils'; -import { initRedesignedSecurityConfiguration } from '~/security_configuration'; -import SecurityConfigurationApp from './components/app.vue'; - -export const initSecurityConfiguration = (el) => { - if (!el) { - return null; - } - - if (gon.features?.securityConfigurationRedesignEE) { - return initRedesignedSecurityConfiguration(el); - } - - const { - autoDevopsHelpPagePath, - autoDevopsPath, - features, - latestPipelinePath, - autoFixEnabled, - autoFixHelpPath, - autoFixUserPath, - containerScanningHelpPath, - dependencyScanningHelpPath, - toggleAutofixSettingEndpoint, - projectPath, - gitlabCiHistoryPath, - } = el.dataset; - - return new Vue({ - el, - components: { - SecurityConfigurationApp, - }, - provide: { - projectPath, - }, - render(createElement) { - return createElement(SecurityConfigurationApp, { - props: { - autoDevopsHelpPagePath, - autoDevopsPath, - features: JSON.parse(features), - latestPipelinePath, - ...parseBooleanDataAttributes(el, [ - 'autoDevopsEnabled', - 'canEnableAutoDevops', - 'gitlabCiPresent', - ]), - gitlabCiHistoryPath, - autoFixSettingsProps: { - autoFixEnabled: JSON.parse(autoFixEnabled), - autoFixHelpPath, - autoFixUserPath, - containerScanningHelpPath, - dependencyScanningHelpPath, - toggleAutofixSettingEndpoint, - ...parseBooleanDataAttributes(el, ['canToggleAutoFixSettings']), - }, - }, - }); - }, - }); -}; diff --git a/ee/app/controllers/ee/projects/security/configuration_controller.rb b/ee/app/controllers/ee/projects/security/configuration_controller.rb index 74d38252dc471..6bd1a9b4e89ed 100644 --- a/ee/app/controllers/ee/projects/security/configuration_controller.rb +++ b/ee/app/controllers/ee/projects/security/configuration_controller.rb @@ -23,10 +23,6 @@ module ConfigurationController end feature_category :static_application_security_testing - - before_action only: [:show] do - push_frontend_feature_flag(:security_configuration_redesign_ee, project, default_enabled: :yaml) - end end # rubocop:disable Gitlab/ModuleWithInstanceVariables diff --git a/ee/app/views/projects/security/configuration/show.html.haml b/ee/app/views/projects/security/configuration/show.html.haml index 0f7558475d1e4..24ca1fa3682e0 100644 --- a/ee/app/views/projects/security/configuration/show.html.haml +++ b/ee/app/views/projects/security/configuration/show.html.haml @@ -1,7 +1,6 @@ - breadcrumb_title _("Security Configuration") - page_title _("Security Configuration") -- redesign_enabled = ::Feature.enabled?(:security_configuration_redesign_ee, @project, default_enabled: :yaml) -- @content_class = "limit-container-width" unless fluid_layout || !redesign_enabled +- @content_class = "limit-container-width" unless fluid_layout - if @configuration.nil? = render_ce 'projects/security/configuration/show' diff --git a/ee/spec/features/projects/security/user_views_security_configuration_spec.rb b/ee/spec/features/projects/security/user_views_security_configuration_spec.rb index beb4b8643a914..9916613144b78 100644 --- a/ee/spec/features/projects/security/user_views_security_configuration_spec.rb +++ b/ee/spec/features/projects/security/user_views_security_configuration_spec.rb @@ -15,7 +15,7 @@ sign_in(user) end - context 'with security_dashboard feature available and redesign feature flag on' do + context 'with security_dashboard feature available' do before do stub_licensed_features(security_dashboard: true, sast: true, dast: true) end @@ -77,90 +77,6 @@ end end - context 'with security_dashboard feature available and redesign feature flag off' do - before do - stub_licensed_features(security_dashboard: true) - stub_feature_flags(security_configuration_redesign_ee: false) - end - - context 'with no SAST report' do - it 'shows SAST is not enabled' do - visit(project_security_configuration_path(project)) - - within_sast_row do - expect(page).to have_text('SAST') - expect(page).to have_text('Not enabled') - expect(page).to have_link('Enable') - end - end - end - - context 'with SAST report' do - before do - create(:ci_build, :sast, pipeline: pipeline, status: 'success') - end - - it 'shows SAST is enabled' do - visit(project_security_configuration_path(project)) - - within_sast_row do - expect(page).to have_text('SAST') - expect(page).to have_text('Enabled') - expect(page).to have_link('Configure') - end - end - end - - context 'with no DAST report' do - it 'shows DAST is not enabled' do - visit(project_security_configuration_path(project)) - - within_dast_row do - expect(page).to have_text('DAST') - expect(page).to have_text('Not enabled') - expect(page).to have_link('Enable') - end - end - end - - context 'with DAST report' do - before do - create(:ci_build, :dast, pipeline: pipeline, status: 'success') - end - - it 'shows DAST is enabled' do - visit(project_security_configuration_path(project)) - - within_dast_row do - expect(page).to have_text('DAST') - expect(page).to have_text('Enabled') - expect(page).to have_link('Configure') - end - end - - it 'links to configuration page' do - visit(project_security_configuration_path(project)) - - within_dast_row do - click_link_or_button 'Configure' - expect(current_path).to eq(project_security_configuration_dast_path(project)) - end - end - end - end - - def within_sast_row - within '[data-testid="security-scanner-row"]:nth-of-type(1)' do - yield - end - end - - def within_dast_row - within '[data-testid="security-scanner-row"]:nth-of-type(2)' do - yield - end - end - def within_sast_card within '[data-testid="security-testing-card"]:nth-of-type(1)' do yield diff --git a/ee/spec/frontend/security_configuration/components/app_spec.js b/ee/spec/frontend/security_configuration/components/app_spec.js deleted file mode 100644 index d3dd47684f07b..0000000000000 --- a/ee/spec/frontend/security_configuration/components/app_spec.js +++ /dev/null @@ -1,185 +0,0 @@ -import { GlAlert, GlLink } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; -import { merge } from 'lodash'; -import SecurityConfigurationApp from 'ee/security_configuration/components/app.vue'; -import ConfigurationTable from 'ee/security_configuration/components/configuration_table.vue'; -import { useLocalStorageSpy } from 'helpers/local_storage_helper'; -import stubChildren from 'helpers/stub_children'; -import { scanners } from '~/security_configuration/components/constants'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; -import { generateFeatures } from './helpers'; - -const propsData = { - features: [], - autoDevopsEnabled: false, - latestPipelinePath: 'http://latestPipelinePath', - autoDevopsHelpPagePath: 'http://autoDevopsHelpPagePath', - autoDevopsPath: 'http://autoDevopsPath', - helpPagePath: 'http://helpPagePath', - gitlabCiPresent: false, - gitlabCiHistoryPath: '/ci/history', - autoFixSettingsProps: {}, -}; - -describe('Security Configuration App', () => { - let wrapper; - const createComponent = (options = {}) => { - wrapper = mount( - SecurityConfigurationApp, - merge( - {}, - { - stubs: { - ...stubChildren(SecurityConfigurationApp), - GlSprintf: false, - }, - propsData, - }, - options, - ), - ); - }; - - beforeEach(() => { - localStorage.clear(); - }); - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - const getPipelinesLink = () => wrapper.find({ ref: 'pipelinesLink' }); - const getConfigurationTable = () => wrapper.find(ConfigurationTable); - const getAlert = () => wrapper.find(GlAlert); - - describe('header', () => { - it.each` - autoDevopsEnabled | expectedUrl - ${true} | ${propsData.autoDevopsHelpPagePath} - ${false} | ${propsData.latestPipelinePath} - `( - 'displays a link to "$expectedUrl" when autoDevops is "$autoDevopsEnabled"', - ({ autoDevopsEnabled, expectedUrl }) => { - createComponent({ propsData: { autoDevopsEnabled } }); - - expect(getPipelinesLink().attributes('href')).toBe(expectedUrl); - expect(getPipelinesLink().attributes('target')).toBe('_blank'); - }, - ); - }); - - describe('Auto DevOps alert', () => { - describe.each` - gitlabCiPresent | autoDevopsEnabled | canEnableAutoDevops | dismissed | shouldShowAlert - ${false} | ${false} | ${true} | ${false} | ${true} - ${false} | ${false} | ${true} | ${true} | ${false} - ${true} | ${false} | ${true} | ${false} | ${false} - ${false} | ${true} | ${true} | ${false} | ${false} - ${false} | ${false} | ${false} | ${false} | ${false} - `( - 'given gitlabCiPresent is $gitlabCiPresent, autoDevopsEnabled is $autoDevopsEnabled, dismissed is $dismissed, canEnableAutoDevops is $canEnableAutoDevops', - ({ gitlabCiPresent, autoDevopsEnabled, canEnableAutoDevops, dismissed, shouldShowAlert }) => { - beforeEach(() => { - if (dismissed) { - localStorage.setItem(SecurityConfigurationApp.autoDevopsAlertStorageKey, 'true'); - } - - createComponent({ - propsData: { - gitlabCiPresent, - autoDevopsEnabled, - canEnableAutoDevops, - }, - stubs: { - LocalStorageSync, - }, - }); - }); - - it(`is${shouldShowAlert ? '' : ' not'} rendered`, () => { - expect(getAlert().exists()).toBe(shouldShowAlert); - }); - - if (shouldShowAlert) { - it('has the expected text', () => { - expect(getAlert().text()).toMatchInterpolatedText( - SecurityConfigurationApp.autoDevopsAlertMessage, - ); - }); - - it('has a link to the Auto DevOps docs', () => { - const link = getAlert().find(GlLink); - expect(link.attributes().href).toBe(propsData.autoDevopsHelpPagePath); - }); - - it('has the correct primary button', () => { - expect(getAlert().props()).toMatchObject({ - title: 'Auto DevOps', - primaryButtonText: 'Enable Auto DevOps', - primaryButtonLink: propsData.autoDevopsPath, - }); - }); - } - }, - ); - - describe('dismissing the alert', () => { - useLocalStorageSpy(); - - beforeEach(() => { - createComponent({ - propsData: { - gitlabCiPresent: false, - autoDevopsEnabled: false, - canEnableAutoDevops: true, - }, - stubs: { - LocalStorageSync, - }, - }); - - getAlert().vm.$emit('dismiss'); - }); - - it('hides the alert', () => { - expect(getAlert().exists()).toBe(false); - }); - - it('saves dismissal in localStorage', () => { - expect(localStorage.setItem.mock.calls).toEqual([ - [SecurityConfigurationApp.autoDevopsAlertStorageKey, 'true'], - ]); - }); - }); - }); - - describe('features table', () => { - it('passes the expected features to the configuration table', () => { - const features = generateFeatures(scanners.length); - - createComponent({ propsData: { features } }); - const table = getConfigurationTable(); - const receivedFeatures = table.props('features'); - - scanners.forEach((scanner, i) => { - expect(receivedFeatures[i]).toMatchObject({ - ...features[i], - name: scanner.name, - description: scanner.description, - helpPath: scanner.helpPath, - }); - }); - }); - - it('passes the expected props data to the configuration table', () => { - createComponent(); - - expect(getConfigurationTable().props()).toMatchObject({ - autoDevopsEnabled: propsData.autoDevopsEnabled, - gitlabCiPresent: propsData.gitlabCiPresent, - gitlabCiHistoryPath: propsData.gitlabCiHistoryPath, - }); - }); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/auto_fix_settings_spec.js b/ee/spec/frontend/security_configuration/components/auto_fix_settings_spec.js deleted file mode 100644 index 504f76d2e3bfc..0000000000000 --- a/ee/spec/frontend/security_configuration/components/auto_fix_settings_spec.js +++ /dev/null @@ -1,178 +0,0 @@ -import { mount } from '@vue/test-utils'; -import AxiosMockAdapter from 'axios-mock-adapter'; -import AutoFixSettings from 'ee/security_configuration/components/auto_fix_settings.vue'; -import { TEST_HOST } from 'helpers/test_constants'; -import waitForPromises from 'helpers/wait_for_promises'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; - -jest.mock('~/flash.js'); - -const AUTO_FIX_USER_PATH = `${TEST_HOST}/security_bot`; -const AUTO_FIX_HELP_PATH = `${TEST_HOST}/help/auto_fix`; -const CONTAINER_SCANNING_HELP_PATH = `${TEST_HOST}/help/container_scanning`; -const DEPENDENCY_SCANNING_HELP_PATH = `${TEST_HOST}/help/dependency_scanning`; -const TOGGLE_AUTO_FIX_ENDPOINT = 'auto_fix'; - -const AUTO_FIX_ENABLED_PROPS = { - container_scanning: true, - dependency_scanning: true, -}; -const AUTO_FIX_DISABLED_PROPS = { - container_scanning: false, - dependency_scanning: false, -}; - -const FOOTER_TEXT = - 'Container Scanning and/or Dependency Scanning must be enabled. ' + - 'GitLab-Security-Bot will be the author of the auto-created merge request. More information.'; - -describe('Auto-fix Settings', () => { - let axiosMock; - let wrapper; - - const createComponent = (props = {}) => { - axiosMock = new AxiosMockAdapter(axios); - wrapper = mount(AutoFixSettings, { - propsData: { - autoFixHelpPath: AUTO_FIX_HELP_PATH, - autoFixUserPath: AUTO_FIX_USER_PATH, - containerScanningHelpPath: CONTAINER_SCANNING_HELP_PATH, - dependencyScanningHelpPath: DEPENDENCY_SCANNING_HELP_PATH, - toggleAutofixSettingEndpoint: TOGGLE_AUTO_FIX_ENDPOINT, - canToggleAutoFixSettings: true, - ...props, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - axiosMock.restore(); - }); - - const findCheckbox = () => wrapper.find('input[type="checkbox"]'); - const findFooter = () => wrapper.find('footer'); - const findFooterLinks = () => findFooter().findAll('a'); - const getFooterTextContent = () => findFooter().text().trim(); - - const expectCheckboxDisabled = () => expect(findCheckbox().attributes().disabled).toBeTruthy(); - - const toggleCheckbox = () => findCheckbox().setChecked(!wrapper.vm.autoFixEnabledLocal); - - const expectCorrectLinks = () => { - const links = findFooterLinks(); - expect(links.length).toBe(4); - expect(links.at(0).attributes('href')).toBe(CONTAINER_SCANNING_HELP_PATH); - expect(links.at(1).attributes('href')).toBe(DEPENDENCY_SCANNING_HELP_PATH); - expect(links.at(2).attributes('href')).toBe(AUTO_FIX_USER_PATH); - expect(links.at(3).attributes('href')).toBe(AUTO_FIX_HELP_PATH); - }; - - const itShowsEnabledInformation = () => { - it('checkbox is checked', () => { - expect(findCheckbox().element.checked).toBeTruthy(); - }); - - it('explains how GitLab Security Bot will author auto-fix MRs', () => { - expect(getFooterTextContent()).toBe(FOOTER_TEXT); - }); - - it('shows links to GitLab Security Bot profile and auto-fix documentation', () => { - expectCorrectLinks(); - }); - }; - - const itShowsDisabledInformation = () => { - it('checkbox is unchecked', () => { - expect(findCheckbox().element.checked).toBeFalsy(); - }); - - it('explains how auto-fix will behave when enabled', () => { - expect(getFooterTextContent()).toBe(FOOTER_TEXT); - }); - - it('shows links ', () => { - expectCorrectLinks(); - }); - }; - - const itSendsPostRequest = () => { - it('sends a post request and sets loading state', () => { - expect(axiosMock.history.post).toHaveLength(1); - expectCheckboxDisabled(); - }); - }; - - describe.each` - description | autoFixEnabled | itShowsInitialState | itShowsToggleSuccessState - ${'enabled'} | ${AUTO_FIX_ENABLED_PROPS} | ${itShowsEnabledInformation} | ${itShowsDisabledInformation} - ${'disabled'} | ${AUTO_FIX_DISABLED_PROPS} | ${itShowsDisabledInformation} | ${itShowsEnabledInformation} - `( - 'with auto-fix $description', - ({ autoFixEnabled, itShowsInitialState, itShowsToggleSuccessState }) => { - beforeEach(() => { - createComponent({ autoFixEnabled }); - }); - - itShowsInitialState(); - - describe('when toggling the checkbox', () => { - describe('on success', () => { - beforeEach(() => { - axiosMock.onPost(TOGGLE_AUTO_FIX_ENDPOINT).reply(200); - toggleCheckbox(); - }); - - itSendsPostRequest(); - - describe('when request resolves', () => { - beforeEach(waitForPromises); - - itShowsToggleSuccessState(); - - it('resets loading state', () => { - expect(findCheckbox().attributes().disabled).toBeFalsy(); - }); - }); - }); - - describe('on error', () => { - beforeEach(() => { - axiosMock.onPost(TOGGLE_AUTO_FIX_ENDPOINT).reply(500); - toggleCheckbox(); - }); - - itSendsPostRequest(); - - describe('when request resolves', () => { - beforeEach(waitForPromises); - - itShowsInitialState(); - - it('shows error flash', () => { - expect(createFlash).toHaveBeenCalledWith({ - message: - 'Something went wrong while toggling auto-fix settings, please try again later.', - }); - }); - }); - }); - }); - }, - ); - - describe("when user isn't allowed to toggle auto-fix settings", () => { - beforeEach(() => { - createComponent({ - canToggleAutoFixSettings: false, - autoFixEnabled: AUTO_FIX_ENABLED_PROPS, - }); - }); - - it('disables the checkbox', () => { - expectCheckboxDisabled(); - }); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/configuration_table_spec.js b/ee/spec/frontend/security_configuration/components/configuration_table_spec.js deleted file mode 100644 index 11ecd5caa3821..0000000000000 --- a/ee/spec/frontend/security_configuration/components/configuration_table_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import { GlAlert, GlLink } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; -import ConfigurationTable from 'ee/security_configuration/components/configuration_table.vue'; -import FeatureStatus from 'ee/security_configuration/components/feature_status.vue'; -import ManageFeature from 'ee/security_configuration/components/manage_feature.vue'; -import stubChildren from 'helpers/stub_children'; -import { generateFeatures } from './helpers'; - -const propsData = { - features: [], - autoDevopsEnabled: false, - gitlabCiPresent: false, - gitlabCiHistoryPath: '/ci/history', -}; - -describe('ConfigurationTable component', () => { - let wrapper; - const mockFeatures = [ - ...generateFeatures(1, { - name: 'foo', - description: 'Foo description', - helpPath: '/help/foo', - }), - ...generateFeatures(1, { - name: 'bar', - description: 'Bar description', - helpPath: '/help/bar', - }), - ]; - - const createComponent = (props) => { - wrapper = mount(ConfigurationTable, { - stubs: { - ...stubChildren(ConfigurationTable), - GlTable: false, - }, - propsData: { - ...propsData, - ...props, - }, - }); - }; - - const getTable = () => wrapper.find('table'); - const getRows = () => wrapper.findAll('tbody tr'); - const getRowCells = (row) => { - const [description, status, manage] = row.findAll('td').wrappers; - return { description, status, manage }; - }; - - afterEach(() => { - wrapper.destroy(); - }); - - it.each(mockFeatures)('renders the feature %p correctly', (feature) => { - createComponent({ features: [feature] }); - expect(getTable().classes('b-table-stacked-md')).toBe(true); - const rows = getRows(); - expect(rows).toHaveLength(1); - - const { description, status, manage } = getRowCells(rows.at(0)); - expect(description.text()).toMatch(feature.name); - expect(description.text()).toMatch(feature.description); - expect(status.find(FeatureStatus).props()).toEqual({ - feature, - gitlabCiPresent: propsData.gitlabCiPresent, - gitlabCiHistoryPath: propsData.gitlabCiHistoryPath, - autoDevopsEnabled: propsData.autoDevopsEnabled, - }); - expect(manage.find(ManageFeature).props()).toMatchObject({ feature }); - expect(description.find(GlLink).attributes('href')).toBe(feature.helpPath); - }); - - it('catches errors and displays them in an alert', async () => { - const error = 'error message'; - createComponent({ features: mockFeatures }); - - const firstRow = getRows().at(0); - await firstRow.findComponent(ManageFeature).vm.$emit('error', error); - - const alert = wrapper.findComponent(GlAlert); - expect(alert.exists()).toBe(true); - expect(alert.text()).toBe(error); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/feature_status_spec.js b/ee/spec/frontend/security_configuration/components/feature_status_spec.js deleted file mode 100644 index d7dfa2787551f..0000000000000 --- a/ee/spec/frontend/security_configuration/components/feature_status_spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import { pick } from 'lodash'; -import FeatureStatus from 'ee/security_configuration/components/feature_status.vue'; -import StatusDastProfiles from 'ee/security_configuration/components/status_dast_profiles.vue'; -import StatusGeneric from 'ee/security_configuration/components/status_generic.vue'; -import StatusViewHistory from 'ee/security_configuration/components/status_view_history.vue'; -import { - REPORT_TYPE_SAST, - REPORT_TYPE_DAST_PROFILES, - REPORT_TYPE_SECRET_DETECTION, -} from '~/vue_shared/security_reports/constants'; -import { generateFeatures } from './helpers'; - -const props = { - gitlabCiPresent: true, - gitlabCiHistoryPath: '/ci-history', - autoDevopsEnabled: false, -}; - -const attrs = { - 'data-qa-selector': 'foo', -}; - -describe('FeatureStatus component', () => { - let wrapper; - - const createComponent = (options) => { - wrapper = shallowMount(FeatureStatus, options); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - describe('always', () => { - beforeEach(() => { - const [feature] = generateFeatures(1); - createComponent({ attrs, propsData: { feature, ...props } }); - }); - - it('passes through attributes to the expected component', () => { - expect(wrapper.attributes()).toMatchObject(attrs); - }); - }); - - describe.each` - type | expectedComponent - ${REPORT_TYPE_SECRET_DETECTION} | ${StatusViewHistory} - ${REPORT_TYPE_SAST} | ${StatusViewHistory} - ${REPORT_TYPE_DAST_PROFILES} | ${StatusDastProfiles} - ${'foo'} | ${StatusGeneric} - `('given a $type feature', ({ type, expectedComponent }) => { - let feature; - let component; - - beforeEach(() => { - [feature] = generateFeatures(1, { type }); - - createComponent({ propsData: { feature, ...props } }); - - component = wrapper.findComponent(expectedComponent); - }); - - it('renders expected component', () => { - expect(component.exists()).toBe(true); - }); - - it('passes through props to expected component', () => { - // Exclude props not defined on the expected component, since - // @vue/test-utils won't include them in `Wrapper#props`. - const expectedProps = pick({ feature, ...props }, Object.keys(expectedComponent.props ?? {})); - expect(component.props()).toEqual(expectedProps); - }); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/helpers.js b/ee/spec/frontend/security_configuration/components/helpers.js deleted file mode 100644 index 56cd4d80f94dd..0000000000000 --- a/ee/spec/frontend/security_configuration/components/helpers.js +++ /dev/null @@ -1,11 +0,0 @@ -import { scanners } from '~/security_configuration/components/constants'; - -export const generateFeatures = (n, overrides = {}) => { - return [...Array(n).keys()].map((i) => ({ - type: scanners[i % scanners.length].type, - configuration_path: i % 2 ? `configuration_path-${i}` : null, - configured: i % 2 === 0, - status: i % 2 === 0 ? 'Enabled' : 'Not enabled', - ...overrides, - })); -}; diff --git a/ee/spec/frontend/security_configuration/components/manage_dast_profiles_spec.js b/ee/spec/frontend/security_configuration/components/manage_dast_profiles_spec.js deleted file mode 100644 index f0925790b0c14..0000000000000 --- a/ee/spec/frontend/security_configuration/components/manage_dast_profiles_spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import ManageDastProfiles from 'ee/security_configuration/components/manage_dast_profiles.vue'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import { generateFeatures } from './helpers'; - -describe('ManageDastProfiles component', () => { - let wrapper; - - const createComponent = (propsData) => { - wrapper = extendedWrapper(shallowMount(ManageDastProfiles, { propsData })); - }; - - const findButton = () => wrapper.findByTestId('manage-button'); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders the DAST Profiles manage button', () => { - const [feature] = generateFeatures(1, { configuration_path: '/foo' }); - createComponent({ feature }); - - const button = findButton(); - expect(button.text()).toBe('Manage'); - expect(button.attributes('href')).toBe(feature.configuration_path); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/manage_feature_spec.js b/ee/spec/frontend/security_configuration/components/manage_feature_spec.js deleted file mode 100644 index 7a03f7d688962..0000000000000 --- a/ee/spec/frontend/security_configuration/components/manage_feature_spec.js +++ /dev/null @@ -1,95 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import ManageDastProfiles from 'ee/security_configuration/components/manage_dast_profiles.vue'; -import ManageFeature from 'ee/security_configuration/components/manage_feature.vue'; -import ManageGeneric from 'ee/security_configuration/components/manage_generic.vue'; -import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue'; -import { - REPORT_TYPE_DAST_PROFILES, - REPORT_TYPE_DEPENDENCY_SCANNING, - REPORT_TYPE_SECRET_DETECTION, -} from '~/vue_shared/security_reports/constants'; -import { generateFeatures } from './helpers'; - -const attrs = { - 'data-qa-selector': 'foo', -}; - -describe('ManageFeature component', () => { - let wrapper; - - const createComponent = (options) => { - wrapper = shallowMount(ManageFeature, { - provide: { - glFeatures: { - secDependencyScanningUiEnable: true, - }, - }, - ...options, - }); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - describe('always', () => { - beforeEach(() => { - const [feature] = generateFeatures(1); - createComponent({ attrs, propsData: { feature } }); - }); - - it('passes through attributes to the expected component', () => { - expect(wrapper.attributes()).toMatchObject(attrs); - }); - - it('re-emits caught errors', () => { - const component = wrapper.findComponent(ManageGeneric); - component.vm.$emit('error', 'testerror'); - - expect(wrapper.emitted('error')).toEqual([['testerror']]); - }); - }); - - describe.each` - type | expectedComponent - ${REPORT_TYPE_DAST_PROFILES} | ${ManageDastProfiles} - ${REPORT_TYPE_DEPENDENCY_SCANNING} | ${ManageViaMr} - ${REPORT_TYPE_SECRET_DETECTION} | ${ManageViaMr} - ${'foo'} | ${ManageGeneric} - `('given a $type feature', ({ type, expectedComponent }) => { - let feature; - let component; - - beforeEach(() => { - [feature] = generateFeatures(1, { type }); - - createComponent({ propsData: { feature } }); - component = wrapper.findComponent(expectedComponent); - }); - - it('renders expected component', () => { - expect(component.exists()).toBe(true); - }); - - it('passes through props to expected component', () => { - expect(component.props()).toMatchObject({ feature }); - }); - }); - - it.each` - type | featureFlag - ${REPORT_TYPE_DEPENDENCY_SCANNING} | ${'secDependencyScanningUiEnable'} - `('renders generic component for $type if $featureFlag is disabled', ({ type, featureFlag }) => { - const [feature] = generateFeatures(1, { type }); - createComponent({ - propsData: { feature }, - provide: { - glFeatures: { - [featureFlag]: false, - }, - }, - }); - - expect(wrapper.findComponent(ManageGeneric).exists()).toBe(true); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/manage_generic_spec.js b/ee/spec/frontend/security_configuration/components/manage_generic_spec.js deleted file mode 100644 index b7605b986241c..0000000000000 --- a/ee/spec/frontend/security_configuration/components/manage_generic_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import ManageGeneric from 'ee/security_configuration/components/manage_generic.vue'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import { generateFeatures } from './helpers'; - -describe('ManageGeneric component', () => { - let wrapper; - let feature; - - const createComponent = (propsData) => { - wrapper = extendedWrapper(shallowMount(ManageGeneric, { propsData })); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - describe.each` - configured | expectedTestId - ${true} | ${'configure-button'} - ${false} | ${'enable-button'} - `('given feature.configured is $configured', ({ configured, expectedTestId }) => { - describe('given a configuration path', () => { - beforeEach(() => { - [feature] = generateFeatures(1, { configured, configuration_path: 'foo' }); - - createComponent({ feature }); - }); - - it('shows a button to configure the feature', () => { - const button = wrapper.findByTestId(expectedTestId); - expect(button.exists()).toBe(true); - expect(button.attributes('href')).toBe(feature.configuration_path); - }); - }); - }); - - describe('given a feature without a configuration path', () => { - beforeEach(() => { - [feature] = generateFeatures(1, { configuration_path: null }); - - createComponent({ feature }); - }); - - it('renders nothing', () => { - expect(wrapper.html()).toBe(''); - }); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/status_dast_profiles_spec.js b/ee/spec/frontend/security_configuration/components/status_dast_profiles_spec.js deleted file mode 100644 index d8812ed33feda..0000000000000 --- a/ee/spec/frontend/security_configuration/components/status_dast_profiles_spec.js +++ /dev/null @@ -1,24 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import StatusDastProfiles from 'ee/security_configuration/components/status_dast_profiles.vue'; - -describe('StatusDastProfiles component', () => { - let wrapper; - - const createComponent = () => { - wrapper = shallowMount(StatusDastProfiles); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders the fixed DAST Profiles status', () => { - createComponent(); - - expect(wrapper.element).toMatchInlineSnapshot(` - <div> - Available for on-demand DAST - </div> - `); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/status_generic_spec.js b/ee/spec/frontend/security_configuration/components/status_generic_spec.js deleted file mode 100644 index 935a395567f52..0000000000000 --- a/ee/spec/frontend/security_configuration/components/status_generic_spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import StatusGeneric from 'ee/security_configuration/components/status_generic.vue'; -import { generateFeatures } from './helpers'; - -describe('StatusGeneric component', () => { - let wrapper; - - const createComponent = (options) => { - wrapper = shallowMount(StatusGeneric, options); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - describe.each` - context | configured | autoDevopsEnabled | status - ${'not configured'} | ${false} | ${false} | ${StatusGeneric.i18n.notEnabled} - ${'not configured, but Auto DevOps is enabled'} | ${false} | ${true} | ${StatusGeneric.i18n.notEnabled} - ${'configured'} | ${true} | ${false} | ${StatusGeneric.i18n.enabled} - ${'configured with Auto DevOps'} | ${true} | ${true} | ${StatusGeneric.i18n.enabledWithAutoDevOps} - `('given the feature is $context', ({ configured, autoDevopsEnabled, status }) => { - let feature; - - beforeEach(() => { - [feature] = generateFeatures(1, { configured }); - - createComponent({ - propsData: { feature, autoDevopsEnabled }, - }); - }); - - it(`shows the status "${status}"`, () => { - expect(wrapper.text()).toBe(status); - }); - }); -}); diff --git a/ee/spec/frontend/security_configuration/components/status_view_history_spec.js b/ee/spec/frontend/security_configuration/components/status_view_history_spec.js deleted file mode 100644 index 686b5ba7ddec8..0000000000000 --- a/ee/spec/frontend/security_configuration/components/status_view_history_spec.js +++ /dev/null @@ -1,60 +0,0 @@ -import { GlLink } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import StatusGeneric from 'ee/security_configuration/components/status_generic.vue'; -import StatusViewHistory from 'ee/security_configuration/components/status_view_history.vue'; -import { REPORT_TYPE_SAST } from '~/vue_shared/security_reports/constants'; -import { generateFeatures } from './helpers'; - -const gitlabCiHistoryPath = '/ci/history'; -const autoDevopsEnabled = true; - -describe('StatusSast component', () => { - let wrapper; - - const createComponent = (options) => { - wrapper = shallowMount(StatusViewHistory, options); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - const findHistoryLink = () => wrapper.find(GlLink); - - describe.each` - context | configured | gitlabCiPresent | shouldShowHistory - ${'no CI with sast disabled'} | ${false} | ${false} | ${false} - ${'CI with sast disabled'} | ${false} | ${true} | ${false} - ${'no CI with sast enabled'} | ${true} | ${false} | ${false} - ${'CI with sast enabled'} | ${true} | ${true} | ${true} - `('given $context', ({ configured, gitlabCiPresent, shouldShowHistory }) => { - let feature; - - beforeEach(() => { - [feature] = generateFeatures(1, { type: REPORT_TYPE_SAST, configured }); - - createComponent({ - propsData: { feature, gitlabCiPresent, gitlabCiHistoryPath, autoDevopsEnabled }, - }); - }); - - it('shows the generic status', () => { - const genericComponent = wrapper.findComponent(StatusGeneric); - expect(genericComponent.exists()).toBe(true); - expect(genericComponent.props()).toEqual({ - feature, - autoDevopsEnabled, - }); - }); - - it(`${shouldShowHistory ? 'shows' : 'does not show'} the history link`, () => { - expect(findHistoryLink().exists()).toBe(shouldShowHistory); - }); - - if (shouldShowHistory) { - it("sets the link's href correctly", () => { - expect(findHistoryLink().attributes('href')).toBe(gitlabCiHistoryPath); - }); - } - }); -}); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index b0017b7bbfe05..7e0405e00b242 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -464,9 +464,6 @@ msgstr[1] "" msgid "%{completedWeight} of %{totalWeight} weight completed" msgstr "" -msgid "%{containerScanningLinkStart}Container Scanning%{containerScanningLinkEnd} and/or %{dependencyScanningLinkStart}Dependency Scanning%{dependencyScanningLinkEnd} must be enabled. %{securityBotLinkStart}GitLab-Security-Bot%{securityBotLinkEnd} will be the author of the auto-created merge request. %{moreInfoLinkStart}More information%{moreInfoLinkEnd}." -msgstr "" - msgid "%{cores} cores" msgstr "" @@ -4896,9 +4893,6 @@ msgstr "" msgid "Automatically close associated incident when a recovery alert notification resolves an alert" msgstr "" -msgid "Automatically create merge requests for vulnerabilities that have fixes available." -msgstr "" - msgid "Automatically resolved" msgstr "" @@ -4914,9 +4908,6 @@ msgstr "" msgid "Available ID" msgstr "" -msgid "Available for dependency and container scanning" -msgstr "" - msgid "Available group runners: %{runners}" msgstr "" @@ -29235,12 +29226,6 @@ msgstr "" msgid "SecurityConfiguration|An error occurred while creating the merge request." msgstr "" -msgid "SecurityConfiguration|Available for on-demand DAST" -msgstr "" - -msgid "SecurityConfiguration|Available with %{linkStart}upgrade or free trial%{linkEnd}" -msgstr "" - msgid "SecurityConfiguration|Available with Ultimate" msgstr "" @@ -29256,9 +29241,6 @@ msgstr "" msgid "SecurityConfiguration|Configuration history" msgstr "" -msgid "SecurityConfiguration|Configure" -msgstr "" - msgid "SecurityConfiguration|Configure %{feature}" msgstr "" @@ -29280,9 +29262,6 @@ msgstr "" msgid "SecurityConfiguration|Customize common SAST settings to suit your requirements. Configuration changes made here override those provided by GitLab and are excluded from updates. For details of more advanced configuration options, see the %{linkStart}GitLab SAST documentation%{linkEnd}." msgstr "" -msgid "SecurityConfiguration|Enable" -msgstr "" - msgid "SecurityConfiguration|Enable %{feature}" msgstr "" @@ -29292,30 +29271,18 @@ msgstr "" msgid "SecurityConfiguration|Enabled" msgstr "" -msgid "SecurityConfiguration|Enabled with Auto DevOps" -msgstr "" - -msgid "SecurityConfiguration|Feature documentation for %{featureName}" -msgstr "" - msgid "SecurityConfiguration|High-level vulnerability statistics across projects and groups" msgstr "" msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:" msgstr "" -msgid "SecurityConfiguration|Manage" -msgstr "" - msgid "SecurityConfiguration|Manage profiles for use by DAST scans." msgstr "" msgid "SecurityConfiguration|Manage scans" msgstr "" -msgid "SecurityConfiguration|More information" -msgstr "" - msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance" msgstr "" @@ -29340,18 +29307,9 @@ msgstr "" msgid "SecurityConfiguration|Secure your project" msgstr "" -msgid "SecurityConfiguration|Security Control" -msgstr "" - msgid "SecurityConfiguration|Security testing" msgstr "" -msgid "SecurityConfiguration|Status" -msgstr "" - -msgid "SecurityConfiguration|Testing & Compliance" -msgstr "" - msgid "SecurityConfiguration|The status of the tools only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}." msgstr "" @@ -29361,15 +29319,9 @@ msgstr "" msgid "SecurityConfiguration|Using custom settings. You won't receive automatic updates on this variable. %{anchorStart}Restore to default%{anchorEnd}" msgstr "" -msgid "SecurityConfiguration|View history" -msgstr "" - msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request" msgstr "" -msgid "SecurityConfiguration|You can quickly enable all security scanning tools by enabling %{linkStart}Auto DevOps%{linkEnd}." -msgstr "" - msgid "SecurityOrchestration|An error occurred assigning your security policy project" msgstr "" @@ -30339,9 +30291,6 @@ msgstr "" msgid "Setup" msgstr "" -msgid "Several security scans are enabled because %{linkStart}Auto DevOps%{linkEnd} is enabled on this project" -msgstr "" - msgid "Severity" msgstr "" @@ -30961,9 +30910,6 @@ msgstr "" msgid "Something went wrong while stopping this environment. Please try again." msgstr "" -msgid "Something went wrong while toggling auto-fix settings, please try again later." -msgstr "" - msgid "Something went wrong while updating a requirement." msgstr "" @@ -31921,15 +31867,9 @@ msgstr "" msgid "Suggest code changes which can be immediately applied in one click. Try it out!" msgstr "" -msgid "Suggested Solutions" -msgstr "" - msgid "Suggested change" msgstr "" -msgid "Suggested solutions help link" -msgstr "" - msgid "SuggestedColors|Aztec Gold" msgstr "" @@ -33202,9 +33142,6 @@ msgstr "" msgid "The start date must be ealier than the end date." msgstr "" -msgid "The status of the table below only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}. Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan." -msgstr "" - msgid "The subject will be used as the title of the new issue, and the message will be the description. %{quickActionsLinkStart}Quick actions%{quickActionsLinkEnd} and styling with %{markdownLinkStart}Markdown%{markdownLinkEnd} are supported." msgstr "" diff --git a/spec/frontend/security_configuration/app_spec.js b/spec/frontend/security_configuration/app_spec.js deleted file mode 100644 index 11d481fb210eb..0000000000000 --- a/spec/frontend/security_configuration/app_spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import App from '~/security_configuration/components/app.vue'; -import ConfigurationTable from '~/security_configuration/components/configuration_table.vue'; - -describe('App Component', () => { - let wrapper; - - const createComponent = () => { - wrapper = shallowMount(App, {}); - }; - const findConfigurationTable = () => wrapper.findComponent(ConfigurationTable); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders correct primary & Secondary Heading', () => { - createComponent(); - expect(wrapper.text()).toContain('Security Configuration'); - expect(wrapper.text()).toContain('Testing & Compliance'); - }); - - it('renders ConfigurationTable Component', () => { - createComponent(); - expect(findConfigurationTable().exists()).toBe(true); - }); -}); diff --git a/spec/frontend/security_configuration/components/redesigned_app_spec.js b/spec/frontend/security_configuration/components/app_spec.js similarity index 97% rename from spec/frontend/security_configuration/components/redesigned_app_spec.js rename to spec/frontend/security_configuration/components/app_spec.js index 92e0443552c94..f27f45f2b260d 100644 --- a/spec/frontend/security_configuration/components/redesigned_app_spec.js +++ b/spec/frontend/security_configuration/components/app_spec.js @@ -4,6 +4,7 @@ import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser'; import stubChildren from 'helpers/stub_children'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import SecurityConfigurationApp, { i18n } from '~/security_configuration/components/app.vue'; import AutoDevopsAlert from '~/security_configuration/components/auto_dev_ops_alert.vue'; import AutoDevopsEnabledAlert from '~/security_configuration/components/auto_dev_ops_enabled_alert.vue'; import { @@ -19,9 +20,6 @@ import { } from '~/security_configuration/components/constants'; import FeatureCard from '~/security_configuration/components/feature_card.vue'; -import RedesignedSecurityConfigurationApp, { - i18n, -} from '~/security_configuration/components/redesigned_app.vue'; import UpgradeBanner from '~/security_configuration/components/upgrade_banner.vue'; import { REPORT_TYPE_LICENSE_COMPLIANCE, @@ -36,7 +34,7 @@ const projectPath = 'namespace/project'; useLocalStorageSpy(); -describe('redesigned App component', () => { +describe('App component', () => { let wrapper; let userCalloutDismissSpy; @@ -44,7 +42,7 @@ describe('redesigned App component', () => { userCalloutDismissSpy = jest.fn(); wrapper = extendedWrapper( - mount(RedesignedSecurityConfigurationApp, { + mount(SecurityConfigurationApp, { propsData, provide: { upgradePath, @@ -53,7 +51,7 @@ describe('redesigned App component', () => { projectPath, }, stubs: { - ...stubChildren(RedesignedSecurityConfigurationApp), + ...stubChildren(SecurityConfigurationApp), GlLink: false, GlSprintf: false, LocalStorageSync: false, diff --git a/spec/frontend/security_configuration/configuration_table_spec.js b/spec/frontend/security_configuration/configuration_table_spec.js deleted file mode 100644 index fbd72265c4b9c..0000000000000 --- a/spec/frontend/security_configuration/configuration_table_spec.js +++ /dev/null @@ -1,52 +0,0 @@ -import { mount } from '@vue/test-utils'; -import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import ConfigurationTable from '~/security_configuration/components/configuration_table.vue'; -import { scanners, UPGRADE_CTA } from '~/security_configuration/components/constants'; - -import { - REPORT_TYPE_SAST, - REPORT_TYPE_SECRET_DETECTION, -} from '~/vue_shared/security_reports/constants'; - -describe('Configuration Table Component', () => { - let wrapper; - - const createComponent = () => { - wrapper = extendedWrapper( - mount(ConfigurationTable, { - provide: { - projectPath: 'testProjectPath', - }, - }), - ); - }; - - const findHelpLinks = () => wrapper.findAll('[data-testid="help-link"]'); - - afterEach(() => { - wrapper.destroy(); - }); - - beforeEach(() => { - createComponent(); - }); - - describe.each(scanners.map((scanner, i) => [scanner, i]))('given scanner %s', (scanner, i) => { - it('should match strings', () => { - expect(wrapper.text()).toContain(scanner.name); - expect(wrapper.text()).toContain(scanner.description); - if (scanner.type === REPORT_TYPE_SAST) { - expect(wrapper.findByTestId(scanner.type).text()).toBe('Configure via Merge Request'); - } else if (scanner.type === REPORT_TYPE_SECRET_DETECTION) { - expect(wrapper.findByTestId(scanner.type).exists()).toBe(false); - } else { - expect(wrapper.findByTestId(scanner.type).text()).toMatchInterpolatedText(UPGRADE_CTA); - } - }); - - it('should show expected help link', () => { - const helpLink = findHelpLinks().at(i); - expect(helpLink.attributes('href')).toBe(scanner.helpPath); - }); - }); -}); diff --git a/spec/frontend/security_configuration/upgrade_spec.js b/spec/frontend/security_configuration/upgrade_spec.js deleted file mode 100644 index 20bb38aa46998..0000000000000 --- a/spec/frontend/security_configuration/upgrade_spec.js +++ /dev/null @@ -1,30 +0,0 @@ -import { mount } from '@vue/test-utils'; -import { UPGRADE_CTA } from '~/security_configuration/components/constants'; -import Upgrade from '~/security_configuration/components/upgrade.vue'; - -const TEST_URL = 'http://www.example.test'; -let wrapper; -const createComponent = (componentData = {}) => { - wrapper = mount(Upgrade, componentData); -}; - -afterEach(() => { - wrapper.destroy(); -}); - -describe('Upgrade component', () => { - beforeEach(() => { - createComponent({ provide: { upgradePath: TEST_URL } }); - }); - - it('renders correct text in link', () => { - expect(wrapper.text()).toMatchInterpolatedText(UPGRADE_CTA); - }); - - it('renders link with correct default attributes', () => { - expect(wrapper.find('a').attributes()).toMatchObject({ - href: TEST_URL, - target: '_blank', - }); - }); -}); -- GitLab