2015-02-17 10:59:50 -05:00
|
|
|
module Gitlab
|
|
|
|
module BitbucketImport
|
|
|
|
class Client
|
2015-07-28 09:33:16 -04:00
|
|
|
class Unauthorized < StandardError; end
|
|
|
|
|
2015-02-17 10:59:50 -05:00
|
|
|
attr_reader :consumer, :api
|
|
|
|
|
2016-03-28 10:35:03 -04:00
|
|
|
def self.from_project(project)
|
2016-04-06 04:36:30 -04:00
|
|
|
import_data_credentials = project.import_data.credentials if project.import_data
|
|
|
|
if import_data_credentials && import_data_credentials[:bb_session]
|
|
|
|
token = import_data_credentials[:bb_session][:bitbucket_access_token]
|
|
|
|
token_secret = import_data_credentials[:bb_session][:bitbucket_access_token_secret]
|
2016-03-28 10:35:03 -04:00
|
|
|
new(token, token_secret)
|
|
|
|
else
|
2016-04-27 03:28:08 -04:00
|
|
|
raise Projects::ImportService::Error, "Unable to find project import data credentials for project ID: #{project.id}"
|
2016-03-28 10:35:03 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-17 10:59:50 -05:00
|
|
|
def initialize(access_token = nil, access_token_secret = nil)
|
|
|
|
@consumer = ::OAuth::Consumer.new(
|
|
|
|
config.app_id,
|
|
|
|
config.app_secret,
|
|
|
|
bitbucket_options
|
|
|
|
)
|
|
|
|
|
|
|
|
if access_token && access_token_secret
|
|
|
|
@api = ::OAuth::AccessToken.new(@consumer, access_token, access_token_secret)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def request_token(redirect_uri)
|
|
|
|
request_token = consumer.get_request_token(oauth_callback: redirect_uri)
|
|
|
|
|
|
|
|
{
|
|
|
|
oauth_token: request_token.token,
|
|
|
|
oauth_token_secret: request_token.secret,
|
|
|
|
oauth_callback_confirmed: request_token.callback_confirmed?.to_s
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def authorize_url(request_token, redirect_uri)
|
|
|
|
request_token = ::OAuth::RequestToken.from_hash(consumer, request_token) if request_token.is_a?(Hash)
|
|
|
|
|
|
|
|
if request_token.callback_confirmed?
|
|
|
|
request_token.authorize_url
|
|
|
|
else
|
|
|
|
request_token.authorize_url(oauth_callback: redirect_uri)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_token(request_token, oauth_verifier, redirect_uri)
|
|
|
|
request_token = ::OAuth::RequestToken.from_hash(consumer, request_token) if request_token.is_a?(Hash)
|
|
|
|
|
|
|
|
if request_token.callback_confirmed?
|
|
|
|
request_token.get_access_token(oauth_verifier: oauth_verifier)
|
|
|
|
else
|
|
|
|
request_token.get_access_token(oauth_callback: redirect_uri)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def user
|
2015-07-28 09:33:16 -04:00
|
|
|
JSON.parse(get("/api/1.0/user").body)
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def issues(project_identifier)
|
2015-08-31 20:03:09 -04:00
|
|
|
all_issues = []
|
|
|
|
offset = 0
|
2016-04-06 04:36:30 -04:00
|
|
|
per_page = 50 # Maximum number allowed by Bitbucket
|
2015-08-31 20:03:09 -04:00
|
|
|
index = 0
|
|
|
|
|
|
|
|
begin
|
|
|
|
issues = JSON.parse(get(issue_api_endpoint(project_identifier, per_page, offset)).body)
|
|
|
|
# Find out how many total issues are present
|
|
|
|
total = issues["count"] if index == 0
|
|
|
|
all_issues.concat(issues["issues"])
|
|
|
|
offset += issues["issues"].count
|
|
|
|
index += 1
|
|
|
|
end while all_issues.count < total
|
|
|
|
|
|
|
|
all_issues
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def issue_comments(project_identifier, issue_id)
|
2015-08-31 20:03:09 -04:00
|
|
|
comments = JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body)
|
|
|
|
comments.sort_by { |comment| comment["utc_created_on"] }
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def project(project_identifier)
|
2015-07-28 09:33:16 -04:00
|
|
|
JSON.parse(get("/api/1.0/repositories/#{project_identifier}").body)
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
2015-02-18 11:00:26 -05:00
|
|
|
def find_deploy_key(project_identifier, key)
|
2015-07-28 09:33:16 -04:00
|
|
|
JSON.parse(get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key|
|
2015-02-18 11:00:26 -05:00
|
|
|
deploy_key["key"].chomp == key.chomp
|
2015-02-18 12:10:22 -05:00
|
|
|
end
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def add_deploy_key(project_identifier, key)
|
2015-02-18 11:00:26 -05:00
|
|
|
deploy_key = find_deploy_key(project_identifier, key)
|
|
|
|
return if deploy_key
|
|
|
|
|
2015-02-17 10:59:50 -05:00
|
|
|
JSON.parse(api.post("/api/1.0/repositories/#{project_identifier}/deploy-keys", key: key, label: "GitLab import key").body)
|
|
|
|
end
|
|
|
|
|
2015-02-18 11:00:26 -05:00
|
|
|
def delete_deploy_key(project_identifier, key)
|
|
|
|
deploy_key = find_deploy_key(project_identifier, key)
|
|
|
|
return unless deploy_key
|
|
|
|
|
|
|
|
api.delete("/api/1.0/repositories/#{project_identifier}/deploy-keys/#{deploy_key["pk"]}").code == "204"
|
|
|
|
end
|
|
|
|
|
2015-02-17 10:59:50 -05:00
|
|
|
def projects
|
2015-07-28 09:33:16 -04:00
|
|
|
JSON.parse(get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" }
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
2015-08-07 04:02:01 -04:00
|
|
|
def incompatible_projects
|
|
|
|
JSON.parse(get("/api/1.0/user/repositories").body).reject { |repo| repo["scm"] == "git" }
|
|
|
|
end
|
|
|
|
|
2015-02-17 10:59:50 -05:00
|
|
|
private
|
|
|
|
|
2015-07-28 09:33:16 -04:00
|
|
|
def get(url)
|
|
|
|
response = api.get(url)
|
2016-05-23 13:10:42 -04:00
|
|
|
raise Unauthorized if (400..499).cover?(response.code.to_i)
|
2015-07-28 09:33:16 -04:00
|
|
|
|
|
|
|
response
|
|
|
|
end
|
|
|
|
|
2015-08-31 20:03:09 -04:00
|
|
|
def issue_api_endpoint(project_identifier, per_page, offset)
|
|
|
|
"/api/1.0/repositories/#{project_identifier}/issues?sort=utc_created_on&limit=#{per_page}&start=#{offset}"
|
|
|
|
end
|
|
|
|
|
2015-02-17 10:59:50 -05:00
|
|
|
def config
|
2016-04-06 04:36:30 -04:00
|
|
|
Gitlab.config.omniauth.providers.find { |provider| provider.name == "bitbucket" }
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def bitbucket_options
|
2015-03-22 21:07:33 -04:00
|
|
|
OmniAuth::Strategies::Bitbucket.default_options[:client_options].symbolize_keys
|
2015-02-17 10:59:50 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|