summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-14 18:08:31 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-14 18:08:31 +0000
commit92f95ccac81911d1fcc32e999a7f1ce04624a56c (patch)
treead207e86b7858ae93a085fbdc04155f5cd469620
parent85e494935a8726dc98bb19ffa584488420e5011e (diff)
downloadgitlab-ce-92f95ccac81911d1fcc32e999a7f1ce04624a56c.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue4
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue23
-rw-r--r--app/assets/javascripts/registry/list/components/collapsible_container.vue9
-rw-r--r--app/controllers/clusters/clusters_controller.rb1
-rw-r--r--app/controllers/search_controller.rb17
-rw-r--r--app/helpers/application_settings_helper.rb1
-rw-r--r--app/helpers/projects_helper.rb1
-rw-r--r--app/models/project_feature.rb10
-rw-r--r--app/services/clusters/applications/base_service.rb2
-rw-r--r--app/services/search_service.rb11
-rw-r--r--app/views/admin/application_settings/_pages.html.haml9
-rw-r--r--changelogs/unreleased/32095-allow-administrators-to-disable-gitlab-pages-access.yml5
-rw-r--r--changelogs/unreleased/ak-bubble-up-log-source.yml5
-rw-r--r--changelogs/unreleased/remove_enable_cluster_application_crossplane_flag.yml5
-rw-r--r--changelogs/unreleased/update_dast_default_branch.yml5
-rw-r--r--db/migrate/20191218122457_add_force_pages_access_control_to_application_settings.rb12
-rw-r--r--db/schema.rb1
-rw-r--r--doc/administration/instance_limits.md8
-rw-r--r--doc/administration/pages/index.md21
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/application_limits.md89
-rw-r--r--doc/user/clusters/applications.md12
-rw-r--r--doc/user/group/epics/index.md1
-rw-r--r--doc/user/project/issues/csv_export.md2
-rw-r--r--doc/user/project/releases/index.md18
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/pages.rb5
-rw-r--r--locale/gitlab.pot27
-rw-r--r--spec/controllers/search_controller_spec.rb20
-rw-r--r--spec/frontend/clusters/components/applications_spec.js1
-rw-r--r--spec/frontend/registry/list/components/collapsible_container_spec.js18
-rw-r--r--spec/lib/gitlab/pages_spec.rb22
-rw-r--r--spec/models/project_feature_spec.rb84
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