client.rb 4.17 KB
Newer Older
Douwe Maan's avatar
Douwe Maan committed
1 2 3
module Gitlab
  module BitbucketImport
    class Client
4 5
      class Unauthorized < StandardError; end

Douwe Maan's avatar
Douwe Maan committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
      attr_reader :consumer, :api

      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
51
        JSON.parse(get("/api/1.0/user").body)
Douwe Maan's avatar
Douwe Maan committed
52 53 54
      end

      def issues(project_identifier)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
        all_issues = []
        offset = 0
        per_page = 50  # Maximum number allowed by Bitbucket
        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
Douwe Maan's avatar
Douwe Maan committed
70 71 72
      end

      def issue_comments(project_identifier, issue_id)
73 74
        comments = JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body)
        comments.sort_by { |comment| comment["utc_created_on"] }
Douwe Maan's avatar
Douwe Maan committed
75 76 77
      end

      def project(project_identifier)
78
        JSON.parse(get("/api/1.0/repositories/#{project_identifier}").body)
Douwe Maan's avatar
Douwe Maan committed
79 80
      end

81
      def find_deploy_key(project_identifier, key)
82
        JSON.parse(get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key|
83
          deploy_key["key"].chomp == key.chomp
Douwe Maan's avatar
Douwe Maan committed
84
        end
Douwe Maan's avatar
Douwe Maan committed
85 86 87
      end

      def add_deploy_key(project_identifier, key)
88 89 90
        deploy_key = find_deploy_key(project_identifier, key)
        return if deploy_key

Douwe Maan's avatar
Douwe Maan committed
91 92 93
        JSON.parse(api.post("/api/1.0/repositories/#{project_identifier}/deploy-keys", key: key, label: "GitLab import key").body)
      end

94 95 96 97 98 99 100
      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

Douwe Maan's avatar
Douwe Maan committed
101
      def projects
102
        JSON.parse(get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" }
Douwe Maan's avatar
Douwe Maan committed
103 104
      end

105 106 107 108
      def incompatible_projects
        JSON.parse(get("/api/1.0/user/repositories").body).reject { |repo| repo["scm"] == "git" }
      end

Douwe Maan's avatar
Douwe Maan committed
109 110
      private

111 112 113 114 115 116 117
      def get(url)
        response = api.get(url)
        raise Unauthorized if (400..499).include?(response.code.to_i)

        response
      end

118 119 120 121
      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

Douwe Maan's avatar
Douwe Maan committed
122 123 124 125 126
      def config
        Gitlab.config.omniauth.providers.find { |provider| provider.name == "bitbucket"}
      end

      def bitbucket_options
127
        OmniAuth::Strategies::Bitbucket.default_options[:client_options].symbolize_keys
Douwe Maan's avatar
Douwe Maan committed
128 129 130 131
      end
    end
  end
end