summaryrefslogtreecommitdiff
path: root/app/controllers/concerns
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
commit8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch)
treea77e7fe7a93de11213032ed4ab1f33a3db51b738 /app/controllers/concerns
parent00b35af3db1abfe813a778f643dad221aad51fca (diff)
downloadgitlab-ce-8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781.tar.gz
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'app/controllers/concerns')
-rw-r--r--app/controllers/concerns/enforces_two_factor_authentication.rb3
-rw-r--r--app/controllers/concerns/find_snippet.rb24
-rw-r--r--app/controllers/concerns/integrations_actions.rb6
-rw-r--r--app/controllers/concerns/issuable_actions.rb29
-rw-r--r--app/controllers/concerns/issuable_collections.rb3
-rw-r--r--app/controllers/concerns/issuable_collections_action.rb4
-rw-r--r--app/controllers/concerns/known_sign_in.rb2
-rw-r--r--app/controllers/concerns/milestone_actions.rb8
-rw-r--r--app/controllers/concerns/notes_actions.rb6
-rw-r--r--app/controllers/concerns/preview_markdown.rb2
-rw-r--r--app/controllers/concerns/service_params.rb3
-rw-r--r--app/controllers/concerns/snippet_authorizations.rb23
-rw-r--r--app/controllers/concerns/snippets_actions.rb61
-rw-r--r--app/controllers/concerns/wiki_actions.rb232
-rw-r--r--app/controllers/concerns/workhorse_import_export_upload.rb33
15 files changed, 404 insertions, 35 deletions
diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb
index d486d734db8..6c443611a60 100644
--- a/app/controllers/concerns/enforces_two_factor_authentication.rb
+++ b/app/controllers/concerns/enforces_two_factor_authentication.rb
@@ -23,8 +23,7 @@ module EnforcesTwoFactorAuthentication
def two_factor_authentication_required?
Gitlab::CurrentSettings.require_two_factor_authentication? ||
- current_user.try(:require_two_factor_authentication_from_group?) ||
- current_user.try(:ultraauth_user?)
+ current_user.try(:require_two_factor_authentication_from_group?)
end
def current_user_requires_two_factor?
diff --git a/app/controllers/concerns/find_snippet.rb b/app/controllers/concerns/find_snippet.rb
new file mode 100644
index 00000000000..d51f1a1b3ad
--- /dev/null
+++ b/app/controllers/concerns/find_snippet.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module FindSnippet
+ extend ActiveSupport::Concern
+ include Gitlab::Utils::StrongMemoize
+
+ private
+
+ # rubocop:disable CodeReuse/ActiveRecord
+ def snippet
+ strong_memoize(:snippet) do
+ snippet_klass.inc_relations_for_view.find_by(id: snippet_id)
+ end
+ end
+ # rubocop:enable CodeReuse/ActiveRecord
+
+ def snippet_klass
+ raise NotImplementedError
+ end
+
+ def snippet_id
+ params[:id]
+ end
+end
diff --git a/app/controllers/concerns/integrations_actions.rb b/app/controllers/concerns/integrations_actions.rb
index ff283f9bb62..cc9db7936e8 100644
--- a/app/controllers/concerns/integrations_actions.rb
+++ b/app/controllers/concerns/integrations_actions.rb
@@ -16,10 +16,12 @@ module IntegrationsActions
def update
saved = integration.update(service_params[:service])
+ overwrite = Gitlab::Utils.to_boolean(params[:overwrite])
respond_to do |format|
format.html do
if saved
+ PropagateIntegrationWorker.perform_async(integration.id, overwrite)
redirect_to scoped_edit_integration_path(integration), notice: success_message
else
render 'shared/integrations/edit'
@@ -34,6 +36,10 @@ module IntegrationsActions
end
end
+ def custom_integration_projects
+ Project.with_custom_integration_compared_to(integration).page(params[:page]).per(20)
+ end
+
def test
render json: {}, status: :ok
end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index 0b1b3f2bcba..98fa8202e25 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -16,19 +16,6 @@ module IssuableActions
end
end
- def permitted_keys
- [
- :issuable_ids,
- :assignee_id,
- :milestone_id,
- :state_event,
- :subscription_event,
- label_ids: [],
- add_label_ids: [],
- remove_label_ids: []
- ]
- end
-
def show
respond_to do |format|
format.html do
@@ -221,10 +208,20 @@ module IssuableActions
end
def bulk_update_params
- permitted_keys_array = permitted_keys.dup
- permitted_keys_array << { assignee_ids: [] }
+ params.require(:update).permit(bulk_update_permitted_keys)
+ end
- params.require(:update).permit(permitted_keys_array)
+ def bulk_update_permitted_keys
+ [
+ :issuable_ids,
+ :assignee_id,
+ :milestone_id,
+ :state_event,
+ :subscription_event,
+ assignee_ids: [],
+ add_label_ids: [],
+ remove_label_ids: []
+ ]
end
def resource_name
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 5aa00af8910..9ef067e8797 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -5,7 +5,6 @@ module IssuableCollections
include PaginatedCollection
include SortingHelper
include SortingPreference
- include Gitlab::IssuableMetadata
include Gitlab::Utils::StrongMemoize
included do
@@ -44,7 +43,7 @@ module IssuableCollections
def set_pagination
@issuables = @issuables.page(params[:page])
@issuables = per_page_for_relative_position if params[:sort] == 'relative_position'
- @issuable_meta_data = issuable_meta_data(@issuables, collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @issuables).data
@total_pages = issuable_page_count(@issuables)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb
index 78b3c6771b3..e3ac117660b 100644
--- a/app/controllers/concerns/issuable_collections_action.rb
+++ b/app/controllers/concerns/issuable_collections_action.rb
@@ -11,7 +11,7 @@ module IssuableCollectionsAction
.non_archived
.page(params[:page])
- @issuable_meta_data = issuable_meta_data(@issues, collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @issues).data
respond_to do |format|
format.html
@@ -22,7 +22,7 @@ module IssuableCollectionsAction
def merge_requests
@merge_requests = issuables_collection.page(params[:page])
- @issuable_meta_data = issuable_meta_data(@merge_requests, collection_type, current_user)
+ @issuable_meta_data = Gitlab::IssuableMetadata.new(current_user, @merge_requests).data
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/known_sign_in.rb b/app/controllers/concerns/known_sign_in.rb
index 97883d8d08c..c0b9605de58 100644
--- a/app/controllers/concerns/known_sign_in.rb
+++ b/app/controllers/concerns/known_sign_in.rb
@@ -26,6 +26,6 @@ module KnownSignIn
end
def notify_user
- current_user.notification_service.unknown_sign_in(current_user, request.remote_ip)
+ current_user.notification_service.unknown_sign_in(current_user, request.remote_ip, current_user.current_sign_in_at)
end
end
diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb
index dbc575a1487..29138e7b014 100644
--- a/app/controllers/concerns/milestone_actions.rb
+++ b/app/controllers/concerns/milestone_actions.rb
@@ -51,13 +51,7 @@ module MilestoneActions
}
end
- # rubocop:disable Gitlab/ModuleWithInstanceVariables
def milestone_redirect_path
- if @milestone.global_milestone?
- url_for(action: :show, title: @milestone.title)
- else
- url_for(action: :show)
- end
+ url_for(action: :show)
end
- # rubocop:enable Gitlab/ModuleWithInstanceVariables
end
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index d4b0d3b2674..d3dfb1813e4 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -13,9 +13,7 @@ module NotesActions
end
def index
- current_fetched_at = Time.current.to_i
-
- notes_json = { notes: [], last_fetched_at: current_fetched_at }
+ notes_json = { notes: [], last_fetched_at: Time.current.to_i }
notes = notes_finder
.execute
@@ -24,7 +22,7 @@ module NotesActions
if notes_filter != UserPreference::NOTES_FILTERS[:only_comments]
notes =
ResourceEvents::MergeIntoNotesService
- .new(noteable, current_user, last_fetched_at: current_fetched_at)
+ .new(noteable, current_user, last_fetched_at: last_fetched_at)
.execute(notes)
end
diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb
index ba15d611c0d..2916762e31f 100644
--- a/app/controllers/concerns/preview_markdown.rb
+++ b/app/controllers/concerns/preview_markdown.rb
@@ -32,7 +32,7 @@ module PreviewMarkdown
def markdown_context_params
case controller_name
- when 'wikis' then { pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id] }
+ when 'wikis' then { pipeline: :wiki, wiki: wiki, page_slug: params[:id] }
when 'snippets' then { skip_project_check: true }
when 'groups' then { group: group }
when 'projects' then projects_filter_params
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index e2c83f9a069..e78fa8f8250 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -6,6 +6,7 @@ module ServiceParams
ALLOWED_PARAMS_CE = [
:active,
:add_pusher,
+ :alert_events,
:api_key,
:api_url,
:api_version,
@@ -28,6 +29,8 @@ module ServiceParams
:drone_url,
:enable_ssl_verification,
:external_wiki_url,
+ :google_iap_service_account_json,
+ :google_iap_audience_client_id,
# We're using `issues_events` and `merge_requests_events`
# in the view so we still need to explicitly state them
# here. `Service#event_names` would only give
diff --git a/app/controllers/concerns/snippet_authorizations.rb b/app/controllers/concerns/snippet_authorizations.rb
new file mode 100644
index 00000000000..9bbb0cc6faa
--- /dev/null
+++ b/app/controllers/concerns/snippet_authorizations.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module SnippetAuthorizations
+ extend ActiveSupport::Concern
+
+ private
+
+ def authorize_read_snippet!
+ return render_404 unless can?(current_user, :read_snippet, snippet)
+ end
+
+ def authorize_update_snippet!
+ return render_404 unless can?(current_user, :update_snippet, snippet)
+ end
+
+ def authorize_admin_snippet!
+ return render_404 unless can?(current_user, :admin_snippet, snippet)
+ end
+
+ def authorize_create_snippet!
+ return render_404 unless can?(current_user, :create_snippet)
+ end
+end
diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb
index e78723bdda2..51fc12398d9 100644
--- a/app/controllers/concerns/snippets_actions.rb
+++ b/app/controllers/concerns/snippets_actions.rb
@@ -3,9 +3,18 @@
module SnippetsActions
extend ActiveSupport::Concern
include SendsBlob
+ include RendersNotes
+ include RendersBlob
+ include PaginatedCollection
+ include Gitlab::NoteableMetadata
included do
+ skip_before_action :verify_authenticity_token,
+ if: -> { action_name == 'show' && js_request? }
+
before_action :redirect_if_binary, only: [:edit, :update]
+
+ respond_to :html
end
def edit
@@ -43,6 +52,58 @@ module SnippetsActions
request.format.js?
end
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def show
+ conditionally_expand_blob(blob)
+
+ respond_to do |format|
+ format.html do
+ @note = Note.new(noteable: @snippet, project: @snippet.project)
+ @noteable = @snippet
+
+ @discussions = @snippet.discussions
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
+ render 'show'
+ end
+
+ format.json do
+ render_blob_json(blob)
+ end
+
+ format.js do
+ if @snippet.embeddable?
+ render 'shared/snippets/show'
+ else
+ head :not_found
+ end
+ end
+ end
+ end
+
+ def update
+ update_params = snippet_params.merge(spammable_params)
+
+ service_response = Snippets::UpdateService.new(@snippet.project, current_user, update_params).execute(@snippet)
+ @snippet = service_response.payload[:snippet]
+
+ handle_repository_error(:edit)
+ end
+
+ def destroy
+ service_response = Snippets::DestroyService.new(current_user, @snippet).execute
+
+ if service_response.success?
+ redirect_to gitlab_dashboard_snippets_path(@snippet), status: :found
+ elsif service_response.http_status == 403
+ access_denied!
+ else
+ redirect_to gitlab_snippet_path(@snippet),
+ status: :found,
+ alert: service_response.message
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
private
def content_disposition
diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb
new file mode 100644
index 00000000000..b4b4fd84c37
--- /dev/null
+++ b/app/controllers/concerns/wiki_actions.rb
@@ -0,0 +1,232 @@
+# frozen_string_literal: true
+
+module WikiActions
+ include SendsBlob
+ include Gitlab::Utils::StrongMemoize
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :authorize_read_wiki!
+ before_action :authorize_create_wiki!, only: [:edit, :create]
+ before_action :authorize_admin_wiki!, only: :destroy
+
+ before_action :wiki
+ before_action :page, only: [:show, :edit, :update, :history, :destroy]
+ before_action :load_sidebar, except: [:pages]
+
+ before_action only: [:show, :edit, :update] do
+ @valid_encoding = valid_encoding?
+ end
+
+ before_action only: [:edit, :update], unless: :valid_encoding? do
+ redirect_to wiki_page_path(wiki, page)
+ end
+ end
+
+ def new
+ redirect_to wiki_page_path(wiki, SecureRandom.uuid, random_title: true)
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def pages
+ @wiki_pages = Kaminari.paginate_array(
+ wiki.list_pages(sort: params[:sort], direction: params[:direction])
+ ).page(params[:page])
+
+ @wiki_entries = WikiPage.group_by_directory(@wiki_pages)
+
+ render 'shared/wikis/pages'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # `#show` handles a number of scenarios:
+ #
+ # - If `id` matches a WikiPage, then show the wiki page.
+ # - If `id` is a file in the wiki repository, then send the file.
+ # - If we know the user wants to create a new page with the given `id`,
+ # then display a create form.
+ # - Otherwise show the empty wiki page and invite the user to create a page.
+ #
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def show
+ if page
+ set_encoding_error unless valid_encoding?
+
+ # Assign vars expected by MarkupHelper
+ @ref = params[:version_id]
+ @path = page.path
+
+ render 'shared/wikis/show'
+ elsif file_blob
+ send_blob(wiki.repository, file_blob, allow_caching: container.public?)
+ elsif show_create_form?
+ # Assign a title to the WikiPage unless `id` is a randomly generated slug from #new
+ title = params[:id] unless params[:random_title].present?
+
+ @page = build_page(title: title)
+
+ render 'shared/wikis/edit'
+ else
+ render 'shared/wikis/empty'
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def edit
+ render 'shared/wikis/edit'
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def update
+ return render('shared/wikis/empty') unless can?(current_user, :create_wiki, container)
+
+ @page = WikiPages::UpdateService.new(container: container, current_user: current_user, params: wiki_params).execute(page)
+
+ if page.valid?
+ redirect_to(
+ wiki_page_path(wiki, page),
+ notice: _('Wiki was successfully updated.')
+ )
+ else
+ render 'shared/wikis/edit'
+ end
+ rescue WikiPage::PageChangedError, WikiPage::PageRenameError, Gitlab::Git::Wiki::OperationError => e
+ @error = e
+ render 'shared/wikis/edit'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def create
+ @page = WikiPages::CreateService.new(container: container, current_user: current_user, params: wiki_params).execute
+
+ if page.persisted?
+ redirect_to(
+ wiki_page_path(wiki, page),
+ notice: _('Wiki was successfully updated.')
+ )
+ else
+ render 'shared/wikis/edit'
+ end
+ rescue Gitlab::Git::Wiki::OperationError => e
+ @page = build_page(wiki_params)
+ @error = e
+ render 'shared/wikis/edit'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def history
+ if page
+ @page_versions = Kaminari.paginate_array(page.versions(page: params[:page].to_i),
+ total_count: page.count_versions)
+ .page(params[:page])
+
+ render 'shared/wikis/history'
+ else
+ redirect_to(
+ wiki_path(wiki),
+ notice: _("Page not found")
+ )
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def destroy
+ WikiPages::DestroyService.new(container: container, current_user: current_user).execute(page)
+
+ redirect_to wiki_path(wiki),
+ status: :found,
+ notice: _("Page was successfully deleted")
+ rescue Gitlab::Git::Wiki::OperationError => e
+ @error = e
+ render 'shared/wikis/edit'
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ private
+
+ def container
+ raise NotImplementedError
+ end
+
+ def show_create_form?
+ can?(current_user, :create_wiki, container) &&
+ page.nil? &&
+ # Always show the create form when the wiki has had at least one page created.
+ # Otherwise, we only show the form when the user has navigated from
+ # the 'empty wiki' page
+ (wiki.exists? || params[:view] == 'create')
+ end
+
+ def wiki
+ strong_memoize(:wiki) do
+ wiki = Wiki.for_container(container, current_user)
+
+ # Call #wiki to make sure the Wiki Repo is initialized
+ wiki.wiki
+
+ wiki
+ end
+ rescue Wiki::CouldNotCreateWikiError
+ flash[:notice] = _("Could not create Wiki Repository at this time. Please try again later.")
+ redirect_to container
+ false
+ end
+
+ def page
+ strong_memoize(:page) do
+ wiki.find_page(*page_params)
+ end
+ end
+
+ # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ def load_sidebar
+ @sidebar_page = wiki.find_sidebar(params[:version_id])
+
+ unless @sidebar_page # Fallback to default sidebar
+ @sidebar_wiki_entries, @sidebar_limited = wiki.sidebar_entries
+ end
+ end
+ # rubocop:enable Gitlab/ModuleWithInstanceVariables
+
+ def wiki_params
+ params.require(:wiki).permit(:title, :content, :format, :message, :last_commit_sha)
+ end
+
+ def build_page(args = {})
+ WikiPage.new(wiki).tap do |page|
+ page.update_attributes(args) # rubocop:disable Rails/ActiveRecordAliases
+ end
+ end
+
+ def page_params
+ keys = [:id]
+ keys << :version_id if params[:action] == 'show'
+
+ params.values_at(*keys)
+ end
+
+ def valid_encoding?
+ page_encoding == Encoding::UTF_8
+ end
+
+ def page_encoding
+ strong_memoize(:page_encoding) { page&.content&.encoding }
+ end
+
+ def set_encoding_error
+ flash.now[:notice] = _("The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.")
+ end
+
+ def file_blob
+ strong_memoize(:file_blob) do
+ commit = wiki.repository.commit(wiki.default_branch)
+
+ next unless commit
+
+ wiki.repository.blob_at(commit.id, params[:id])
+ end
+ end
+end
diff --git a/app/controllers/concerns/workhorse_import_export_upload.rb b/app/controllers/concerns/workhorse_import_export_upload.rb
new file mode 100644
index 00000000000..3c52f4d7adf
--- /dev/null
+++ b/app/controllers/concerns/workhorse_import_export_upload.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module WorkhorseImportExportUpload
+ extend ActiveSupport::Concern
+ include WorkhorseRequest
+
+ included do
+ skip_before_action :verify_authenticity_token, only: %i[authorize]
+ before_action :verify_workhorse_api!, only: %i[authorize]
+ end
+
+ def authorize
+ set_workhorse_internal_api_content_type
+
+ authorized = ImportExportUploader.workhorse_authorize(
+ has_length: false,
+ maximum_size: Gitlab::CurrentSettings.max_import_size.megabytes
+ )
+
+ render json: authorized
+ rescue SocketError
+ render json: _("Error uploading file"), status: :internal_server_error
+ end
+
+ private
+
+ def file_is_valid?(file)
+ return false unless file.is_a?(::UploadedFile)
+
+ ImportExportUploader::EXTENSION_WHITELIST
+ .include?(File.extname(file.original_filename).delete('.'))
+ end
+end