diff options
33 files changed, 357 insertions, 95 deletions
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index b37e644b503..704515cf70c 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -129,9 +129,6 @@ export default { crossplaneInstalled() { return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED; }, - enableClusterApplicationCrossplane() { - return gon.features && gon.features.enableClusterApplicationCrossplane; - }, enableClusterApplicationElasticStack() { return gon.features && gon.features.enableClusterApplicationElasticStack; }, @@ -519,7 +516,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity </div> </application-row> <application-row - v-if="enableClusterApplicationCrossplane" id="crossplane" :logo-url="crossplaneLogo" :title="applications.crossplane.title" diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue index 4802cc2ad25..0883b89d75b 100644 --- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue @@ -82,6 +82,11 @@ export default { required: false, default: false, }, + pagesAccessControlForced: { + type: Boolean, + required: false, + default: false, + }, pagesHelpPath: { type: String, required: false, @@ -130,10 +135,22 @@ export default { }, pagesFeatureAccessLevelOptions() { - if (this.visibilityLevel !== visibilityOptions.PUBLIC) { - return this.featureAccessLevelOptions.concat([[30, PAGE_FEATURE_ACCESS_LEVEL]]); + const options = [featureAccessLevelMembers]; + + if (this.pagesAccessControlForced) { + if (this.visibilityLevel === visibilityOptions.INTERNAL) { + options.push(featureAccessLevelEveryone); + } + } else { + if (this.visibilityLevel !== visibilityOptions.PRIVATE) { + options.push(featureAccessLevelEveryone); + } + + if (this.visibilityLevel !== visibilityOptions.PUBLIC) { + options.push([30, PAGE_FEATURE_ACCESS_LEVEL]); + } } - return this.featureAccessLevelOptions; + return options; }, repositoryEnabled() { diff --git a/app/assets/javascripts/registry/list/components/collapsible_container.vue b/app/assets/javascripts/registry/list/components/collapsible_container.vue index 86bb2d8092e..9786a1a3f75 100644 --- a/app/assets/javascripts/registry/list/components/collapsible_container.vue +++ b/app/assets/javascripts/registry/list/components/collapsible_container.vue @@ -14,7 +14,7 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import Icon from '~/vue_shared/components/icon.vue'; import TableRegistry from './table_registry.vue'; import { DELETE_REPO_ERROR_MESSAGE } from '../constants'; -import { __ } from '~/locale'; +import { __, sprintf } from '~/locale'; export default { name: 'CollapsibeContainerRegisty', @@ -55,6 +55,11 @@ export default { canDeleteRepo() { return this.repo.canDelete && !this.isDeleteDisabled; }, + deleteImageConfirmationMessage() { + return sprintf(__('Image %{imageName} was scheduled for deletion from the registry.'), { + imageName: this.repo.name, + }); + }, }, methods: { ...mapActions(['fetchRepos', 'fetchList', 'deleteItem']), @@ -69,7 +74,7 @@ export default { this.track('confirm_delete'); return this.deleteItem(this.repo) .then(() => { - createFlash(__('This container registry has been scheduled for deletion.'), 'notice'); + createFlash(this.deleteImageConfirmationMessage, 'notice'); this.fetchRepos(); }) .catch(() => createFlash(DELETE_REPO_ERROR_MESSAGE)); diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index f4b74b14c0b..52a5f801bad 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -14,7 +14,6 @@ class Clusters::ClustersController < Clusters::BaseController before_action :update_applications_status, only: [:cluster_status] before_action only: [:show] do push_frontend_feature_flag(:enable_cluster_application_elastic_stack) - push_frontend_feature_flag(:enable_cluster_application_crossplane) end helper_method :token_in_session diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index b6e24a450e8..04d2b3068da 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -5,9 +5,6 @@ class SearchController < ApplicationController include SearchHelper include RendersCommits - NON_ES_SEARCH_TERM_LIMIT = 64 - NON_ES_SEARCH_CHAR_LIMIT = 4096 - around_action :allow_gitaly_ref_name_caching skip_before_action :authenticate_user! @@ -68,19 +65,13 @@ class SearchController < ApplicationController private def search_term_valid? - return true if Gitlab::CurrentSettings.elasticsearch_search? - - chars_count = params[:search].length - if chars_count > NON_ES_SEARCH_CHAR_LIMIT - flash[:alert] = t('errors.messages.search_chars_too_long', count: NON_ES_SEARCH_CHAR_LIMIT) - + unless search_service.valid_query_length? + flash[:alert] = t('errors.messages.search_chars_too_long', count: SearchService::SEARCH_CHAR_LIMIT) return false end - search_terms_count = params[:search].split.count { |word| word.length >= 3 } - if search_terms_count > NON_ES_SEARCH_TERM_LIMIT - flash[:alert] = t('errors.messages.search_terms_too_long', count: NON_ES_SEARCH_TERM_LIMIT) - + unless search_service.valid_terms_count? + flash[:alert] = t('errors.messages.search_terms_too_long', count: SearchService::SEARCH_TERM_LIMIT) return false end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 7115fd834fd..077035a49ed 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -202,6 +202,7 @@ module ApplicationSettingsHelper :enabled_git_access_protocol, :enforce_terms, :first_day_of_week, + :force_pages_access_control, :gitaly_timeout_default, :gitaly_timeout_medium, :gitaly_timeout_fast, diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index d683faf6a20..7bd6c6670c1 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -587,6 +587,7 @@ module ProjectsHelper lfsHelpPath: help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs'), pagesAvailable: Gitlab.config.pages.enabled, pagesAccessControlEnabled: Gitlab.config.pages.access_control, + pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?, pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control-core') } end diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb index 4973c7761c1..ec097844499 100644 --- a/app/models/project_feature.rb +++ b/app/models/project_feature.rb @@ -97,7 +97,13 @@ class ProjectFeature < ApplicationRecord default_value_for :wiki_access_level, value: ENABLED, allows_nil: false default_value_for :repository_access_level, value: ENABLED, allows_nil: false - default_value_for(:pages_access_level, allows_nil: false) { |feature| feature.project&.public? ? ENABLED : PRIVATE } + default_value_for(:pages_access_level, allows_nil: false) do |feature| + if ::Gitlab::Pages.access_control_is_forced? + PRIVATE + else + feature.project&.public? ? ENABLED : PRIVATE + end + end def feature_available?(feature, user) # This feature might not be behind a feature flag at all, so default to true @@ -137,6 +143,8 @@ class ProjectFeature < ApplicationRecord def public_pages? return true unless Gitlab.config.pages.access_control + return false if ::Gitlab::Pages.access_control_is_forced? + pages_access_level == PUBLIC || pages_access_level == ENABLED && project.public? end diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb index 89b8163f798..844da11e5cb 100644 --- a/app/services/clusters/applications/base_service.rb +++ b/app/services/clusters/applications/base_service.rb @@ -68,7 +68,7 @@ module Clusters end def invalid_application? - unknown_application? || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack)) || (application_name == Applications::Crossplane.application_name && !Feature.enabled?(:enable_cluster_application_crossplane)) + unknown_application? || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack)) end def unknown_application? diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 91c0f9ba104..fe5e823b56c 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -3,6 +3,9 @@ class SearchService include Gitlab::Allowable + SEARCH_TERM_LIMIT = 64 + SEARCH_CHAR_LIMIT = 4096 + def initialize(current_user, params = {}) @current_user = current_user @params = params.dup @@ -42,6 +45,14 @@ class SearchService @show_snippets = params[:snippets] == 'true' end + def valid_query_length? + params[:search].length <= SEARCH_CHAR_LIMIT + end + + def valid_terms_count? + params[:search].split.count { |word| word.length >= 3 } <= SEARCH_TERM_LIMIT + end + delegate :scope, to: :search_service def search_results diff --git a/app/views/admin/application_settings/_pages.html.haml b/app/views/admin/application_settings/_pages.html.haml index b15afb3b806..8214cf8ce9f 100644 --- a/app/views/admin/application_settings/_pages.html.haml +++ b/app/views/admin/application_settings/_pages.html.haml @@ -15,6 +15,15 @@ .form-text.text-muted = _("Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled") = link_to icon('question-circle'), help_page_path('user/project/pages/custom_domains_ssl_tls_certification/index.md', anchor: '4-verify-the-domains-ownership') + - if Gitlab.config.pages.access_control + .form-group + .form-check + = f.check_box :force_pages_access_control, class: 'form-check-input' + = f.label :force_pages_access_control, class: 'form-check-label' do + = _("Disable public access to Pages sites") + .form-text.text-muted + = _("Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance.") + = link_to icon('question-circle'), help_page_path('administration/pages/index.md', anchor: 'disabling-public-access-to-all-pages-websites') %h5 = _("Configure Let's Encrypt") %p diff --git a/changelogs/unreleased/32095-allow-administrators-to-disable-gitlab-pages-access.yml b/changelogs/unreleased/32095-allow-administrators-to-disable-gitlab-pages-access.yml new file mode 100644 index 00000000000..6f7dfe812de --- /dev/null +++ b/changelogs/unreleased/32095-allow-administrators-to-disable-gitlab-pages-access.yml @@ -0,0 +1,5 @@ +--- +title: Allow administrators to enforce access control for all pages web-sites +merge_request: 22003 +author: +type: added diff --git a/changelogs/unreleased/ak-bubble-up-log-source.yml b/changelogs/unreleased/ak-bubble-up-log-source.yml new file mode 100644 index 00000000000..8bdd58483c7 --- /dev/null +++ b/changelogs/unreleased/ak-bubble-up-log-source.yml @@ -0,0 +1,5 @@ +--- +title: Pass log source to the frontend +merge_request: 22694 +author: +type: changed diff --git a/changelogs/unreleased/remove_enable_cluster_application_crossplane_flag.yml b/changelogs/unreleased/remove_enable_cluster_application_crossplane_flag.yml new file mode 100644 index 00000000000..659e8e69ecb --- /dev/null +++ b/changelogs/unreleased/remove_enable_cluster_application_crossplane_flag.yml @@ -0,0 +1,5 @@ +--- +title: Enable ability to install Crossplane app by default +merge_request: 22141 +author: +type: changed diff --git a/changelogs/unreleased/update_dast_default_branch.yml b/changelogs/unreleased/update_dast_default_branch.yml new file mode 100644 index 00000000000..fd241b76a72 --- /dev/null +++ b/changelogs/unreleased/update_dast_default_branch.yml @@ -0,0 +1,5 @@ +--- +title: Update auto-deploy-image to v0.8.3 for DAST default branch deploy +merge_request: 22227 +author: +type: changed diff --git a/db/migrate/20191218122457_add_force_pages_access_control_to_application_settings.rb b/db/migrate/20191218122457_add_force_pages_access_control_to_application_settings.rb new file mode 100644 index 00000000000..97352fc98ff --- /dev/null +++ b/db/migrate/20191218122457_add_force_pages_access_control_to_application_settings.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddForcePagesAccessControlToApplicationSettings < ActiveRecord::Migration[5.2] + DOWNTIME = false + + def change + add_column :application_settings, :force_pages_access_control, :boolean, null: false, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 56b0cbde61a..7f1a7ac0ff1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -364,6 +364,7 @@ ActiveRecord::Schema.define(version: 2020_01_08_233040) do t.string "encrypted_slack_app_secret_iv", limit: 255 t.text "encrypted_slack_app_verification_token" t.string "encrypted_slack_app_verification_token_iv", limit: 255 + t.boolean "force_pages_access_control", default: false, null: false t.boolean "updating_name_disabled_for_users", default: false, null: false t.integer "instance_administrators_group_id" t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id" diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md index 288177e98c9..d68b825ed88 100644 --- a/doc/administration/instance_limits.md +++ b/doc/administration/instance_limits.md @@ -34,3 +34,11 @@ Read more in the [CI documentation](../ci/yaml/README.md#processing-git-pushes). > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/21164) in GitLab 8.12. Activity history for projects and individuals' profiles was limited to one year until [GitLab 11.4](https://gitlab.com/gitlab-org/gitlab-foss/issues/52246) when it was extended to two years, and in [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/33840) to three years. + +## Number of project webhooks + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/20730) in GitLab 12.6. + +A maximum number of project webhooks applies to each GitLab.com tier. Check the +[Maximum number of webhooks (per tier)](../user/project/integrations/webhooks.md#maximum-number-of-webhooks-per-tier) +section in the Webhooks page. diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md index cce8cfc4d5a..434cb2447c8 100644 --- a/doc/administration/pages/index.md +++ b/doc/administration/pages/index.md @@ -307,6 +307,27 @@ Pages access control is disabled by default. To enable it: 1. [Reconfigure GitLab][reconfigure]. 1. Users can now configure it in their [projects' settings](../../user/project/pages/pages_access_control.md). +#### Disabling public access to all Pages websites + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/32095) in GitLab 12.7. + +You can enforce [Access Control](#access-control) for all GitLab Pages websites hosted +on your GitLab instance. By doing so, only logged-in users will have access to them. +This setting overrides Access Control set by users in individual projects. + +This can be useful to preserve information published with Pages websites to the users +of your instance only. +To do that: + +1. Navigate to your instance's **Admin Area > Settings > Preferences** and expand **Pages** settings. +1. Check the **Disable public access to Pages sites** checkbox. +1. Click **Save changes**. + +CAUTION: **Warning:** +This action will not make all currently public web-sites private until they redeployed. +This issue among others will be resolved by +[changing GitLab Pages configuration mechanism](https://gitlab.com/gitlab-org/gitlab-pages/issues/282). + ### Running behind a proxy Like the rest of GitLab, Pages can be used in those environments where external diff --git a/doc/development/README.md b/doc/development/README.md index 684f6d01d12..c5830bbded0 100644 --- a/doc/development/README.md +++ b/doc/development/README.md @@ -72,6 +72,7 @@ description: 'Learn how to contribute to GitLab.' - [Mass Inserting Models](mass_insert.md) - [Cycle Analytics development guide](cycle_analytics.md) - [Issue types vs first-class types](issue_types.md) +- [Application limits](application_limits.md) ## Performance guides diff --git a/doc/development/application_limits.md b/doc/development/application_limits.md new file mode 100644 index 00000000000..28d1f14b1b3 --- /dev/null +++ b/doc/development/application_limits.md @@ -0,0 +1,89 @@ +# Application limits development + +This document provides a development guide for contributors to add application +limits to GitLab. + +## Documentation + +First of all, you have to gather information and decide which are the different +limits that will be set for the different GitLab tiers. You also need to +coordinate with others to [document](../administration/instance_limits.md) +and communicate those limits. + +There is a guide about [introducing application +limits](https://about.gitlab.com/handbook/product/#introducing-application-limits). + +## Development + +The merge request to [configure maximum number of webhooks per +project](https://gitlab.com/gitlab-org/gitlab/merge_requests/20730/diffs) is a +good example about configuring application limits. + +### Insert database plan limits + +In the `plan_limits` table, you have to create a new column and insert the +limit values. It's recommended to create separate migration script files. + +1. Add new column to the `plan_limits` table with non-null default value 0, eg: + + ```ruby + add_column(:plan_limits, :project_hooks, :integer, default: 0, null: false) + ``` + + NOTE: **Note:** Plan limits entries set to `0` mean that limits are not + enabled. + +1. Insert plan limits values into the database using + `create_or_update_plan_limit` migration helper, eg: + + ```ruby + create_or_update_plan_limit('project_hooks', 'free', 10) + create_or_update_plan_limit('project_hooks', 'bronze', 20) + create_or_update_plan_limit('project_hooks', 'silver', 30) + create_or_update_plan_limit('project_hooks', 'gold', 100) + ``` + +### Plan limits validation + +#### Get current limit + +Access to the current limit can be done through the project or the namespace, +eg: + +```ruby +project.actual_limits.project_hooks +``` + +#### Check current limit + +There is one method `PlanLimits#exceeded?` to check if the current limit is +being exceeded. You can use either an `ActiveRecord` object or an `Integer`. + +Ensures that the count of the records does not exceed the defined limit, eg: + +```ruby +project.actual_limits.exceeded?(:project_hooks, ProjectHook.where(project: project)) +``` + +Ensures that the number does not exceed the defined limit, eg: + +```ruby +project.actual_limits.exceeded?(:project_hooks, 10) +``` + +#### `Limitable` concern + +The [`Limitable` concern](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/concerns/ee/limitable.rb) +can be used to validate that a model does not exceed the limits. It ensures +that the count of the records for the current model does not exceed the defined +limit. + +NOTE: **Note:** The name (pluralized) of the plan limit introduced in the +database (`project_hooks`) must correspond to the name of the model we are +validating (`ProjectHook`). + +```ruby +class ProjectHook + include Limitable +end +``` diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md index f498645466f..3d7d5019c94 100644 --- a/doc/user/clusters/applications.md +++ b/doc/user/clusters/applications.md @@ -420,18 +420,6 @@ install Crossplane using the [`values.yaml`](https://github.com/crossplaneio/crossplane/blob/master/cluster/charts/crossplane/values.yaml.tmpl) file. -#### Enabling installation - -This is a preliminary release of Crossplane as a GitLab-managed application. By default, -the ability to install it is disabled. - -To allow installation of Crossplane as a GitLab-managed application, ask a GitLab -administrator to run following command within a Rails console: - -```ruby -Feature.enable(:enable_cluster_application_crossplane) -``` - ### Elastic Stack > Introduced in GitLab 12.7 for project- and group-level clusters. diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md index e6947431fcb..8a04871db1f 100644 --- a/doc/user/group/epics/index.md +++ b/doc/user/group/epics/index.md @@ -40,6 +40,7 @@ An epic's page contains the following tabs: - **Epics and Issues**: epics and issues added to this epic. Child epics, and their issues, are shown in a tree view. - Click on the <kbd>></kbd> beside a parent epic to reveal the child epics and issues. + - Hover over the total counts to see a breakdown of open and closed items. - **Roadmap**: a roadmap view of child epics which have start and due dates. ![epic view](img/epic_view_v12.3.png) diff --git a/doc/user/project/issues/csv_export.md b/doc/user/project/issues/csv_export.md index b97bcd47f61..13f0c11399f 100644 --- a/doc/user/project/issues/csv_export.md +++ b/doc/user/project/issues/csv_export.md @@ -69,6 +69,8 @@ Data will be encoded with a comma as the column delimiter, with `"` used to quot | Labels | Title of any labels joined with a `,` | | Time Estimate | [Time estimate](../time_tracking.md#estimates) in seconds | | Time Spent | [Time spent](../time_tracking.md#time-spent) in seconds | +| Epic ID | Id of the parent epic **(ULTIMATE)**, introduced in 12.7 | +| Epic Title | Title of the parent epic **(ULTIMATE)**, introduced in 12.7 | ## Limitations diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md index cdb492c4db5..c253210af46 100644 --- a/doc/user/project/releases/index.md +++ b/doc/user/project/releases/index.md @@ -153,7 +153,7 @@ You can also edit an existing tag to add release notes: ![tags](img/tags_12_5.png "Addition of note to an existing tag") -## Release evidence +## Release Evidence > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.6. @@ -216,6 +216,22 @@ Here is what this object can look like: } ``` +### Enabling Release Evidence display **(CORE ONLY)** + +This feature comes with the `:release_evidence_collection` feature flag +disabled by default in GitLab self-managed instances. To turn it on, +ask a GitLab administrator with Rails console access to run the following +command: + +```ruby +Feature.enable(:release_evidence_collection) +``` + +NOTE: **Note:** +Please note that Release Evidence's data is collected regardless of this +feature flag, which only enables or disables the display of the data on the +Releases page. + <!-- ## Troubleshooting Include any troubleshooting steps that you can foresee. If you know beforehand what issues diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml index 7a672f910dd..feedb0994c2 100644 --- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml @@ -1,5 +1,5 @@ .dast-auto-deploy: - image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.6.0" + image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.8.3" dast_environment_deploy: extends: .dast-auto-deploy diff --git a/lib/gitlab/pages.rb b/lib/gitlab/pages.rb index 7703b086341..c8cb8b6e020 100644 --- a/lib/gitlab/pages.rb +++ b/lib/gitlab/pages.rb @@ -18,6 +18,11 @@ module Gitlab def secret_path Gitlab.config.pages.secret_file end + + def access_control_is_forced? + ::Gitlab.config.pages.access_control && + ::Gitlab::CurrentSettings.current_application_settings.force_pages_access_control + end end end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index f61290b5687..955a3cc306c 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -332,6 +332,12 @@ msgstr "" msgid "%{openOrClose} %{noteable}" msgstr "" +msgid "%{openedEpics} open, %{closedEpics} closed" +msgstr "" + +msgid "%{openedIssues} open, %{closedIssues} closed" +msgstr "" + msgid "%{percent}%% complete" msgstr "" @@ -841,6 +847,9 @@ msgstr "" msgid "Access to '%{classification_label}' not allowed" msgstr "" +msgid "Access to Pages websites are controlled based on the user's membership to a given project. By checking this box, users will be required to be logged in to have access to all Pages websites in your instance." +msgstr "" + msgid "AccessDropdown|Groups" msgstr "" @@ -6318,6 +6327,9 @@ msgstr "" msgid "Disable group Runners" msgstr "" +msgid "Disable public access to Pages sites" +msgstr "" + msgid "Disable shared Runners" msgstr "" @@ -6999,6 +7011,9 @@ msgstr "" msgid "Environments|Environments are places where code gets deployed, such as staging or production." msgstr "" +msgid "Environments|Install Elastic Stack on your cluster to enable advanced querying capabilities such as full text search." +msgstr "" + msgid "Environments|Job" msgstr "" @@ -7119,9 +7134,6 @@ msgstr "" msgid "Epics let you manage your portfolio of projects more efficiently and with less effort" msgstr "" -msgid "Epics|%{epicsCount} epics and %{issuesCount} issues" -msgstr "" - msgid "Epics|Add an epic" msgstr "" @@ -9754,6 +9766,9 @@ msgstr "" msgid "Iglu registry URL (optional)" msgstr "" +msgid "Image %{imageName} was scheduled for deletion from the registry." +msgstr "" + msgid "ImageDiffViewer|2-up" msgstr "" @@ -18629,9 +18644,6 @@ msgstr "" msgid "This commit was signed with an <strong>unverified</strong> signature." msgstr "" -msgid "This container registry has been scheduled for deletion." -msgstr "" - msgid "This date is after the due date, so this epic won't appear in the roadmap." msgstr "" @@ -20367,6 +20379,9 @@ msgstr "" msgid "Very helpful" msgstr "" +msgid "View Documentation" +msgstr "" + msgid "View app" msgstr "" diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 1559a50d016..ca7b8a4036a 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -106,8 +106,8 @@ describe SearchController do context 'check search term length' do let(:search_queries) do - char_limit = controller.class::NON_ES_SEARCH_CHAR_LIMIT - term_limit = controller.class::NON_ES_SEARCH_TERM_LIMIT + char_limit = SearchService::SEARCH_CHAR_LIMIT + term_limit = SearchService::SEARCH_TERM_LIMIT { chars_under_limit: ('a' * (char_limit - 1)), chars_over_limit: ('a' * (char_limit + 1)), @@ -116,21 +116,15 @@ describe SearchController do } end - where(:es_enabled, :string_name, :expectation) do - true | :chars_under_limit | :not_to_set_flash - true | :chars_over_limit | :not_to_set_flash - true | :terms_under_limit | :not_to_set_flash - true | :terms_over_limit | :not_to_set_flash - false | :chars_under_limit | :not_to_set_flash - false | :chars_over_limit | :set_chars_flash - false | :terms_under_limit | :not_to_set_flash - false | :terms_over_limit | :set_terms_flash + where(:string_name, :expectation) do + :chars_under_limit | :not_to_set_flash + :chars_over_limit | :set_chars_flash + :terms_under_limit | :not_to_set_flash + :terms_over_limit | :set_terms_flash end with_them do it do - allow(Gitlab::CurrentSettings).to receive(:elasticsearch_search?).and_return(es_enabled) - get :show, params: { scope: 'projects', search: search_queries[string_name] } case expectation diff --git a/spec/frontend/clusters/components/applications_spec.js b/spec/frontend/clusters/components/applications_spec.js index a646ea8c700..01e9b04dcd7 100644 --- a/spec/frontend/clusters/components/applications_spec.js +++ b/spec/frontend/clusters/components/applications_spec.js @@ -17,7 +17,6 @@ describe('Applications', () => { gon.features = gon.features || {}; gon.features.enableClusterApplicationElasticStack = true; - gon.features.enableClusterApplicationCrossplane = true; }); afterEach(() => { diff --git a/spec/frontend/registry/list/components/collapsible_container_spec.js b/spec/frontend/registry/list/components/collapsible_container_spec.js index 1768df89432..dda35b55af8 100644 --- a/spec/frontend/registry/list/components/collapsible_container_spec.js +++ b/spec/frontend/registry/list/components/collapsible_container_spec.js @@ -89,19 +89,31 @@ describe('collapsible registry container', () => { }); describe('delete repo', () => { + beforeEach(() => { + const deleteItem = jest.fn().mockResolvedValue(); + const fetchRepos = jest.fn().mockResolvedValue(); + wrapper.setMethods({ deleteItem, fetchRepos }); + }); + it('should be possible to delete a repo', () => { const deleteBtn = findDeleteBtn(); expect(deleteBtn.exists()).toBe(true); }); it('should call deleteItem when confirming deletion', () => { - const deleteItem = jest.fn().mockResolvedValue(); - const fetchRepos = jest.fn().mockResolvedValue(); - wrapper.setMethods({ deleteItem, fetchRepos }); wrapper.vm.handleDeleteRepository(); expect(wrapper.vm.deleteItem).toHaveBeenCalledWith(wrapper.vm.repo); }); + it('should show a flash with a success notice', () => + wrapper.vm.handleDeleteRepository().then(() => { + expect(wrapper.vm.deleteImageConfirmationMessage).toContain(wrapper.vm.repo.name); + expect(createFlash).toHaveBeenCalledWith( + wrapper.vm.deleteImageConfirmationMessage, + 'notice', + ); + })); + it('should show an error when there is API error', () => { const deleteItem = jest.fn().mockRejectedValue('error'); wrapper.setMethods({ deleteItem }); diff --git a/spec/lib/gitlab/pages_spec.rb b/spec/lib/gitlab/pages_spec.rb index aecbc74385e..5889689cb81 100644 --- a/spec/lib/gitlab/pages_spec.rb +++ b/spec/lib/gitlab/pages_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Gitlab::Pages do + using RSpec::Parameterized::TableSyntax + let(:pages_secret) { SecureRandom.random_bytes(Gitlab::Pages::SECRET_LENGTH) } before do @@ -26,4 +28,24 @@ describe Gitlab::Pages do expect(described_class.verify_api_request(headers)).to eq([{ "iss" => "gitlab-pages" }, { "alg" => "HS256" }]) end end + + describe '.access_control_is_forced?' do + subject { described_class.access_control_is_forced? } + + where(:access_control_is_enabled, :access_control_is_forced, :result) do + false | false | false + false | true | false + true | false | false + true | true | true + end + + with_them do + before do + stub_pages_setting(access_control: access_control_is_enabled) + stub_application_setting(force_pages_access_control: access_control_is_forced) + end + + it { is_expected.to eq(result) } + end + end end diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb index 9ce1b8fd895..6a333898955 100644 --- a/spec/models/project_feature_spec.rb +++ b/spec/models/project_feature_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe ProjectFeature do + using RSpec::Parameterized::TableSyntax + let(:project) { create(:project) } let(:user) { create(:user) } @@ -121,13 +123,14 @@ describe ProjectFeature do end context 'public features' do - it "does not allow public for other than pages" do - features = %w(issues wiki builds merge_requests snippets repository) - project_feature = project.project_feature + features = %w(issues wiki builds merge_requests snippets repository) - features.each do |feature| + features.each do |feature| + it "does not allow public access level for #{feature}" do + project_feature = project.project_feature field = "#{feature}_access_level".to_sym project_feature.update_attribute(field, ProjectFeature::PUBLIC) + expect(project_feature.valid?).to be_falsy end end @@ -158,12 +161,13 @@ describe ProjectFeature do end describe 'default pages access level' do - subject { project.project_feature.pages_access_level } + subject { project_feature.pages_access_level } - before do + let(:project_feature) do # project factory overrides all values in project_feature after creation project.project_feature.destroy! project.build_project_feature.save! + project.project_feature end context 'when new project is private' do @@ -182,6 +186,14 @@ describe ProjectFeature do let(:project) { create(:project, :public) } it { is_expected.to eq(ProjectFeature::ENABLED) } + + context 'when access control is forced on the admin level' do + before do + allow(::Gitlab::Pages).to receive(:access_control_is_forced?).and_return(true) + end + + it { is_expected.to eq(ProjectFeature::PRIVATE) } + end end end @@ -189,53 +201,59 @@ describe ProjectFeature do it 'returns true if Pages access controll is not enabled' do stub_config(pages: { access_control: false }) - project_feature = described_class.new + project_feature = described_class.new(pages_access_level: described_class::PRIVATE) expect(project_feature.public_pages?).to eq(true) end - context 'Pages access control is enabled' do + context 'when Pages access control is enabled' do before do stub_config(pages: { access_control: true }) end - it 'returns true if Pages access level is public' do - project_feature = described_class.new(pages_access_level: described_class::PUBLIC) - - expect(project_feature.public_pages?).to eq(true) + where(:project_visibility, :pages_access_level, :result) do + :private | ProjectFeature::PUBLIC | true + :internal | ProjectFeature::PUBLIC | true + :internal | ProjectFeature::ENABLED | false + :public | ProjectFeature::ENABLED | true + :private | ProjectFeature::PRIVATE | false + :public | ProjectFeature::PRIVATE | false end - it 'returns true if Pages access level is enabled and the project is public' do - project = build(:project, :public) - - project_feature = described_class.new(project: project, pages_access_level: described_class::ENABLED) - - expect(project_feature.public_pages?).to eq(true) - end + with_them do + let(:project_feature) do + project = build(:project, project_visibility) + project_feature = project.project_feature + project_feature.update!(pages_access_level: pages_access_level) + project_feature + end - it 'returns false if pages or the project are not public' do - project = build(:project, :private) + it 'properly handles project and Pages visibility settings' do + expect(project_feature.public_pages?).to eq(result) + end - project_feature = described_class.new(project: project, pages_access_level: described_class::ENABLED) + it 'returns false if access_control is forced on the admin level' do + stub_application_setting(force_pages_access_control: true) - expect(project_feature.public_pages?).to eq(false) + expect(project_feature.public_pages?).to eq(false) + end end end + end - describe '#private_pages?' do - subject(:project_feature) { described_class.new } + describe '#private_pages?' do + subject(:project_feature) { described_class.new } - it 'returns false if public_pages? is true' do - expect(project_feature).to receive(:public_pages?).and_return(true) + it 'returns false if public_pages? is true' do + expect(project_feature).to receive(:public_pages?).and_return(true) - expect(project_feature.private_pages?).to eq(false) - end + expect(project_feature.private_pages?).to eq(false) + end - it 'returns true if public_pages? is false' do - expect(project_feature).to receive(:public_pages?).and_return(false) + it 'returns true if public_pages? is false' do + expect(project_feature).to receive(:public_pages?).and_return(false) - expect(project_feature.private_pages?).to eq(true) - end + expect(project_feature.private_pages?).to eq(true) end end |