summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-04 09:08:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-04 09:08:21 +0000
commiteada495948d07e4a1affffa1fa77bfd9730be1af (patch)
tree12473ea37a4602e06e54289711b8eb089efbf821 /app
parentb41e09c9ce655d61557a3513508952240506b161 (diff)
downloadgitlab-ce-eada495948d07e4a1affffa1fa77bfd9730be1af.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/pages/admin/groups/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/serverless/domains/index.js28
-rw-r--r--app/assets/javascripts/pages/groups/settings/badges/index.js4
-rw-r--r--app/assets/javascripts/pages/import/github/status/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/compare/show/index.js10
-rw-r--r--app/assets/javascripts/pages/projects/cycle_analytics/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/graphs/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/import/jira/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/jobs/terminal/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/pages_domains/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/pages_domains/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js6
-rw-r--r--app/controllers/concerns/dependency_proxy/auth.rb43
-rw-r--r--app/controllers/concerns/dependency_proxy/group_access.rb6
-rw-r--r--app/controllers/groups/dependency_proxies_controller.rb2
-rw-r--r--app/controllers/groups/dependency_proxy/application_controller.rb76
-rw-r--r--app/controllers/groups/dependency_proxy_auth_controller.rb4
-rw-r--r--app/controllers/groups/dependency_proxy_for_containers_controller.rb19
-rw-r--r--app/models/ci/build.rb1
-rw-r--r--app/models/deploy_token.rb15
-rw-r--r--app/models/group_deploy_token.rb9
-rw-r--r--app/models/label.rb4
-rw-r--r--app/models/project.rb3
-rw-r--r--app/models/terraform/state.rb1
-rw-r--r--app/policies/group_policy.rb14
-rw-r--r--app/services/auth/dependency_proxy_authentication_service.rb20
-rw-r--r--app/views/admin/application_settings/_visibility_and_access.html.haml1
-rw-r--r--app/views/layouts/nav/sidebar/_group_menus.html.haml13
29 files changed, 180 insertions, 121 deletions
diff --git a/app/assets/javascripts/pages/admin/groups/edit/index.js b/app/assets/javascripts/pages/admin/groups/edit/index.js
index a4e5df559ff..01e03ed437d 100644
--- a/app/assets/javascripts/pages/admin/groups/edit/index.js
+++ b/app/assets/javascripts/pages/admin/groups/edit/index.js
@@ -1,3 +1,3 @@
import initFilePickers from '~/file_pickers';
-document.addEventListener('DOMContentLoaded', initFilePickers);
+initFilePickers();
diff --git a/app/assets/javascripts/pages/admin/serverless/domains/index.js b/app/assets/javascripts/pages/admin/serverless/domains/index.js
index 5be466886a5..4fab7a1d9cb 100644
--- a/app/assets/javascripts/pages/admin/serverless/domains/index.js
+++ b/app/assets/javascripts/pages/admin/serverless/domains/index.js
@@ -1,19 +1,17 @@
import initSettingsPanels from '~/settings_panels';
-document.addEventListener('DOMContentLoaded', () => {
- // Initialize expandable settings panels
- initSettingsPanels();
+// Initialize expandable settings panels
+initSettingsPanels();
- const domainCard = document.querySelector('.js-domain-cert-show');
- const domainForm = document.querySelector('.js-domain-cert-inputs');
- const domainReplaceButton = document.querySelector('.js-domain-cert-replace-btn');
- const domainSubmitButton = document.querySelector('.js-serverless-domain-submit');
+const domainCard = document.querySelector('.js-domain-cert-show');
+const domainForm = document.querySelector('.js-domain-cert-inputs');
+const domainReplaceButton = document.querySelector('.js-domain-cert-replace-btn');
+const domainSubmitButton = document.querySelector('.js-serverless-domain-submit');
- if (domainReplaceButton && domainCard && domainForm) {
- domainReplaceButton.addEventListener('click', () => {
- domainCard.classList.add('hidden');
- domainForm.classList.remove('hidden');
- domainSubmitButton.removeAttribute('disabled');
- });
- }
-});
+if (domainReplaceButton && domainCard && domainForm) {
+ domainReplaceButton.addEventListener('click', () => {
+ domainCard.classList.add('hidden');
+ domainForm.classList.remove('hidden');
+ domainSubmitButton.removeAttribute('disabled');
+ });
+}
diff --git a/app/assets/javascripts/pages/groups/settings/badges/index.js b/app/assets/javascripts/pages/groups/settings/badges/index.js
index 3f48e4f281e..9dcea737d51 100644
--- a/app/assets/javascripts/pages/groups/settings/badges/index.js
+++ b/app/assets/javascripts/pages/groups/settings/badges/index.js
@@ -5,6 +5,4 @@ import Translate from '~/vue_shared/translate';
Vue.use(Translate);
-document.addEventListener('DOMContentLoaded', () => {
- mountBadgeSettings(GROUP_BADGE);
-});
+mountBadgeSettings(GROUP_BADGE);
diff --git a/app/assets/javascripts/pages/import/github/status/index.js b/app/assets/javascripts/pages/import/github/status/index.js
index 98ddb8b3aa4..4c427b72372 100644
--- a/app/assets/javascripts/pages/import/github/status/index.js
+++ b/app/assets/javascripts/pages/import/github/status/index.js
@@ -1,7 +1,5 @@
import mountImportProjectsTable from '~/import_entities/import_projects';
-document.addEventListener('DOMContentLoaded', () => {
- const mountElement = document.getElementById('import-projects-mount-element');
+const mountElement = document.getElementById('import-projects-mount-element');
- mountImportProjectsTable(mountElement);
-});
+mountImportProjectsTable(mountElement);
diff --git a/app/assets/javascripts/pages/projects/compare/show/index.js b/app/assets/javascripts/pages/projects/compare/show/index.js
index 549e596cb8d..5edaa7f7e51 100644
--- a/app/assets/javascripts/pages/projects/compare/show/index.js
+++ b/app/assets/javascripts/pages/projects/compare/show/index.js
@@ -5,9 +5,7 @@ import initCompareSelector from '~/projects/compare';
initCompareSelector();
-document.addEventListener('DOMContentLoaded', () => {
- new Diff(); // eslint-disable-line no-new
- const paddingTop = 16;
- initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
- GpgBadges.fetch();
-});
+new Diff(); // eslint-disable-line no-new
+const paddingTop = 16;
+initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
+GpgBadges.fetch();
diff --git a/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js b/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js
index 255d05b39be..bef21ef8fdf 100644
--- a/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js
+++ b/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js
@@ -1,3 +1,3 @@
import initCycleAnalytics from '~/cycle_analytics';
-document.addEventListener('DOMContentLoaded', initCycleAnalytics);
+initCycleAnalytics();
diff --git a/app/assets/javascripts/pages/projects/graphs/show/index.js b/app/assets/javascripts/pages/projects/graphs/show/index.js
index 09d9c78c446..4f5a5bfe6fe 100644
--- a/app/assets/javascripts/pages/projects/graphs/show/index.js
+++ b/app/assets/javascripts/pages/projects/graphs/show/index.js
@@ -1,3 +1,3 @@
import initContributorsGraphs from '~/contributors';
-document.addEventListener('DOMContentLoaded', initContributorsGraphs);
+initContributorsGraphs();
diff --git a/app/assets/javascripts/pages/projects/import/jira/index.js b/app/assets/javascripts/pages/projects/import/jira/index.js
index cb7a7bde55d..5876e5283b5 100644
--- a/app/assets/javascripts/pages/projects/import/jira/index.js
+++ b/app/assets/javascripts/pages/projects/import/jira/index.js
@@ -1,3 +1,3 @@
import mountJiraImportApp from '~/jira_import';
-document.addEventListener('DOMContentLoaded', mountJiraImportApp);
+mountJiraImportApp();
diff --git a/app/assets/javascripts/pages/projects/issues/edit/index.js b/app/assets/javascripts/pages/projects/issues/edit/index.js
index aecc6484b26..48afd2142ee 100644
--- a/app/assets/javascripts/pages/projects/issues/edit/index.js
+++ b/app/assets/javascripts/pages/projects/issues/edit/index.js
@@ -1,3 +1,3 @@
import initForm from 'ee_else_ce/pages/projects/issues/form';
-document.addEventListener('DOMContentLoaded', initForm);
+initForm();
diff --git a/app/assets/javascripts/pages/projects/jobs/terminal/index.js b/app/assets/javascripts/pages/projects/jobs/terminal/index.js
index 7129e24cee1..d42c163a41b 100644
--- a/app/assets/javascripts/pages/projects/jobs/terminal/index.js
+++ b/app/assets/javascripts/pages/projects/jobs/terminal/index.js
@@ -1,3 +1,3 @@
import initTerminal from '~/terminal/';
-document.addEventListener('DOMContentLoaded', initTerminal);
+initTerminal();
diff --git a/app/assets/javascripts/pages/projects/pages_domains/new/index.js b/app/assets/javascripts/pages/projects/pages_domains/new/index.js
index 27e4433ad4d..17fa49a46e0 100644
--- a/app/assets/javascripts/pages/projects/pages_domains/new/index.js
+++ b/app/assets/javascripts/pages/projects/pages_domains/new/index.js
@@ -1,3 +1,3 @@
import initForm from '~/pages/projects/pages_domains/form';
-document.addEventListener('DOMContentLoaded', initForm);
+initForm();
diff --git a/app/assets/javascripts/pages/projects/pages_domains/show/index.js b/app/assets/javascripts/pages/projects/pages_domains/show/index.js
index 27e4433ad4d..17fa49a46e0 100644
--- a/app/assets/javascripts/pages/projects/pages_domains/show/index.js
+++ b/app/assets/javascripts/pages/projects/pages_domains/show/index.js
@@ -1,3 +1,3 @@
import initForm from '~/pages/projects/pages_domains/form';
-document.addEventListener('DOMContentLoaded', initForm);
+initForm();
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
index 40730ec7e60..cd4bc35e74e 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import PipelineSchedulesCallout from '../shared/components/pipeline_schedules_callout.vue';
-document.addEventListener('DOMContentLoaded', () => {
+function initPipelineSchedules() {
const el = document.getElementById('pipeline-schedules-callout');
if (!el) {
@@ -21,4 +21,6 @@ document.addEventListener('DOMContentLoaded', () => {
return createElement(PipelineSchedulesCallout);
},
});
-});
+}
+
+initPipelineSchedules();
diff --git a/app/controllers/concerns/dependency_proxy/auth.rb b/app/controllers/concerns/dependency_proxy/auth.rb
deleted file mode 100644
index 1276feedba6..00000000000
--- a/app/controllers/concerns/dependency_proxy/auth.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module DependencyProxy
- module Auth
- extend ActiveSupport::Concern
-
- included do
- # We disable `authenticate_user!` since the `DependencyProxy::Auth` performs auth using JWT token
- skip_before_action :authenticate_user!, raise: false
- prepend_before_action :authenticate_user_from_jwt_token!
- end
-
- def authenticate_user_from_jwt_token!
- return unless dependency_proxy_for_private_groups?
-
- authenticate_with_http_token do |token, _|
- user = user_from_token(token)
- sign_in(user) if user
- end
-
- request_bearer_token! unless current_user
- end
-
- private
-
- def dependency_proxy_for_private_groups?
- Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true)
- end
-
- def request_bearer_token!
- # unfortunately, we cannot use https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html#method-i-authentication_request
- response.headers['WWW-Authenticate'] = ::DependencyProxy::Registry.authenticate_header
- render plain: '', status: :unauthorized
- end
-
- def user_from_token(token)
- token_payload = DependencyProxy::AuthTokenService.decoded_token_payload(token)
- User.find(token_payload['user_id'])
- rescue JWT::DecodeError, JWT::ExpiredSignature, JWT::ImmatureSignature
- nil
- end
- end
-end
diff --git a/app/controllers/concerns/dependency_proxy/group_access.rb b/app/controllers/concerns/dependency_proxy/group_access.rb
index 2a923d02752..07aca72b22f 100644
--- a/app/controllers/concerns/dependency_proxy/group_access.rb
+++ b/app/controllers/concerns/dependency_proxy/group_access.rb
@@ -12,15 +12,15 @@ module DependencyProxy
private
def verify_dependency_proxy_enabled!
- render_404 unless group.dependency_proxy_feature_available?
+ render_404 unless group&.dependency_proxy_feature_available?
end
def authorize_read_dependency_proxy!
- access_denied! unless can?(current_user, :read_dependency_proxy, group)
+ access_denied! unless can?(auth_user, :read_dependency_proxy, group)
end
def authorize_admin_dependency_proxy!
- access_denied! unless can?(current_user, :admin_dependency_proxy, group)
+ access_denied! unless can?(auth_user, :admin_dependency_proxy, group)
end
end
end
diff --git a/app/controllers/groups/dependency_proxies_controller.rb b/app/controllers/groups/dependency_proxies_controller.rb
index b896b240daf..b037aa52939 100644
--- a/app/controllers/groups/dependency_proxies_controller.rb
+++ b/app/controllers/groups/dependency_proxies_controller.rb
@@ -2,7 +2,7 @@
module Groups
class DependencyProxiesController < Groups::ApplicationController
- include DependencyProxy::GroupAccess
+ include ::DependencyProxy::GroupAccess
before_action :authorize_admin_dependency_proxy!, only: :update
before_action :dependency_proxy
diff --git a/app/controllers/groups/dependency_proxy/application_controller.rb b/app/controllers/groups/dependency_proxy/application_controller.rb
new file mode 100644
index 00000000000..c6484ffb5f1
--- /dev/null
+++ b/app/controllers/groups/dependency_proxy/application_controller.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Groups
+ module DependencyProxy
+ class ApplicationController < ::ApplicationController
+ EMPTY_AUTH_RESULT = Gitlab::Auth::Result.new(nil, nil, nil, nil).freeze
+
+ delegate :actor, to: :@authentication_result, allow_nil: true
+
+ # This allows auth_user to be set in the base ApplicationController
+ alias_method :authenticated_user, :actor
+
+ # We disable `authenticate_user!` since the `DependencyProxy::ApplicationController` performs auth using JWT token
+ skip_before_action :authenticate_user!, raise: false
+
+ prepend_before_action :authenticate_user_from_jwt_token!
+
+ def authenticate_user_from_jwt_token!
+ return unless dependency_proxy_for_private_groups?
+
+ if Feature.enabled?(:dependency_proxy_deploy_tokens)
+ authenticate_with_http_token do |token, _|
+ @authentication_result = EMPTY_AUTH_RESULT
+
+ found_user = user_from_token(token)
+ sign_in(found_user) if found_user.is_a?(User)
+ end
+
+ request_bearer_token! unless authenticated_user
+ else
+ authenticate_with_http_token do |token, _|
+ user = user_from_token(token)
+ sign_in(user) if user
+ end
+
+ request_bearer_token! unless current_user
+ end
+ end
+
+ private
+
+ def dependency_proxy_for_private_groups?
+ Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true)
+ end
+
+ def request_bearer_token!
+ # unfortunately, we cannot use https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html#method-i-authentication_request
+ response.headers['WWW-Authenticate'] = ::DependencyProxy::Registry.authenticate_header
+ render plain: '', status: :unauthorized
+ end
+
+ def user_from_token(token)
+ token_payload = ::DependencyProxy::AuthTokenService.decoded_token_payload(token)
+ return User.find(token_payload['user_id']) unless Feature.enabled?(:dependency_proxy_deploy_tokens)
+
+ if token_payload['user_id']
+ token_user = User.find(token_payload['user_id'])
+ return unless token_user
+
+ @authentication_result = Gitlab::Auth::Result.new(token_user, nil, :user, [])
+ return token_user
+ elsif token_payload['deploy_token']
+ deploy_token = DeployToken.active.find_by_token(token_payload['deploy_token'])
+ return unless deploy_token
+
+ @authentication_result = Gitlab::Auth::Result.new(deploy_token, nil, :deploy_token, [])
+ return deploy_token
+ end
+
+ nil
+ rescue JWT::DecodeError, JWT::ExpiredSignature, JWT::ImmatureSignature
+ nil
+ end
+ end
+ end
+end
diff --git a/app/controllers/groups/dependency_proxy_auth_controller.rb b/app/controllers/groups/dependency_proxy_auth_controller.rb
index e3e9bd88e24..60b2371fa9a 100644
--- a/app/controllers/groups/dependency_proxy_auth_controller.rb
+++ b/app/controllers/groups/dependency_proxy_auth_controller.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
-class Groups::DependencyProxyAuthController < ApplicationController
- include DependencyProxy::Auth
-
+class Groups::DependencyProxyAuthController < ::Groups::DependencyProxy::ApplicationController
feature_category :dependency_proxy
def authenticate
diff --git a/app/controllers/groups/dependency_proxy_for_containers_controller.rb b/app/controllers/groups/dependency_proxy_for_containers_controller.rb
index e341b9d75e0..f7dc552bd3e 100644
--- a/app/controllers/groups/dependency_proxy_for_containers_controller.rb
+++ b/app/controllers/groups/dependency_proxy_for_containers_controller.rb
@@ -1,11 +1,12 @@
# frozen_string_literal: true
-class Groups::DependencyProxyForContainersController < Groups::ApplicationController
- include DependencyProxy::Auth
+class Groups::DependencyProxyForContainersController < ::Groups::DependencyProxy::ApplicationController
+ include Gitlab::Utils::StrongMemoize
include DependencyProxy::GroupAccess
include SendFileUpload
include ::PackagesHelper # for event tracking
+ before_action :ensure_group
before_action :ensure_token_granted!
before_action :ensure_feature_enabled!
@@ -24,7 +25,7 @@ class Groups::DependencyProxyForContainersController < Groups::ApplicationContro
content_type = result[:manifest].content_type
event_name = tracking_event_name(object_type: :manifest, from_cache: result[:from_cache])
- track_package_event(event_name, :dependency_proxy, namespace: group, user: current_user)
+ track_package_event(event_name, :dependency_proxy, namespace: group, user: auth_user)
send_upload(
result[:manifest].file,
proxy: true,
@@ -42,7 +43,7 @@ class Groups::DependencyProxyForContainersController < Groups::ApplicationContro
if result[:status] == :success
event_name = tracking_event_name(object_type: :blob, from_cache: result[:from_cache])
- track_package_event(event_name, :dependency_proxy, namespace: group, user: current_user)
+ track_package_event(event_name, :dependency_proxy, namespace: group, user: auth_user)
send_upload(result[:blob].file)
else
head result[:http_status]
@@ -51,6 +52,12 @@ class Groups::DependencyProxyForContainersController < Groups::ApplicationContro
private
+ def group
+ strong_memoize(:group) do
+ Group.find_by_full_path(params[:group_id], follow_redirects: request.get?)
+ end
+ end
+
def image
params[:image]
end
@@ -71,6 +78,10 @@ class Groups::DependencyProxyForContainersController < Groups::ApplicationContro
group.dependency_proxy_setting || group.create_dependency_proxy_setting
end
+ def ensure_group
+ render_404 unless group
+ end
+
def ensure_feature_enabled!
render_404 unless dependency_proxy.enabled
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 0d5d63371fc..537d18646c5 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -128,7 +128,6 @@ module Ci
end
scope :eager_load_job_artifacts, -> { includes(:job_artifacts) }
- scope :eager_load_job_artifacts_archive, -> { includes(:job_artifacts_archive) }
scope :eager_load_tags, -> { includes(:tags) }
scope :eager_load_everything, -> do
diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb
index 5fa9f2ef9f9..326d3fb8470 100644
--- a/app/models/deploy_token.rb
+++ b/app/models/deploy_token.rb
@@ -10,6 +10,7 @@ class DeployToken < ApplicationRecord
AVAILABLE_SCOPES = %i(read_repository read_registry write_registry
read_package_registry write_package_registry).freeze
GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'
+ REQUIRED_DEPENDENCY_PROXY_SCOPES = %i[read_registry write_registry].freeze
default_value_for(:expires_at) { Forever.date }
@@ -46,6 +47,12 @@ class DeployToken < ApplicationRecord
active.find_by(name: GITLAB_DEPLOY_TOKEN_NAME)
end
+ def valid_for_dependency_proxy?
+ group_type? &&
+ active? &&
+ REQUIRED_DEPENDENCY_PROXY_SCOPES.all? { |scope| scope.in?(scopes) }
+ end
+
def revoke!
update!(revoked: true)
end
@@ -73,6 +80,14 @@ class DeployToken < ApplicationRecord
holder.has_access_to?(requested_project)
end
+ def has_access_to_group?(requested_group)
+ return false unless active?
+ return false unless group_type?
+ return false unless holder
+
+ holder.has_access_to_group?(requested_group)
+ end
+
# This is temporal. Currently we limit DeployToken
# to a single project or group, later we're going to
# extend that to be for multiple projects and namespaces.
diff --git a/app/models/group_deploy_token.rb b/app/models/group_deploy_token.rb
index 084a8672460..d9667e7c74d 100644
--- a/app/models/group_deploy_token.rb
+++ b/app/models/group_deploy_token.rb
@@ -11,9 +11,14 @@ class GroupDeployToken < ApplicationRecord
def has_access_to?(requested_project)
requested_project_group = requested_project&.group
return false unless requested_project_group
- return true if requested_project_group.id == group_id
- requested_project_group
+ has_access_to_group?(requested_project_group)
+ end
+
+ def has_access_to_group?(requested_group)
+ return true if requested_group.id == group_id
+
+ requested_group
.ancestors
.where(id: group_id)
.exists?
diff --git a/app/models/label.rb b/app/models/label.rb
index 1a07620f944..a46d6bc5c0f 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -9,10 +9,6 @@ class Label < ApplicationRecord
include Sortable
include FromUnion
include Presentable
- include IgnorableColumns
-
- # TODO: Project#create_labels can remove column exception when this column is dropped from all envs
- ignore_column :remove_on_close, remove_with: '14.1', remove_after: '2021-06-22'
cache_markdown_field :description, pipeline: :single_line
diff --git a/app/models/project.rb b/app/models/project.rb
index 5cad761ce2c..0d32138b08c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1427,8 +1427,7 @@ class Project < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def create_labels
Label.templates.each do |label|
- # TODO: remove_on_close exception can be removed after the column is dropped from all envs
- params = label.attributes.except('id', 'template', 'created_at', 'updated_at', 'type', 'remove_on_close')
+ params = label.attributes.except('id', 'template', 'created_at', 'updated_at', 'type')
Labels::FindOrCreateService.new(nil, self, params).execute(skip_authorization: true)
end
end
diff --git a/app/models/terraform/state.rb b/app/models/terraform/state.rb
index 8aeeae1330c..8c3b85ac4c3 100644
--- a/app/models/terraform/state.rb
+++ b/app/models/terraform/state.rb
@@ -20,7 +20,6 @@ module Terraform
foreign_key: :terraform_state_id,
inverse_of: :terraform_state
- scope :versioning_not_enabled, -> { where(versioning_enabled: false) }
scope :ordered_by_name, -> { order(:name) }
scope :with_name, -> (name) { where(name: name) }
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 7e07cd12ede..fa7834c10df 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -50,6 +50,14 @@ class GroupPolicy < BasePolicy
@subject.dependency_proxy_feature_available?
end
+ condition(:dependency_proxy_access_allowed) do
+ if Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true)
+ access_level >= GroupMember::REPORTER || valid_dependency_proxy_deploy_token
+ else
+ can?(:read_group)
+ end
+ end
+
desc "Deploy token with read_package_registry scope"
condition(:read_package_registry_deploy_token) do
@user.is_a?(DeployToken) && @user.groups.include?(@subject) && @user.read_package_registry
@@ -212,7 +220,7 @@ class GroupPolicy < BasePolicy
enable :read_group
end
- rule { can?(:read_group) & dependency_proxy_available }
+ rule { dependency_proxy_access_allowed & dependency_proxy_available }
.enable :read_dependency_proxy
rule { developer & dependency_proxy_available }
@@ -260,6 +268,10 @@ class GroupPolicy < BasePolicy
def resource_access_token_creation_allowed?
resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
end
+
+ def valid_dependency_proxy_deploy_token
+ @user.is_a?(DeployToken) && @user&.valid_for_dependency_proxy? && @user&.has_access_to_group?(@subject)
+ end
end
GroupPolicy.prepend_mod_with('GroupPolicy')
diff --git a/app/services/auth/dependency_proxy_authentication_service.rb b/app/services/auth/dependency_proxy_authentication_service.rb
index 4335fb0bd06..164594d6f6c 100644
--- a/app/services/auth/dependency_proxy_authentication_service.rb
+++ b/app/services/auth/dependency_proxy_authentication_service.rb
@@ -8,10 +8,7 @@ module Auth
def execute(authentication_abilities:)
return error('dependency proxy not enabled', 404) unless ::Gitlab.config.dependency_proxy.enabled
-
- # Because app/controllers/concerns/dependency_proxy/auth.rb consumes this
- # JWT only as `User.find`, we currently only allow User (not DeployToken, etc)
- return error('access forbidden', 403) unless current_user
+ return error('access forbidden', 403) unless valid_user_actor?
{ token: authorized_token.encoded }
end
@@ -36,11 +33,24 @@ module Auth
private
+ def valid_user_actor?
+ current_user || valid_deploy_token?
+ end
+
+ def valid_deploy_token?
+ deploy_token && deploy_token.valid_for_dependency_proxy?
+ end
+
def authorized_token
JSONWebToken::HMACToken.new(self.class.secret).tap do |token|
- token['user_id'] = current_user.id
+ token['user_id'] = current_user.id if current_user
+ token['deploy_token'] = deploy_token.token if deploy_token
token.expire_time = self.class.token_expire_at
end
end
+
+ def deploy_token
+ params[:deploy_token]
+ end
end
end
diff --git a/app/views/admin/application_settings/_visibility_and_access.html.haml b/app/views/admin/application_settings/_visibility_and_access.html.haml
index 4bf47c3d60d..b6266c3ea34 100644
--- a/app/views/admin/application_settings/_visibility_and_access.html.haml
+++ b/app/views/admin/application_settings/_visibility_and_access.html.haml
@@ -9,6 +9,7 @@
= f.label s_('ProjectCreationLevel|Default project creation protection'), class: 'label-bold'
= f.select :default_project_creation, options_for_select(Gitlab::Access.project_creation_options, @application_setting.default_project_creation), {}, class: 'form-control'
= render_if_exists 'admin/application_settings/default_project_deletion_protection_setting', form: f
+ = render_if_exists 'admin/application_settings/default_delayed_project_deletion_setting', form: f
= render_if_exists 'admin/application_settings/default_project_deletion_adjourned_period_setting', form: f
.form-group.visibility-level-setting
= f.label :default_project_visibility, class: 'label-bold'
diff --git a/app/views/layouts/nav/sidebar/_group_menus.html.haml b/app/views/layouts/nav/sidebar/_group_menus.html.haml
index 42114287cdf..4f171f2777a 100644
--- a/app/views/layouts/nav/sidebar/_group_menus.html.haml
+++ b/app/views/layouts/nav/sidebar/_group_menus.html.haml
@@ -1,16 +1,3 @@
-- if group_sidebar_link?(:kubernetes)
- = nav_link(controller: [:clusters]) do
- = link_to group_clusters_path(@group) do
- .nav-icon-container
- = sprite_icon('cloud-gear')
- %span.nav-item-name
- = _('Kubernetes')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: [:clusters], html_options: { class: "fly-out-top-item" } ) do
- = link_to group_clusters_path(@group), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do
- %strong.fly-out-top-item-name
- = _('Kubernetes')
-
= render 'groups/sidebar/packages'
= render 'layouts/nav/sidebar/analytics_links', links: group_analytics_navbar_links(@group, current_user)