diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-20 12:40:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-20 12:40:42 +0300 |
commit | ee664acb356f8123f4f6b00b73c1e1cf0866c7fb (patch) | |
tree | f8479f94a28f66654c6a4f6fb99bad6b4e86a40e /app/controllers/concerns | |
parent | 62f7d5c5b69180e82ae8196b7b429eeffc8e7b4f (diff) |
Add latest changes from gitlab-org/gitlab@15-5-stable-eev15.5.0-rc42
Diffstat (limited to 'app/controllers/concerns')
-rw-r--r-- | app/controllers/concerns/access_tokens_actions.rb | 16 | ||||
-rw-r--r-- | app/controllers/concerns/authenticates_with_two_factor.rb | 5 | ||||
-rw-r--r-- | app/controllers/concerns/boards_actions.rb | 59 | ||||
-rw-r--r-- | app/controllers/concerns/boards_responses.rb | 94 | ||||
-rw-r--r-- | app/controllers/concerns/import/github_oauth.rb | 100 | ||||
-rw-r--r-- | app/controllers/concerns/issuable_collections_action.rb | 5 | ||||
-rw-r--r-- | app/controllers/concerns/multiple_boards_actions.rb | 93 | ||||
-rw-r--r-- | app/controllers/concerns/preview_markdown.rb | 16 | ||||
-rw-r--r-- | app/controllers/concerns/product_analytics_tracking.rb | 9 | ||||
-rw-r--r-- | app/controllers/concerns/registrations_tracking.rb | 15 | ||||
-rw-r--r-- | app/controllers/concerns/sends_blob.rb | 22 | ||||
-rw-r--r-- | app/controllers/concerns/wiki_actions.rb | 6 |
12 files changed, 203 insertions, 237 deletions
diff --git a/app/controllers/concerns/access_tokens_actions.rb b/app/controllers/concerns/access_tokens_actions.rb index 451841c43bb..6e43be5594d 100644 --- a/app/controllers/concerns/access_tokens_actions.rb +++ b/app/controllers/concerns/access_tokens_actions.rb @@ -22,11 +22,10 @@ module AccessTokensActions if token_response.success? @resource_access_token = token_response.payload[:access_token] - PersonalAccessToken.redis_store!(key_identity, @resource_access_token.token) - - redirect_to resource_access_tokens_path, notice: _("Your new access token has been created.") + render json: { new_token: @resource_access_token.token, + active_access_tokens: active_resource_access_tokens }, status: :ok else - redirect_to resource_access_tokens_path, alert: _("Failed to create new access token: %{token_response_message}") % { token_response_message: token_response.message } + render json: { errors: token_response.errors }, status: :unprocessable_entity end end # rubocop:enable Gitlab/ModuleWithInstanceVariables @@ -63,12 +62,15 @@ module AccessTokensActions resource.members.load @scopes = Gitlab::Auth.resource_bot_scopes - @active_resource_access_tokens = finder(state: 'active').execute.preload_users - @inactive_resource_access_tokens = finder(state: 'inactive', sort: 'expires_at_asc').execute.preload_users - @new_resource_access_token = PersonalAccessToken.redis_getdel(key_identity) + @active_resource_access_tokens = active_resource_access_tokens end # rubocop:enable Gitlab/ModuleWithInstanceVariables + def active_resource_access_tokens + tokens = finder(state: 'active', sort: 'expires_at_asc_id_desc').execute.preload_users + represent(tokens) + end + def finder(options = {}) PersonalAccessTokensFinder.new({ user: bot_users, impersonation: false }.merge(options)) end diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index 4228a93d310..fbaa754124c 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -89,6 +89,7 @@ module AuthenticatesWithTwoFactor user.save! sign_in(user, message: :two_factor_authenticated, event: :authentication) else + send_two_factor_otp_attempt_failed_email(user) handle_two_factor_failure(user, 'OTP', _('Invalid two-factor code.')) end end @@ -158,6 +159,10 @@ module AuthenticatesWithTwoFactor prompt_for_two_factor(user) end + def send_two_factor_otp_attempt_failed_email(user) + user.notification_service.two_factor_otp_attempt_failed(user, request.remote_ip) + end + def log_failed_two_factor(user, method) # overridden in EE end diff --git a/app/controllers/concerns/boards_actions.rb b/app/controllers/concerns/boards_actions.rb index 2f9edfad12d..42bf6c68aa7 100644 --- a/app/controllers/concerns/boards_actions.rb +++ b/app/controllers/concerns/boards_actions.rb @@ -5,41 +5,38 @@ module BoardsActions extend ActiveSupport::Concern included do - include BoardsResponses - before_action :authorize_read_board!, only: [:index, :show] - before_action :boards, only: :index - before_action :board, only: :show + before_action :redirect_to_recent_board, only: [:index] + before_action :board, only: [:index, :show] before_action :push_licensed_features, only: [:index, :show] end def index - respond_with_boards + # if no board exists, create one + @board = board_create_service.execute.payload unless board # rubocop:disable Gitlab/ModuleWithInstanceVariables end def show - # Add / update the board in the recent visits table - board_visit_service.new(parent, current_user).execute(board) if request.format.html? + return render_404 unless board - respond_with_board + # Add / update the board in the recent visits table + board_visit_service.new(parent, current_user).execute(board) end private - # Noop on FOSS - def push_licensed_features + def redirect_to_recent_board + return if !parent.multiple_issue_boards_available? || !latest_visited_board + + redirect_to board_path(latest_visited_board.board) end - def boards - strong_memoize(:boards) do - existing_boards = boards_finder.execute - if existing_boards.any? - existing_boards - else - # if no board exists, create one - [board_create_service.execute.payload] - end - end + def latest_visited_board + @latest_visited_board ||= Boards::VisitsFinder.new(parent, current_user).latest + end + + # Noop on FOSS + def push_licensed_features end def board @@ -48,20 +45,26 @@ module BoardsActions end end - def board_type - board_klass.to_type - end - def board_visit_service Boards::Visits::CreateService end - def serializer - BoardSerializer.new(current_user: current_user) + def parent + strong_memoize(:parent) do + group? ? group : project + end + end + + def board_path(board) + if group? + group_board_path(parent, board) + else + project_board_path(parent, board) + end end - def serialize_as_json(resource) - serializer.represent(resource, serializer: 'board', include_full_project_path: board.group_board?) + def group? + instance_variable_defined?(:@group) end end diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb deleted file mode 100644 index eb7392648a1..00000000000 --- a/app/controllers/concerns/boards_responses.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: true - -module BoardsResponses - include Gitlab::Utils::StrongMemoize - - # Overridden on EE module - def board_params - params.require(:board).permit(:name) - end - - def parent - strong_memoize(:parent) do - group? ? group : project - end - end - - def boards_path - if group? - group_boards_path(parent) - else - project_boards_path(parent) - end - end - - def board_path(board) - if group? - group_board_path(parent, board) - else - project_board_path(parent, board) - end - end - - def group? - instance_variable_defined?(:@group) - end - - def authorize_read_list - authorize_action_for!(board, :read_issue_board_list) - end - - def authorize_read_issue - authorize_action_for!(board, :read_issue) - end - - def authorize_update_issue - authorize_action_for!(issue, :admin_issue) - end - - def authorize_create_issue - list = List.find(issue_params[:list_id]) - action = list.backlog? ? :create_issue : :admin_issue - - authorize_action_for!(project, action) - end - - def authorize_admin_list - authorize_action_for!(board, :admin_issue_board_list) - end - - def authorize_action_for!(resource, ability) - return render_403 unless can?(current_user, ability, resource) - end - - def respond_with_boards - respond_with(@boards) # rubocop:disable Gitlab/ModuleWithInstanceVariables - end - - def respond_with_board - # rubocop:disable Gitlab/ModuleWithInstanceVariables - return render_404 unless @board - - respond_with(@board) - # rubocop:enable Gitlab/ModuleWithInstanceVariables - end - - def serialize_as_json(resource) - serializer.represent(resource).as_json - end - - def respond_with(resource) - respond_to do |format| - format.html - format.json do - render json: serialize_as_json(resource) - end - end - end - - def serializer - BoardSerializer.new - end -end - -BoardsResponses.prepend_mod_with('BoardsResponses') diff --git a/app/controllers/concerns/import/github_oauth.rb b/app/controllers/concerns/import/github_oauth.rb new file mode 100644 index 00000000000..d53022aabf2 --- /dev/null +++ b/app/controllers/concerns/import/github_oauth.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Import + module GithubOauth + extend ActiveSupport::Concern + + OAuthConfigMissingError = Class.new(StandardError) + + included do + rescue_from OAuthConfigMissingError, with: :missing_oauth_config + end + + private + + def provider_auth + return if session[access_token_key].present? + + go_to_provider_for_permissions unless ci_cd_only? + end + + def ci_cd_only? + %w[1 true].include?(params[:ci_cd_only]) + end + + def go_to_provider_for_permissions + redirect_to authorize_url + end + + def oauth_client + raise OAuthConfigMissingError unless oauth_config + + oauth_client_from_config + end + + def oauth_client_from_config + @oauth_client_from_config ||= ::OAuth2::Client.new( + oauth_config.app_id, + oauth_config.app_secret, + oauth_options.merge(ssl: { verify: oauth_config['verify_ssl'] }) + ) + end + + def oauth_config + @oauth_config ||= Gitlab::Auth::OAuth::Provider.config_for('github') + end + + def oauth_options + return unless oauth_config + + oauth_config.dig('args', 'client_options').deep_symbolize_keys + end + + def authorize_url + state = SecureRandom.base64(64) + session[auth_state_key] = state + if Feature.enabled?(:remove_legacy_github_client) + oauth_client.auth_code.authorize_url( + redirect_uri: callback_import_url, + scope: 'repo, user, user:email', + state: state + ) + else + client.authorize_url(callback_import_url, state) + end + end + + def get_token(code) + if Feature.enabled?(:remove_legacy_github_client) + oauth_client.auth_code.get_token(code).token + else + client.get_token(code) + end + end + + def missing_oauth_config + session[access_token_key] = nil + + message = _('Missing OAuth configuration for GitHub.') + + respond_to do |format| + format.json do + render json: { errors: message }, status: :unauthorized + end + + format.any do + redirect_to new_import_url, + alert: message + end + end + end + + def callback_import_url + public_send("users_import_#{provider_name}_callback_url", extra_import_params.merge({ namespace_id: params[:namespace_id] })) # rubocop:disable GitlabSecurity/PublicSend + end + + def extra_import_params + {} + end + end +end diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb index 96cf6021ea9..e03d1de7bf9 100644 --- a/app/controllers/concerns/issuable_collections_action.rb +++ b/app/controllers/concerns/issuable_collections_action.rb @@ -59,9 +59,12 @@ module IssuableCollectionsAction end def finder_options + issue_types = Issue::TYPES_FOR_LIST + issue_types = issue_types.excluding('task') unless Feature.enabled?(:work_items) + super.merge( non_archived: true, - issue_types: Issue::TYPES_FOR_LIST + issue_types: issue_types ) end end diff --git a/app/controllers/concerns/multiple_boards_actions.rb b/app/controllers/concerns/multiple_boards_actions.rb deleted file mode 100644 index 685c93fc2a2..00000000000 --- a/app/controllers/concerns/multiple_boards_actions.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -module MultipleBoardsActions - include Gitlab::Utils::StrongMemoize - extend ActiveSupport::Concern - - included do - include BoardsActions - - before_action :redirect_to_recent_board, only: [:index] - before_action :authenticate_user!, only: [:recent] - before_action :authorize_create_board!, only: [:create] - before_action :authorize_admin_board!, only: [:create, :update, :destroy] - end - - def recent - recent_visits = ::Boards::VisitsFinder.new(parent, current_user).latest(Board::RECENT_BOARDS_SIZE) - recent_boards = recent_visits.map(&:board) - - render json: serialize_as_json(recent_boards) - end - - def create - response = Boards::CreateService.new(parent, current_user, board_params).execute - - respond_to do |format| - format.json do - board = response.payload - - if response.success? - extra_json = { board_path: board_path(board) } - render json: serialize_as_json(board).merge(extra_json) - else - render json: board.errors, status: :unprocessable_entity - end - end - end - end - - def update - service = Boards::UpdateService.new(parent, current_user, board_params) - - respond_to do |format| - format.json do - if service.execute(board) - extra_json = { board_path: board_path(board) } - render json: serialize_as_json(board).merge(extra_json) - else - render json: board.errors, status: :unprocessable_entity - end - end - end - end - - def destroy - service = Boards::DestroyService.new(parent, current_user) - service.execute(board) - - respond_to do |format| - format.json { head :ok } - format.html { redirect_to boards_path, status: :found } - end - end - - private - - def redirect_to_recent_board - return unless board_type == Board.to_type - return if request.format.json? || !parent.multiple_issue_boards_available? || !latest_visited_board - - redirect_to board_path(latest_visited_board.board) - end - - def latest_visited_board - @latest_visited_board ||= Boards::VisitsFinder.new(parent, current_user).latest - end - - def authorize_create_board! - check_multiple_group_issue_boards_available! if group? - end - - def authorize_admin_board! - return render_404 unless can?(current_user, :admin_issue_board, parent) - end - - def serializer - BoardSerializer.new(current_user: current_user) - end - - def serialize_as_json(resource) - serializer.represent(resource, serializer: 'board', include_full_project_path: board.group_board?) - end -end diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb index 1d2f9e31c46..79b3fa28660 100644 --- a/app/controllers/concerns/preview_markdown.rb +++ b/app/controllers/concerns/preview_markdown.rb @@ -26,16 +26,24 @@ module PreviewMarkdown } end + def timeline_events_filter_params + { + issuable_reference_expansion_enabled: true, + pipeline: :'incident_management/timeline_event' + } + end + def markdown_service_params params end def markdown_context_params case controller_name - 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 + 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 + when 'timeline_events' then timeline_events_filter_params else {} end.merge(requested_path: params[:path], ref: params[:ref]) end diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb index 8e936782e5a..4f96cc5c895 100644 --- a/app/controllers/concerns/product_analytics_tracking.rb +++ b/app/controllers/concerns/product_analytics_tracking.rb @@ -29,7 +29,13 @@ module ProductAnalyticsTracking track_unique_redis_hll_event(name, &block) if destinations.include?(:redis_hll) if destinations.include?(:snowplow) && event_enabled?(name) - Gitlab::Tracking.event(self.class.to_s, name, namespace: tracking_namespace_source, user: current_user) + Gitlab::Tracking.event( + self.class.to_s, + name, + namespace: tracking_namespace_source, + user: current_user, + context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: name).to_context] + ) end end @@ -49,6 +55,7 @@ module ProductAnalyticsTracking user: current_user, property: name, label: label, + context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: name).to_context], **optional_arguments ) end diff --git a/app/controllers/concerns/registrations_tracking.rb b/app/controllers/concerns/registrations_tracking.rb new file mode 100644 index 00000000000..14743349c1a --- /dev/null +++ b/app/controllers/concerns/registrations_tracking.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module RegistrationsTracking + extend ActiveSupport::Concern + + included do + helper_method :glm_tracking_params + end + + private + + def glm_tracking_params + params.permit(:glm_source, :glm_content) + end +end diff --git a/app/controllers/concerns/sends_blob.rb b/app/controllers/concerns/sends_blob.rb index 381f2eba352..3cf260c9f1b 100644 --- a/app/controllers/concerns/sends_blob.rb +++ b/app/controllers/concerns/sends_blob.rb @@ -27,12 +27,14 @@ module SendsBlob private def cached_blob?(blob, allow_caching: false) - stale = stale?(etag: blob.id) # The #stale? method sets cache headers. - - # Because we are opinionated we set the cache headers ourselves. - response.cache_control[:public] = allow_caching + stale = + if Feature.enabled?(:improve_blobs_cache_headers) + stale?(strong_etag: blob.id) + else + stale?(etag: blob.id) + end - response.cache_control[:max_age] = + max_age = if @ref && @commit && @ref == @commit.id # rubocop:disable Gitlab/ModuleWithInstanceVariables # This is a link to a commit by its commit SHA. That means that the blob # is immutable. The only reason to invalidate the cache is if the commit @@ -44,6 +46,16 @@ module SendsBlob Blob::CACHE_TIME end + # Because we are opinionated we set the cache headers ourselves. + if Feature.enabled?(:improve_blobs_cache_headers) + expires_in(max_age, + public: allow_caching, must_revalidate: true, stale_if_error: 5.minutes, + stale_while_revalidate: 1.minute, 's-maxage': 1.minute) + else + response.cache_control[:public] = allow_caching + response.cache_control[:max_age] = max_age + end + !stale end diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb index 83447744013..2b781c528ad 100644 --- a/app/controllers/concerns/wiki_actions.rb +++ b/app/controllers/concerns/wiki_actions.rb @@ -209,9 +209,7 @@ module WikiActions 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.create_wiki_repository wiki end @@ -242,7 +240,7 @@ module WikiActions def wiki_pages strong_memoize(:wiki_pages) do Kaminari.paginate_array( - wiki.list_pages(sort: params[:sort], direction: params[:direction]) + wiki.list_pages(direction: params[:direction]) ).page(params[:page]) end end |