Commit 56cb4762 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre Committed by Stan Hu

Refactoring Bitbucket import controller to use the new OAuth2 client

parent 411d0a93
...@@ -3,49 +3,54 @@ class Import::BitbucketController < Import::BaseController ...@@ -3,49 +3,54 @@ class Import::BitbucketController < Import::BaseController
before_action :bitbucket_auth, except: :callback before_action :bitbucket_auth, except: :callback
rescue_from OAuth::Error, with: :bitbucket_unauthorized rescue_from OAuth::Error, with: :bitbucket_unauthorized
rescue_from Gitlab::BitbucketImport::Client::Unauthorized, with: :bitbucket_unauthorized rescue_from Bitbucket::Error::Unauthorized, with: :bitbucket_unauthorized
def callback def callback
request_token = session.delete(:oauth_request_token) response = client.auth_code.get_token(params[:code], redirect_uri: callback_import_bitbucket_url)
raise "Session expired!" if request_token.nil?
request_token.symbolize_keys! session[:bitbucket_token] = response.token
session[:bitbucket_expires_at] = response.expires_at
access_token = client.get_token(request_token, params[:oauth_verifier], callback_import_bitbucket_url) session[:bitbucket_expires_in] = response.expires_in
session[:bitbucket_refresh_token] = response.refresh_token
session[:bitbucket_access_token] = access_token.token
session[:bitbucket_access_token_secret] = access_token.secret
redirect_to status_import_bitbucket_url redirect_to status_import_bitbucket_url
end end
def status def status
@repos = client.projects client = Bitbucket::Client.new(credentials)
@incompatible_repos = client.incompatible_projects repos = client.repos
@repos = repos.select(&:valid?)
@incompatible_repos = repos.reject(&:valid?)
@already_added_projects = current_user.created_projects.where(import_type: "bitbucket") @already_added_projects = current_user.created_projects.where(import_type: 'bitbucket')
already_added_projects_names = @already_added_projects.pluck(:import_source) already_added_projects_names = @already_added_projects.pluck(:import_source)
@repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } @repos.to_a.reject! { |repo| already_added_projects_names.include?(repo.full_name) }
end end
def jobs def jobs
jobs = current_user.created_projects.where(import_type: "bitbucket").to_json(only: [:id, :import_status]) render json: current_user.created_projects
render json: jobs .where(import_type: 'bitbucket')
.to_json(only: [:id, :import_status])
end end
def create def create
client = Bitbucket::Client.new(credentials)
@repo_id = params[:repo_id].to_s @repo_id = params[:repo_id].to_s
repo = client.project(@repo_id.gsub('___', '/')) name = @repo_id.to_s.gsub('___', '/')
@project_name = repo['slug'] repo = client.repo(name)
@target_namespace = find_or_create_namespace(repo['owner'], client.user['user']['username']) @project_name = repo.name
unless Gitlab::BitbucketImport::KeyAdder.new(repo, current_user, access_params).execute repo_owner = repo.owner
render 'deploy_key' and return repo_owner = current_user.username if repo_owner == client.user.username
end @target_namespace = params[:new_namespace].presence || repo_owner
namespace = find_or_create_namespace(target_namespace_name, repo_owner)
if current_user.can?(:create_projects, @target_namespace) if current_user.can?(:create_projects, @target_namespace)
@project = Gitlab::BitbucketImport::ProjectCreator.new(repo, @target_namespace, current_user, access_params).execute @project = Gitlab::BitbucketImport::ProjectCreator.new(repo, namespace, current_user, credentials).execute
else else
render 'unauthorized' render 'unauthorized'
end end
...@@ -54,8 +59,15 @@ class Import::BitbucketController < Import::BaseController ...@@ -54,8 +59,15 @@ class Import::BitbucketController < Import::BaseController
private private
def client def client
@client ||= Gitlab::BitbucketImport::Client.new(session[:bitbucket_access_token], @client ||= OAuth2::Client.new(provider.app_id, provider.app_secret, options)
session[:bitbucket_access_token_secret]) end
def provider
Gitlab.config.omniauth.providers.find { |provider| provider.name == 'bitbucket' }
end
def options
OmniAuth::Strategies::Bitbucket.default_options[:client_options].deep_symbolize_keys
end end
def verify_bitbucket_import_enabled def verify_bitbucket_import_enabled
...@@ -63,26 +75,23 @@ class Import::BitbucketController < Import::BaseController ...@@ -63,26 +75,23 @@ class Import::BitbucketController < Import::BaseController
end end
def bitbucket_auth def bitbucket_auth
if session[:bitbucket_access_token].blank? go_to_bitbucket_for_permissions if session[:bitbucket_token].blank?
go_to_bitbucket_for_permissions
end
end end
def go_to_bitbucket_for_permissions def go_to_bitbucket_for_permissions
request_token = client.request_token(callback_import_bitbucket_url) redirect_to client.auth_code.authorize_url(redirect_uri: callback_import_bitbucket_url)
session[:oauth_request_token] = request_token
redirect_to client.authorize_url(request_token, callback_import_bitbucket_url)
end end
def bitbucket_unauthorized def bitbucket_unauthorized
go_to_bitbucket_for_permissions go_to_bitbucket_for_permissions
end end
def access_params def credentials
{ {
bitbucket_access_token: session[:bitbucket_access_token], token: session[:bitbucket_token],
bitbucket_access_token_secret: session[:bitbucket_access_token_secret] expires_at: session[:bitbucket_expires_at],
expires_in: session[:bitbucket_expires_in],
refresh_token: session[:bitbucket_refresh_token]
} }
end end
end end
- page_title "Bitbucket import" - page_title 'Bitbucket import'
- header_title "Projects", root_path - header_title 'Projects', root_path
%h3.page-title %h3.page-title
%i.fa.fa-bitbucket %i.fa.fa-bitbucket
Import projects from Bitbucket Import projects from Bitbucket
...@@ -10,13 +11,13 @@ ...@@ -10,13 +11,13 @@
%hr %hr
%p %p
- if @incompatible_repos.any? - if @incompatible_repos.any?
= button_tag class: "btn btn-import btn-success js-import-all" do = button_tag class: 'btn btn-import btn-success js-import-all' do
Import all compatible projects Import all compatible projects
= icon("spinner spin", class: "loading-icon") = icon('spinner spin', class: 'loading-icon')
- else - else
= button_tag class: "btn btn-success js-import-all" do = button_tag class: 'btn btn-success js-import-all' do
Import all projects Import all projects
= icon("spinner spin", class: "loading-icon") = icon('spinner spin', class: 'loading-icon')
.table-responsive .table-responsive
%table.table.import-jobs %table.table.import-jobs
...@@ -32,7 +33,7 @@ ...@@ -32,7 +33,7 @@
- @already_added_projects.each do |project| - @already_added_projects.each do |project|
%tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
%td %td
= link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: "_blank" = link_to project.import_source, 'https://bitbucket.org/#{project.import_source}', target: '_blank'
%td %td
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] = link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
%td.job-status %td.job-status
...@@ -47,31 +48,31 @@ ...@@ -47,31 +48,31 @@
= project.human_import_status_name = project.human_import_status_name
- @repos.each do |repo| - @repos.each do |repo|
%tr{id: "repo_#{repo["owner"]}___#{repo["slug"]}"} %tr{id: "repo_#{repo.owner}___#{repo.slug}"}
%td %td
= link_to "#{repo["owner"]}/#{repo["slug"]}", "https://bitbucket.org/#{repo["owner"]}/#{repo["slug"]}", target: "_blank" = link_to "#{repo.full_name}", "https://bitbucket.org/#{repo.full_name}", target: "_blank"
%td.import-target %td.import-target
= import_project_target(repo['owner'], repo['slug']) = "#{repo.full_name}"
%td.import-actions.job-status %td.import-actions.job-status
= button_tag class: "btn btn-import js-add-to-import" do = button_tag class: 'btn btn-import js-add-to-import' do
Import Import
= icon("spinner spin", class: "loading-icon") = icon('spinner spin', class: 'loading-icon')
- @incompatible_repos.each do |repo| - @incompatible_repos.each do |repo|
%tr{id: "repo_#{repo["owner"]}___#{repo["slug"]}"} %tr{id: "repo_#{repo.owner}___#{repo.slug}"}
%td %td
= link_to "#{repo["owner"]}/#{repo["slug"]}", "https://bitbucket.org/#{repo["owner"]}/#{repo["slug"]}", target: "_blank" = link_to "#{repo.full_name}", "https://bitbucket.org/#{repo.full_name}", target: '_blank'
%td.import-target %td.import-target
%td.import-actions-job-status %td.import-actions-job-status
= label_tag "Incompatible Project", nil, class: "label label-danger" = label_tag 'Incompatible Project', nil, class: 'label label-danger'
- if @incompatible_repos.any? - if @incompatible_repos.any?
%p %p
One or more of your Bitbucket projects cannot be imported into GitLab One or more of your Bitbucket projects cannot be imported into GitLab
directly because they use Subversion or Mercurial for version control, directly because they use Subversion or Mercurial for version control,
rather than Git. Please convert rather than Git. Please convert
= link_to "them to Git,", "https://www.atlassian.com/git/tutorials/migrating-overview" = link_to 'them to Git,', 'https://www.atlassian.com/git/tutorials/migrating-overview'
and go through the and go through the
= link_to "import flow", status_import_bitbucket_path, "data-no-turbolink" => "true" = link_to 'import flow', status_import_bitbucket_path, 'data-no-turbolink' => 'true'
again. again.
.js-importer-status{ data: { jobs_import_path: "#{jobs_import_bitbucket_path}", import_path: "#{import_bitbucket_path}" } } .js-importer-status{ data: { jobs_import_path: "#{jobs_import_bitbucket_path}", import_path: "#{import_bitbucket_path}" } }
module Bitbucket
module Error
class Unauthorized < StandardError
end
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