diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-26 18:08:03 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-26 18:08:03 +0000 |
commit | dc003cd08b4cb72fecbb03aa978ea0c53c03aeb4 (patch) | |
tree | 5e77ce228c33619201ac6706b9789d4a2eed2a3b /app | |
parent | e80e0dd64fbb04f60394cb1bb08e17dbcb22b8ce (diff) | |
download | gitlab-ce-dc003cd08b4cb72fecbb03aa978ea0c53c03aeb4.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/clusters/components/applications.vue | 5 | ||||
-rw-r--r-- | app/assets/javascripts/frequent_items/utils.js | 21 | ||||
-rw-r--r-- | app/assets/javascripts/pages/projects/snippets/show/index.js | 20 | ||||
-rw-r--r-- | app/assets/javascripts/pages/snippets/show/index.js | 20 | ||||
-rw-r--r-- | app/assets/javascripts/snippet/snippet_show.js | 19 | ||||
-rw-r--r-- | app/controllers/clusters/base_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/concerns/hotlink_interceptor.rb | 15 | ||||
-rw-r--r-- | app/controllers/import/fogbugz_controller.rb | 18 | ||||
-rw-r--r-- | app/controllers/projects/mirrors_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/repositories_controller.rb | 2 | ||||
-rw-r--r-- | app/models/group.rb | 3 | ||||
-rw-r--r-- | app/models/issue.rb | 6 | ||||
-rw-r--r-- | app/serializers/merge_request_poll_widget_entity.rb | 2 | ||||
-rw-r--r-- | app/uploaders/object_storage.rb | 2 | ||||
-rw-r--r-- | app/views/projects/mirrors/_mirror_repos.html.haml | 50 |
15 files changed, 119 insertions, 70 deletions
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index f4d37c8c5f3..219825b1c01 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -107,8 +107,12 @@ export default { isProjectCluster() { return this.type === CLUSTER_TYPE.PROJECT; }, + managedAppsLocalTillerEnabled() { + return Boolean(gon.features?.managedAppsLocalTiller); + }, helmInstalled() { return ( + this.managedAppsLocalTillerEnabled || this.applications.helm.status === APPLICATION_STATUS.INSTALLED || this.applications.helm.status === APPLICATION_STATUS.UPDATED ); @@ -270,6 +274,7 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity <div class="cluster-application-list prepend-top-10"> <application-row + v-if="!managedAppsLocalTillerEnabled" id="helm" :logo-url="helmLogo" :title="applications.helm.title" diff --git a/app/assets/javascripts/frequent_items/utils.js b/app/assets/javascripts/frequent_items/utils.js index a992480c22b..d4b7ffdcbe1 100644 --- a/app/assets/javascripts/frequent_items/utils.js +++ b/app/assets/javascripts/frequent_items/utils.js @@ -45,8 +45,19 @@ export const updateExistingFrequentItem = (frequentItem, item) => { }; }; -export const sanitizeItem = item => ({ - ...item, - name: sanitize(item.name.toString(), { allowedTags: [] }), - namespace: sanitize(item.namespace.toString(), { allowedTags: [] }), -}); +export const sanitizeItem = item => { + // Only sanitize if the key exists on the item + const maybeSanitize = key => { + if (!Object.prototype.hasOwnProperty.call(item, key)) { + return {}; + } + + return { [key]: sanitize(item[key].toString(), { allowedTags: [] }) }; + }; + + return { + ...item, + ...maybeSanitize('name'), + ...maybeSanitize('namespace'), + }; +}; diff --git a/app/assets/javascripts/pages/projects/snippets/show/index.js b/app/assets/javascripts/pages/projects/snippets/show/index.js index e49d46ea97b..f955a41e18a 100644 --- a/app/assets/javascripts/pages/projects/snippets/show/index.js +++ b/app/assets/javascripts/pages/projects/snippets/show/index.js @@ -1,19 +1 @@ -import initNotes from '~/init_notes'; -import ZenMode from '~/zen_mode'; -import LineHighlighter from '~/line_highlighter'; -import BlobViewer from '~/blob/viewer'; -import snippetEmbed from '~/snippet/snippet_embed'; -import { SnippetShowInit } from '~/snippets'; - -document.addEventListener('DOMContentLoaded', () => { - if (!gon.features.snippetsVue) { - new LineHighlighter(); // eslint-disable-line no-new - new BlobViewer(); // eslint-disable-line no-new - initNotes(); - new ZenMode(); // eslint-disable-line no-new - snippetEmbed(); - } else { - SnippetShowInit(); - initNotes(); - } -}); +import '~/snippet/snippet_show'; diff --git a/app/assets/javascripts/pages/snippets/show/index.js b/app/assets/javascripts/pages/snippets/show/index.js index 9a463b4762b..f955a41e18a 100644 --- a/app/assets/javascripts/pages/snippets/show/index.js +++ b/app/assets/javascripts/pages/snippets/show/index.js @@ -1,19 +1 @@ -import LineHighlighter from '~/line_highlighter'; -import BlobViewer from '~/blob/viewer'; -import ZenMode from '~/zen_mode'; -import initNotes from '~/init_notes'; -import snippetEmbed from '~/snippet/snippet_embed'; -import { SnippetShowInit } from '~/snippets'; - -document.addEventListener('DOMContentLoaded', () => { - if (!gon.features.snippetsVue) { - new LineHighlighter(); // eslint-disable-line no-new - new BlobViewer(); // eslint-disable-line no-new - initNotes(); - new ZenMode(); // eslint-disable-line no-new - snippetEmbed(); - } else { - SnippetShowInit(); - initNotes(); - } -}); +import '~/snippet/snippet_show'; diff --git a/app/assets/javascripts/snippet/snippet_show.js b/app/assets/javascripts/snippet/snippet_show.js new file mode 100644 index 00000000000..9a463b4762b --- /dev/null +++ b/app/assets/javascripts/snippet/snippet_show.js @@ -0,0 +1,19 @@ +import LineHighlighter from '~/line_highlighter'; +import BlobViewer from '~/blob/viewer'; +import ZenMode from '~/zen_mode'; +import initNotes from '~/init_notes'; +import snippetEmbed from '~/snippet/snippet_embed'; +import { SnippetShowInit } from '~/snippets'; + +document.addEventListener('DOMContentLoaded', () => { + if (!gon.features.snippetsVue) { + new LineHighlighter(); // eslint-disable-line no-new + new BlobViewer(); // eslint-disable-line no-new + initNotes(); + new ZenMode(); // eslint-disable-line no-new + snippetEmbed(); + } else { + SnippetShowInit(); + initNotes(); + } +}); diff --git a/app/controllers/clusters/base_controller.rb b/app/controllers/clusters/base_controller.rb index 188805c6106..8c13cc67be2 100644 --- a/app/controllers/clusters/base_controller.rb +++ b/app/controllers/clusters/base_controller.rb @@ -6,6 +6,10 @@ class Clusters::BaseController < ApplicationController skip_before_action :authenticate_user! before_action :authorize_read_cluster! + before_action do + push_frontend_feature_flag(:managed_apps_local_tiller) + end + helper_method :clusterable private diff --git a/app/controllers/concerns/hotlink_interceptor.rb b/app/controllers/concerns/hotlink_interceptor.rb new file mode 100644 index 00000000000..712a10eab98 --- /dev/null +++ b/app/controllers/concerns/hotlink_interceptor.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module HotlinkInterceptor + extend ActiveSupport::Concern + + def intercept_hotlinking! + return render_406 if Gitlab::HotlinkingDetector.intercept_hotlinking?(request) + end + + private + + def render_406 + head :not_acceptable + end +end diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index 28ead8d44da..4fb6efde7ff 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -3,6 +3,7 @@ class Import::FogbugzController < Import::BaseController before_action :verify_fogbugz_import_enabled before_action :user_map, only: [:new_user_map, :create_user_map] + before_action :verify_blocked_uri, only: :callback rescue_from Fogbugz::AuthenticationException, with: :fogbugz_unauthorized @@ -106,4 +107,21 @@ class Import::FogbugzController < Import::BaseController def verify_fogbugz_import_enabled render_404 unless fogbugz_import_enabled? end + + def verify_blocked_uri + Gitlab::UrlBlocker.validate!( + params[:uri], + { + allow_localhost: allow_local_requests?, + allow_local_network: allow_local_requests?, + schemes: %w(http https) + } + ) + rescue Gitlab::UrlBlocker::BlockedUrlError => e + redirect_to new_import_fogbugz_url, alert: _('Specified URL cannot be used: "%{reason}"') % { reason: e.message } + end + + def allow_local_requests? + Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services? + end end diff --git a/app/controllers/projects/mirrors_controller.rb b/app/controllers/projects/mirrors_controller.rb index dd1ea151de7..936f89e58e7 100644 --- a/app/controllers/projects/mirrors_controller.rb +++ b/app/controllers/projects/mirrors_controller.rb @@ -67,7 +67,7 @@ class Projects::MirrorsController < Projects::ApplicationController end def check_mirror_available! - Gitlab::CurrentSettings.current_application_settings.mirror_available || current_user&.admin? + render_404 unless can?(current_user, :admin_remote_mirror, project) end def mirror_params_attributes diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index 1cb9e1d2c9b..303326bbe23 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -4,12 +4,14 @@ class Projects::RepositoriesController < Projects::ApplicationController include ExtractsPath include StaticObjectExternalStorage include Gitlab::RateLimitHelpers + include HotlinkInterceptor prepend_before_action(only: [:archive]) { authenticate_sessionless_user!(:archive) } # Authorize before_action :require_non_empty_project, except: :create before_action :archive_rate_limit!, only: :archive + before_action :intercept_hotlinking!, only: :archive before_action :assign_archive_vars, only: :archive before_action :assign_append_sha, only: :archive before_action :authorize_download_code! diff --git a/app/models/group.rb b/app/models/group.rb index da69f7cc11e..5e6e3032251 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -70,6 +70,9 @@ class Group < Namespace validates :variables, variable_duplicates: true validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 } + validates :name, + format: { with: Gitlab::Regex.group_name_regex, + message: Gitlab::Regex.group_name_regex_message } add_authentication_token_field :runners_token, encrypted: -> { Feature.enabled?(:groups_tokens_optional_encryption, default_enabled: true) ? :optional : :required } diff --git a/app/models/issue.rb b/app/models/issue.rb index 0f00a78c728..f414be51065 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -326,10 +326,8 @@ class Issue < ApplicationRecord true elsif project.owner == user true - elsif confidential? - author == user || - assignees.include?(user) || - project.team.member?(user, Gitlab::Access::REPORTER) + elsif confidential? && !assignee_or_author?(user) + project.team.member?(user, Gitlab::Access::REPORTER) else project.public? || project.internal? && !user.external? || diff --git a/app/serializers/merge_request_poll_widget_entity.rb b/app/serializers/merge_request_poll_widget_entity.rb index a45026ea016..18e8ec0e7d1 100644 --- a/app/serializers/merge_request_poll_widget_entity.rb +++ b/app/serializers/merge_request_poll_widget_entity.rb @@ -53,7 +53,7 @@ class MergeRequestPollWidgetEntity < Grape::Entity # CI related expose :has_ci?, as: :has_ci - expose :ci_status do |merge_request| + expose :ci_status, if: -> (mr, _) { presenter(mr).can_read_pipeline? } do |merge_request| presenter(merge_request).ci_status end diff --git a/app/uploaders/object_storage.rb b/app/uploaders/object_storage.rb index 0e83932ff26..7db1b29ca9a 100644 --- a/app/uploaders/object_storage.rb +++ b/app/uploaders/object_storage.rb @@ -318,7 +318,7 @@ module ObjectStorage def cache!(new_file = sanitized_file) # We intercept ::UploadedFile which might be stored on remote storage # We use that for "accelerated" uploads, where we store result on remote storage - if new_file.is_a?(::UploadedFile) && new_file.remote_id + if new_file.is_a?(::UploadedFile) && new_file.remote_id.present? return cache_remote_file!(new_file.remote_id, new_file.original_filename) end diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index 80d2d2afada..4004c4f4b07 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -1,7 +1,9 @@ - expanded = expanded_by_default? - protocols = Gitlab::UrlSanitizer::ALLOWED_SCHEMES.join('|') +- mirror_settings_enabled = can?(current_user, :admin_remote_mirror, @project) +- mirror_settings_class = "#{'expanded' if expanded} #{'js-mirror-settings' if mirror_settings_enabled}".strip -%section.settings.project-mirror-settings.js-mirror-settings.no-animate#js-push-remote-settings{ class: ('expanded' if expanded), data: { qa_selector: 'mirroring_repositories_settings_section' } } +%section.settings.project-mirror-settings.no-animate#js-push-remote-settings{ class: mirror_settings_class, data: { qa_selector: 'mirroring_repositories_settings_section' } } .settings-header %h4= _('Mirroring repositories') %button.btn.js-settings-toggle @@ -11,26 +13,32 @@ = link_to _('Read more'), help_page_path('workflow/repository_mirroring'), target: '_blank' .settings-content - = form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| - .panel.panel-default - .panel-body - %div= form_errors(@project) + - if mirror_settings_enabled + = form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| + .panel.panel-default + .panel-body + %div= form_errors(@project) - .form-group.has-feedback - = label_tag :url, _('Git repository URL'), class: 'label-light' - = text_field_tag :url, nil, class: 'form-control js-mirror-url js-repo-url qa-mirror-repository-url-input', placeholder: _('Input your repository URL'), required: true, pattern: "(#{protocols}):\/\/.+", autocomplete: 'new-password' + .form-group.has-feedback + = label_tag :url, _('Git repository URL'), class: 'label-light' + = text_field_tag :url, nil, class: 'form-control js-mirror-url js-repo-url qa-mirror-repository-url-input', placeholder: _('Input your repository URL'), required: true, pattern: "(#{protocols}):\/\/.+", autocomplete: 'new-password' - = render 'projects/mirrors/instructions' + = render 'projects/mirrors/instructions' - = render 'projects/mirrors/mirror_repos_form', f: f + = render 'projects/mirrors/mirror_repos_form', f: f - .form-check.append-bottom-10 - = check_box_tag :only_protected_branches, '1', false, class: 'js-mirror-protected form-check-input' - = label_tag :only_protected_branches, _('Only mirror protected branches'), class: 'form-check-label' - = link_to icon('question-circle'), help_page_path('user/project/protected_branches'), target: '_blank' + .form-check.append-bottom-10 + = check_box_tag :only_protected_branches, '1', false, class: 'js-mirror-protected form-check-input' + = label_tag :only_protected_branches, _('Only mirror protected branches'), class: 'form-check-label' + = link_to icon('question-circle'), help_page_path('user/project/protected_branches'), target: '_blank' - .panel-footer - = f.submit _('Mirror repository'), class: 'btn btn-success js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror + .panel-footer + = f.submit _('Mirror repository'), class: 'btn btn-success js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror + - else + .gl-alert.gl-alert-info{ role: 'alert' } + = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-body + = _('Mirror settings are only available to GitLab administrators.') .panel.panel-default .table-responsive @@ -61,8 +69,10 @@ - if mirror.last_error.present? .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error') %td - .btn-group.mirror-actions-group.pull-right{ role: 'group' } - - if mirror.ssh_key_auth? - = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button') - = render 'shared/remote_mirror_update_button', remote_mirror: mirror + - if mirror_settings_enabled + .btn-group.mirror-actions-group.pull-right{ role: 'group' } + - if mirror.ssh_key_auth? + = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button') + = render 'shared/remote_mirror_update_button', remote_mirror: mirror %button.js-delete-mirror.qa-delete-mirror.rspec-delete-mirror.btn.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= icon('trash-o') + |