From 6e4e1050d9dba2b7b2523fdd1768823ab85feef4 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 20 Aug 2020 18:42:06 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-3-stable-ee --- .../import/available_namespaces_controller.rb | 7 ++ app/controllers/import/base_controller.rb | 8 ++- app/controllers/import/gitea_controller.rb | 10 +++ app/controllers/import/github_controller.rb | 76 ++++++++++++++++++++-- app/controllers/import/manifest_controller.rb | 57 ++++++++++------ 5 files changed, 129 insertions(+), 29 deletions(-) create mode 100644 app/controllers/import/available_namespaces_controller.rb (limited to 'app/controllers/import') diff --git a/app/controllers/import/available_namespaces_controller.rb b/app/controllers/import/available_namespaces_controller.rb new file mode 100644 index 00000000000..7983b4f20b5 --- /dev/null +++ b/app/controllers/import/available_namespaces_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Import::AvailableNamespacesController < ApplicationController + def index + render json: NamespaceSerializer.new.represent(current_user.manageable_groups_with_routes) + end +end diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb index bc05030f8af..8a7a4c92b37 100644 --- a/app/controllers/import/base_controller.rb +++ b/app/controllers/import/base_controller.rb @@ -41,6 +41,10 @@ class Import::BaseController < ApplicationController raise NotImplementedError end + def extra_representation_opts + {} + end + private def filter_attribute @@ -58,11 +62,11 @@ class Import::BaseController < ApplicationController end def serialized_provider_repos - Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url) + Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url, **extra_representation_opts) end def serialized_incompatible_repos - Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url) + Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url, **extra_representation_opts) end def serialized_imported_projects diff --git a/app/controllers/import/gitea_controller.rb b/app/controllers/import/gitea_controller.rb index efeff8439e4..4785a71b8a1 100644 --- a/app/controllers/import/gitea_controller.rb +++ b/app/controllers/import/gitea_controller.rb @@ -54,6 +54,16 @@ class Import::GiteaController < Import::GithubController end end + override :client_repos + def client_repos + @client_repos ||= filtered(client.repos) + end + + override :client + def client + @client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options) + end + override :client_options def client_options { host: provider_url, api_version: 'v1' } diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index ac6b8c06d66..29fe34f0734 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -10,6 +10,9 @@ class Import::GithubController < Import::BaseController before_action :provider_auth, only: [:status, :realtime_changes, :create] before_action :expire_etag_cache, only: [:status, :create] + OAuthConfigMissingError = Class.new(StandardError) + + rescue_from OAuthConfigMissingError, with: :missing_oauth_config rescue_from Octokit::Unauthorized, with: :provider_unauthorized rescue_from Octokit::TooManyRequests, with: :provider_rate_limit @@ -22,7 +25,7 @@ class Import::GithubController < Import::BaseController end def callback - session[access_token_key] = client.get_token(params[:code]) + session[access_token_key] = get_token(params[:code]) redirect_to status_import_url end @@ -77,9 +80,7 @@ class Import::GithubController < Import::BaseController override :provider_url def provider_url strong_memoize(:provider_url) do - provider = Gitlab::Auth::OAuth::Provider.config_for('github') - - provider&.dig('url').presence || 'https://github.com' + oauth_config&.dig('url').presence || 'https://github.com' end end @@ -104,11 +105,66 @@ class Import::GithubController < Import::BaseController end def client - @client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options) + @client ||= if Feature.enabled?(:remove_legacy_github_client) + Gitlab::GithubImport::Client.new(session[access_token_key]) + else + Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options) + end end def client_repos - @client_repos ||= filtered(client.repos) + @client_repos ||= if Feature.enabled?(:remove_legacy_github_client) + filtered(concatenated_repos) + else + filtered(client.repos) + end + end + + def concatenated_repos + return [] unless client.respond_to?(:each_page) + + client.each_page(:repos).flat_map(&:objects) + end + + def oauth_client + raise OAuthConfigMissingError unless oauth_config + + @oauth_client ||= ::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 + if oauth_config + oauth_config.dig('args', 'client_options').deep_symbolize_keys + else + OmniAuth::Strategies::GitHub.default_options[:client_options].symbolize_keys + end + end + + def authorize_url + if Feature.enabled?(:remove_legacy_github_client) + oauth_client.auth_code.authorize_url( + redirect_uri: callback_import_url, + scope: 'repo, user, user:email' + ) + else + client.authorize_url(callback_import_url) + 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 verify_import_enabled @@ -116,7 +172,7 @@ class Import::GithubController < Import::BaseController end def go_to_provider_for_permissions - redirect_to client.authorize_url(callback_import_url) + redirect_to authorize_url end def import_enabled? @@ -152,6 +208,12 @@ class Import::GithubController < Import::BaseController alert: _("GitHub API rate limit exceeded. Try again after %{reset_time}") % { reset_time: reset_time } end + def missing_oauth_config + session[access_token_key] = nil + redirect_to new_import_url, + alert: _('Missing OAuth configuration for GitHub.') + end + def access_token_key :"#{provider_name}_access_token" end diff --git a/app/controllers/import/manifest_controller.rb b/app/controllers/import/manifest_controller.rb index 9aec870c6ea..9c47e6d4b0b 100644 --- a/app/controllers/import/manifest_controller.rb +++ b/app/controllers/import/manifest_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Import::ManifestController < Import::BaseController + extend ::Gitlab::Utils::Override + before_action :whitelist_query_limiting, only: [:create] before_action :verify_import_enabled before_action :ensure_import_vars, only: [:create, :status] @@ -8,16 +10,9 @@ class Import::ManifestController < Import::BaseController def new end - # rubocop: disable CodeReuse/ActiveRecord def status - @already_added_projects = find_already_added_projects - already_added_import_urls = @already_added_projects.pluck(:import_url) - - @pending_repositories = repositories.to_a.reject do |repository| - already_added_import_urls.include?(repository[:url]) - end + super end - # rubocop: enable CodeReuse/ActiveRecord def upload group = Group.find(params[:group_id]) @@ -42,8 +37,8 @@ class Import::ManifestController < Import::BaseController end end - def jobs - render json: find_jobs + def realtime_changes + super end def create @@ -54,12 +49,43 @@ class Import::ManifestController < Import::BaseController project = Gitlab::ManifestImport::ProjectCreator.new(repository, group, current_user).execute if project.persisted? - render json: ProjectSerializer.new.represent(project) + render json: ProjectSerializer.new.represent(project, serializer: :import) else render json: { errors: project_save_error(project) }, status: :unprocessable_entity end end + protected + + # rubocop: disable CodeReuse/ActiveRecord + override :importable_repos + def importable_repos + already_added_projects_names = already_added_projects.pluck(:import_url) + + repositories.reject { |repo| already_added_projects_names.include?(repo[:url]) } + end + # rubocop: enable CodeReuse/ActiveRecord + + override :incompatible_repos + def incompatible_repos + [] + end + + override :provider_name + def provider_name + :manifest + end + + override :provider_url + def provider_url + nil + end + + override :extra_representation_opts + def extra_representation_opts + { group_full_path: group.full_path } + end + private def ensure_import_vars @@ -82,15 +108,6 @@ class Import::ManifestController < Import::BaseController find_already_added_projects.to_json(only: [:id], methods: [:import_status]) end - # rubocop: disable CodeReuse/ActiveRecord - def find_already_added_projects - group.all_projects - .where(import_type: 'manifest') - .where(creator_id: current_user) - .with_import_state - end - # rubocop: enable CodeReuse/ActiveRecord - def verify_import_enabled render_404 unless manifest_import_enabled? end -- cgit v1.2.1