Commit 3a75f033 authored by Imre Farkas's avatar Imre Farkas

Merge branch 'georgekoltsov/remove-legacy-github-client-from-github-controller' into 'master'

Remove use of LegacyGithubClient in GithubController

See merge request gitlab-org/gitlab!37555
parents d482a049 73ad1340
...@@ -54,6 +54,16 @@ class Import::GiteaController < Import::GithubController ...@@ -54,6 +54,16 @@ class Import::GiteaController < Import::GithubController
end end
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 override :client_options
def client_options def client_options
{ host: provider_url, api_version: 'v1' } { host: provider_url, api_version: 'v1' }
......
...@@ -10,6 +10,9 @@ class Import::GithubController < Import::BaseController ...@@ -10,6 +10,9 @@ class Import::GithubController < Import::BaseController
before_action :provider_auth, only: [:status, :realtime_changes, :create] before_action :provider_auth, only: [:status, :realtime_changes, :create]
before_action :expire_etag_cache, only: [:status, :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::Unauthorized, with: :provider_unauthorized
rescue_from Octokit::TooManyRequests, with: :provider_rate_limit rescue_from Octokit::TooManyRequests, with: :provider_rate_limit
...@@ -22,7 +25,7 @@ class Import::GithubController < Import::BaseController ...@@ -22,7 +25,7 @@ class Import::GithubController < Import::BaseController
end end
def callback def callback
session[access_token_key] = client.get_token(params[:code]) session[access_token_key] = get_token(params[:code])
redirect_to status_import_url redirect_to status_import_url
end end
...@@ -77,9 +80,7 @@ class Import::GithubController < Import::BaseController ...@@ -77,9 +80,7 @@ class Import::GithubController < Import::BaseController
override :provider_url override :provider_url
def provider_url def provider_url
strong_memoize(:provider_url) do strong_memoize(:provider_url) do
provider = Gitlab::Auth::OAuth::Provider.config_for('github') oauth_config&.dig('url').presence || 'https://github.com'
provider&.dig('url').presence || 'https://github.com'
end end
end end
...@@ -104,11 +105,56 @@ class Import::GithubController < Import::BaseController ...@@ -104,11 +105,56 @@ class Import::GithubController < Import::BaseController
end end
def client def client
@client ||= Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options) @client ||= if Feature.enabled?(:remove_legacy_github_client, default_enabled: false)
Gitlab::GithubImport::Client.new(session[access_token_key])
else
Gitlab::LegacyGithubImport::Client.new(session[access_token_key], client_options)
end
end end
def client_repos def client_repos
@client_repos ||= filtered(client.repos) @client_repos ||= filtered(client.octokit.repos)
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(redirect_uri)
if Feature.enabled?(:remove_legacy_github_client, default_enabled: false)
oauth_client.auth_code.authorize_url({
redirect_uri: redirect_uri,
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, default_enabled: false)
oauth_client.auth_code.get_token(code).token
else
client.get_token(code)
end
end end
def verify_import_enabled def verify_import_enabled
...@@ -116,7 +162,7 @@ class Import::GithubController < Import::BaseController ...@@ -116,7 +162,7 @@ class Import::GithubController < Import::BaseController
end end
def go_to_provider_for_permissions def go_to_provider_for_permissions
redirect_to client.authorize_url(callback_import_url) redirect_to authorize_url(callback_import_url)
end end
def import_enabled? def import_enabled?
...@@ -152,6 +198,12 @@ class Import::GithubController < Import::BaseController ...@@ -152,6 +198,12 @@ class Import::GithubController < Import::BaseController
alert: _("GitHub API rate limit exceeded. Try again after %{reset_time}") % { reset_time: reset_time } alert: _("GitHub API rate limit exceeded. Try again after %{reset_time}") % { reset_time: reset_time }
end end
def missing_oauth_config
session[access_token_key] = nil
redirect_to new_import_url,
alert: _('OAuth configuration for GitHub missing.')
end
def access_token_key def access_token_key
:"#{provider_name}_access_token" :"#{provider_name}_access_token"
end end
......
...@@ -33,7 +33,7 @@ module Import ...@@ -33,7 +33,7 @@ module Import
end end
def repo def repo
@repo ||= client.repo(params[:repo_id].to_i) @repo ||= client.repository(params[:repo_id].to_i)
end end
def project_name def project_name
......
...@@ -115,14 +115,18 @@ RSpec.describe 'New project' do ...@@ -115,14 +115,18 @@ RSpec.describe 'New project' do
expect(page).to have_text('Authenticate with GitHub') expect(page).to have_text('Authenticate with GitHub')
allow_any_instance_of(Gitlab::LegacyGithubImport::Client).to receive(:repos).and_return([repo]) allow_next_instance_of(Octokit::Client) do |client|
allow(client).to receive(:repos).and_return([repo])
end
fill_in 'personal_access_token', with: 'fake-token' fill_in 'personal_access_token', with: 'fake-token'
click_button 'Authenticate' click_button 'Authenticate'
wait_for_requests wait_for_requests
# Mock the POST `/import/github` # Mock the POST `/import/github`
allow_any_instance_of(Gitlab::LegacyGithubImport::Client).to receive(:repo).and_return(repo) allow_next_instance_of(Gitlab::GithubImport::Client) do |client|
allow(client).to receive(:repository).and_return(repo)
end
project = create(:project, name: 'some-github-repo', creator: user, import_type: 'github') project = create(:project, name: 'some-github-repo', creator: user, import_type: 'github')
create(:import_state, :finished, import_url: repo.clone_url, project: project) create(:import_state, :finished, import_url: repo.clone_url, project: project)
allow_any_instance_of(CiCd::SetupProject).to receive(:setup_external_service) allow_any_instance_of(CiCd::SetupProject).to receive(:setup_external_service)
...@@ -150,7 +154,9 @@ RSpec.describe 'New project' do ...@@ -150,7 +154,9 @@ RSpec.describe 'New project' do
find('.js-import-github').click find('.js-import-github').click
end end
allow_any_instance_of(Gitlab::LegacyGithubImport::Client).to receive(:repos).and_raise(Octokit::Unauthorized) allow_next_instance_of(Octokit::Client) do |client|
allow(client).to receive(:repos).and_raise(Octokit::Unauthorized)
end
fill_in 'personal_access_token', with: 'unauthorized-fake-token' fill_in 'personal_access_token', with: 'unauthorized-fake-token'
click_button 'Authenticate' click_button 'Authenticate'
......
...@@ -10,7 +10,11 @@ module API ...@@ -10,7 +10,11 @@ module API
helpers do helpers do
def client def client
@client ||= Gitlab::LegacyGithubImport::Client.new(params[:personal_access_token], client_options) @client ||= if Feature.enabled?(:remove_legacy_github_client, default_enabled: false)
Gitlab::GithubImport::Client.new(params[:personal_access_token])
else
Gitlab::LegacyGithubImport::Client.new(params[:personal_access_token], client_options)
end
end end
def access_params def access_params
......
...@@ -32,6 +32,8 @@ module Gitlab ...@@ -32,6 +32,8 @@ module Gitlab
) )
end end
alias_method :octokit, :api
def client def client
unless config unless config
raise Projects::ImportService::Error, raise Projects::ImportService::Error,
......
...@@ -16397,6 +16397,9 @@ msgstr "" ...@@ -16397,6 +16397,9 @@ msgstr ""
msgid "Number of files touched" msgid "Number of files touched"
msgstr "" msgstr ""
msgid "OAuth configuration for GitHub missing."
msgstr ""
msgid "OK" msgid "OK"
msgstr "" msgstr ""
......
...@@ -15,10 +15,7 @@ RSpec.describe Import::GithubController do ...@@ -15,10 +15,7 @@ RSpec.describe Import::GithubController do
it "redirects to GitHub for an access token if logged in with GitHub" do it "redirects to GitHub for an access token if logged in with GitHub" do
allow(controller).to receive(:logged_in_with_provider?).and_return(true) allow(controller).to receive(:logged_in_with_provider?).and_return(true)
expect(controller).to receive(:go_to_provider_for_permissions).and_call_original expect(controller).to receive(:go_to_provider_for_permissions).and_call_original
allow_any_instance_of(Gitlab::LegacyGithubImport::Client) allow(controller).to receive(:authorize_url).with(users_import_github_callback_url).and_call_original
.to receive(:authorize_url)
.with(users_import_github_callback_url)
.and_call_original
get :new get :new
...@@ -46,13 +43,15 @@ RSpec.describe Import::GithubController do ...@@ -46,13 +43,15 @@ RSpec.describe Import::GithubController do
end end
describe "GET callback" do describe "GET callback" do
before do
allow(controller).to receive(:get_token).and_return(token)
allow(controller).to receive(:oauth_options).and_return({})
stub_omniauth_provider('github')
end
it "updates access token" do it "updates access token" do
token = "asdasd12345" token = "asdasd12345"
allow_any_instance_of(Gitlab::LegacyGithubImport::Client)
.to receive(:get_token).and_return(token)
allow_any_instance_of(Gitlab::LegacyGithubImport::Client)
.to receive(:github_options).and_return({})
stub_omniauth_provider('github')
get :callback get :callback
...@@ -67,6 +66,54 @@ RSpec.describe Import::GithubController do ...@@ -67,6 +66,54 @@ RSpec.describe Import::GithubController do
describe "GET status" do describe "GET status" do
it_behaves_like 'a GitHub-ish import controller: GET status' it_behaves_like 'a GitHub-ish import controller: GET status'
context 'when using OAuth' do
before do
allow(controller).to receive(:logged_in_with_provider?).and_return(true)
end
context 'when OAuth config is missing' do
let(:new_import_url) { public_send("new_import_#{provider}_url") }
before do
allow(controller).to receive(:oauth_config).and_return(nil)
end
it 'returns missing config error' do
expect(controller).to receive(:go_to_provider_for_permissions).and_call_original
get :status
expect(session[:"#{provider}_access_token"]).to be_nil
expect(controller).to redirect_to(new_import_url)
expect(flash[:alert]).to eq('OAuth configuration for GitHub missing.')
end
end
end
context 'when feature remove_legacy_github_client is disabled' do
before do
stub_feature_flags(remove_legacy_github_client: false)
end
it 'uses Gitlab::LegacyGitHubImport::Client' do
expect(controller.send(:client)).to be_instance_of(Gitlab::LegacyGithubImport::Client)
get :status
end
end
context 'when feature remove_legacy_github_client is enabled' do
before do
stub_feature_flags(remove_legacy_github_client: true)
end
it 'uses Gitlab::GithubImport::Client' do
expect(controller.send(:client)).to be_instance_of(Gitlab::GithubImport::Client)
get :status
end
end
end end
describe "POST create" do describe "POST create" do
......
...@@ -22,7 +22,7 @@ RSpec.describe API::ImportGithub do ...@@ -22,7 +22,7 @@ RSpec.describe API::ImportGithub do
before do before do
Grape::Endpoint.before_each do |endpoint| Grape::Endpoint.before_each do |endpoint|
allow(endpoint).to receive(:client).and_return(double('client', user: provider_user, repo: provider_repo).as_null_object) allow(endpoint).to receive(:client).and_return(double('client', user: provider_user, repository: provider_repo).as_null_object)
end end
end end
......
...@@ -6,7 +6,7 @@ RSpec.describe Import::GithubService do ...@@ -6,7 +6,7 @@ RSpec.describe Import::GithubService do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:token) { 'complex-token' } let_it_be(:token) { 'complex-token' }
let_it_be(:access_params) { { github_access_token: 'github-complex-token' } } let_it_be(:access_params) { { github_access_token: 'github-complex-token' } }
let_it_be(:client) { Gitlab::LegacyGithubImport::Client.new(token) } let_it_be(:client) { Gitlab::GithubImport::Client.new(token) }
let_it_be(:params) { { repo_id: 123, new_name: 'new_repo', target_namespace: 'root' } } let_it_be(:params) { { repo_id: 123, new_name: 'new_repo', target_namespace: 'root' } }
let(:subject) { described_class.new(client, user, params) } let(:subject) { described_class.new(client, user, params) }
...@@ -19,7 +19,7 @@ RSpec.describe Import::GithubService do ...@@ -19,7 +19,7 @@ RSpec.describe Import::GithubService do
let(:exception) { Octokit::ClientError.new(status: 404, body: 'Not Found') } let(:exception) { Octokit::ClientError.new(status: 404, body: 'Not Found') }
before do before do
expect(client).to receive(:repo).and_raise(exception) expect(client).to receive(:repository).and_raise(exception)
end end
it 'logs the original error' do it 'logs the original error' do
...@@ -46,7 +46,7 @@ RSpec.describe Import::GithubService do ...@@ -46,7 +46,7 @@ RSpec.describe Import::GithubService do
it 'raises an exception for unknown error causes' do it 'raises an exception for unknown error causes' do
exception = StandardError.new('Not Implemented') exception = StandardError.new('Not Implemented')
expect(client).to receive(:repo).and_raise(exception) expect(client).to receive(:repository).and_raise(exception)
expect(Gitlab::Import::Logger).not_to receive(:error) expect(Gitlab::Import::Logger).not_to receive(:error)
......
...@@ -111,8 +111,11 @@ RSpec.shared_examples 'a GitHub-ish import controller: GET status' do ...@@ -111,8 +111,11 @@ RSpec.shared_examples 'a GitHub-ish import controller: GET status' do
end end
it "handles an invalid access token" do it "handles an invalid access token" do
allow_any_instance_of(Gitlab::LegacyGithubImport::Client) allow_any_instance_of(Gitlab::LegacyGithubImport::Client).to receive(:repos).and_raise(Octokit::Unauthorized)
.to receive(:repos).and_raise(Octokit::Unauthorized)
allow_next_instance_of(Octokit::Client) do |client|
allow(client).to receive(:repos).and_raise(Octokit::Unauthorized)
end
get :status get :status
...@@ -187,7 +190,7 @@ RSpec.shared_examples 'a GitHub-ish import controller: POST create' do ...@@ -187,7 +190,7 @@ RSpec.shared_examples 'a GitHub-ish import controller: POST create' do
end end
before do before do
stub_client(user: provider_user, repo: provider_repo) stub_client(user: provider_user, repo: provider_repo, repository: provider_repo)
assign_session_token(provider) assign_session_token(provider)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment