From eede0323453190440a8d738b5eab0723f54dee65 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 22 Apr 2016 12:43:10 -0700 Subject: [PATCH 1/2] Backport GitHub Enterprise import support from EE These changes were pulled from GitLab EE to support configuring an alternative API URL than the default https://api.github.com. In addition, the `verify_ssl` flag allows users to disable SSL cert checking. One modification: add a default `args` option if it does not exist to avoid breaking existing configurations. --- CHANGELOG | 1 + config/gitlab.yml.example | 2 + config/initializers/1_settings.rb | 24 +++++++++++ doc/integration/github.md | 14 +++++++ lib/gitlab/github_import/client.rb | 15 +++++-- .../import/github_controller_spec.rb | 2 + spec/lib/gitlab/github_import/client_spec.rb | 40 +++++++++++++++++-- spec/services/projects/import_service_spec.rb | 13 ++++-- 8 files changed, 101 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e52e52691c..e899877380 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ v 8.8.0 (unreleased) - Replace Devise Async with Devise ActiveJob integration. !3902 (Connor Shea) - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea) - Added button to toggle whitespaces changes on diff view + - Backport GitLab Enterprise support from EE v 8.7.1 (unreleased) - Throttle the update of `project.last_activity_at` to 1 minute. !3848 diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index d9c15f8140..2790f1c8a2 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -350,6 +350,8 @@ production: &base # - { name: 'github', # app_id: 'YOUR_APP_ID', # app_secret: 'YOUR_APP_SECRET', + # url: "https://github.com/", + # verify_ssl: true, # args: { scope: 'user:email' } } # - { name: 'bitbucket', # app_id: 'YOUR_APP_ID', diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 10c25044b7..3964165518 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -140,6 +140,30 @@ Settings.omniauth.cas3['session_duration'] ||= 8.hours Settings.omniauth['session_tickets'] ||= Settingslogic.new({}) Settings.omniauth.session_tickets['cas3'] = 'ticket' +# Fill out omniauth-gitlab settings. It is needed for easy set up GHE or GH by just specifying url. + +github_default_url = "https://github.com" +github_settings = Settings.omniauth['providers'].find { |provider| provider["name"] == "github"} + +if github_settings + # For compatibility with old config files (before 7.8) + # where people dont have url in github settings + if github_settings['url'].blank? + github_settings['url'] = github_default_url + end + + github_settings["args"] ||= Settingslogic.new({}) + + if github_settings["url"].include?(github_default_url) + github_settings["args"]["client_options"] = OmniAuth::Strategies::GitHub.default_options[:client_options] + else + github_settings["args"]["client_options"] = { + "site" => File.join(github_settings["url"], "api/v3"), + "authorize_url" => File.join(github_settings["url"], "login/oauth/authorize"), + "token_url" => File.join(github_settings["url"], "login/oauth/access_token") + } + end +end Settings['shared'] ||= Settingslogic.new({}) Settings.shared['path'] = File.expand_path(Settings.shared['path'] || "shared", Rails.root) diff --git a/doc/integration/github.md b/doc/integration/github.md index 1890edd7a4..ac17e2069f 100644 --- a/doc/integration/github.md +++ b/doc/integration/github.md @@ -60,12 +60,26 @@ GitHub will generate an application ID and secret key for you to use. For installation from source: + For GitHub.com: + ``` - { name: 'github', app_id: 'YOUR_APP_ID', app_secret: 'YOUR_APP_SECRET', args: { scope: 'user:email' } } ``` + + For GitHub Enterprise: + + ``` + - { name: 'github', app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + url: "https://github.example.com/", + args: { scope: 'user:email' } } + ``` + + __Replace `https://github.example.com/` with your GitHub URL__ + 1. Change 'YOUR_APP_ID' to the client ID from the GitHub application page from step 7. 1. Change 'YOUR_APP_SECRET' to the client secret from the GitHub application page from step 7. diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb index 74d1529e1f..67988ea346 100644 --- a/lib/gitlab/github_import/client.rb +++ b/lib/gitlab/github_import/client.rb @@ -7,12 +7,19 @@ module Gitlab @client = ::OAuth2::Client.new( config.app_id, config.app_secret, - github_options + github_options.merge(ssl: { verify: config['verify_ssl'] }) ) if access_token ::Octokit.auto_paginate = true - @api = ::Octokit::Client.new(access_token: access_token) + + @api = ::Octokit::Client.new( + access_token: access_token, + api_endpoint: github_options[:site], + connection_options: { + ssl: { verify: config['verify_ssl'] } + } + ) end end @@ -42,11 +49,11 @@ module Gitlab private def config - Gitlab.config.omniauth.providers.find{|provider| provider.name == "github"} + Gitlab.config.omniauth.providers.find { |provider| provider.name == "github" } end def github_options - OmniAuth::Strategies::GitHub.default_options[:client_options].to_h.symbolize_keys + config["args"]["client_options"].deep_symbolize_keys end end end diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index bbf8adef53..bcc713dce2 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -22,6 +22,8 @@ describe Import::GithubController do token = "asdasd12345" allow_any_instance_of(Gitlab::GithubImport::Client). to receive(:get_token).and_return(token) + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:github_options).and_return({}) stub_omniauth_provider('github') get :callback diff --git a/spec/lib/gitlab/github_import/client_spec.rb b/spec/lib/gitlab/github_import/client_spec.rb index 49d8cdf431..7c21cbe96d 100644 --- a/spec/lib/gitlab/github_import/client_spec.rb +++ b/spec/lib/gitlab/github_import/client_spec.rb @@ -2,15 +2,49 @@ require 'spec_helper' describe Gitlab::GithubImport::Client, lib: true do let(:token) { '123456' } - let(:client) { Gitlab::GithubImport::Client.new(token) } + let(:github_provider) { Settingslogic.new('app_id' => 'asd123', 'app_secret' => 'asd123', 'name' => 'github', 'args' => { 'client_options' => {} }) } + + subject(:client) { described_class.new(token) } before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "github") + allow(Gitlab.config.omniauth).to receive(:providers).and_return([github_provider]) end - it 'all OAuth2 client options are symbols' do + it 'convert OAuth2 client options to symbols' do client.client.options.keys.each do |key| expect(key).to be_kind_of(Symbol) end end + + it 'does not crash (e.g. Settingslogic::MissingSetting) when verify_ssl config is not present' do + expect { client.api }.not_to raise_error + end + + context 'allow SSL verification to be configurable on API' do + before do + github_provider['verify_ssl'] = false + end + + it 'uses supplied value' do + expect(client.client.options[:connection_opts][:ssl]).to eq({ verify: false }) + expect(client.api.connection_options[:ssl]).to eq({ verify: false }) + end + end + + context 'when provider does not specity an API endpoint' do + it 'uses GitHub root API endpoint' do + expect(client.api.api_endpoint).to eq 'https://api.github.com/' + end + end + + context 'when provider specify a custom API endpoint' do + before do + github_provider['args']['client_options']['site'] = 'https://github.company.com/' + end + + it 'uses the custom API endpoint' do + expect(OmniAuth::Strategies::GitHub).not_to receive(:default_options) + expect(client.api.api_endpoint).to eq 'https://github.company.com/' + end + end end diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb index 32bf3acf48..7f2dcdab96 100644 --- a/spec/services/projects/import_service_spec.rb +++ b/spec/services/projects/import_service_spec.rb @@ -112,9 +112,16 @@ describe Projects::ImportService, services: true do def stub_github_omniauth_provider provider = OpenStruct.new( - name: 'github', - app_id: 'asd123', - app_secret: 'asd123' + 'name' => 'github', + 'app_id' => 'asd123', + 'app_secret' => 'asd123', + 'args' => { + 'client_options' => { + 'site' => 'https://github.com/api/v3', + 'authorize_url' => 'https://github.com/login/oauth/authorize', + 'token_url' => 'https://github.com/login/oauth/access_token' + } + } ) Gitlab.config.omniauth.providers << provider From c47183d78723a30733dc465f72e37299d8628363 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 26 Apr 2016 21:02:24 -0700 Subject: [PATCH 2/2] Fixes for review of GitHub Enterprise backport changes --- config/initializers/1_settings.rb | 6 +++--- doc/integration/github.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 3964165518..6eb144d043 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -143,7 +143,7 @@ Settings.omniauth.session_tickets['cas3'] = 'ticket' # Fill out omniauth-gitlab settings. It is needed for easy set up GHE or GH by just specifying url. github_default_url = "https://github.com" -github_settings = Settings.omniauth['providers'].find { |provider| provider["name"] == "github"} +github_settings = Settings.omniauth['providers'].find { |provider| provider["name"] == "github" } if github_settings # For compatibility with old config files (before 7.8) @@ -158,9 +158,9 @@ if github_settings github_settings["args"]["client_options"] = OmniAuth::Strategies::GitHub.default_options[:client_options] else github_settings["args"]["client_options"] = { - "site" => File.join(github_settings["url"], "api/v3"), + "site" => File.join(github_settings["url"], "api/v3"), "authorize_url" => File.join(github_settings["url"], "login/oauth/authorize"), - "token_url" => File.join(github_settings["url"], "login/oauth/access_token") + "token_url" => File.join(github_settings["url"], "login/oauth/access_token") } end end diff --git a/doc/integration/github.md b/doc/integration/github.md index ac17e2069f..e1f9242fd0 100644 --- a/doc/integration/github.md +++ b/doc/integration/github.md @@ -78,7 +78,7 @@ GitHub will generate an application ID and secret key for you to use. args: { scope: 'user:email' } } ``` - __Replace `https://github.example.com/` with your GitHub URL__ + __Replace `https://github.example.com/` with your GitHub URL.__ 1. Change 'YOUR_APP_ID' to the client ID from the GitHub application page from step 7.