Commit c6c8ffbd25f158b867ab1e4719fd1dfd0f34ecd4

Authored by Stephen Crosby
2 parents a93c24f6 1ac7afa9
Exists in master and in 1 other branch production

Merge pull request #958 from appropriate/github-enterprise-login

GitHub enterprise login
@@ -17,7 +17,9 @@ ERRBIT_PER_APP_NOTIFY_AT_NOTICES=false @@ -17,7 +17,9 @@ ERRBIT_PER_APP_NOTIFY_AT_NOTICES=false
17 MONGO_URL='mongodb://localhost' 17 MONGO_URL='mongodb://localhost'
18 ERRBIT_LOG_LEVEL=info 18 ERRBIT_LOG_LEVEL=info
19 ERRBIT_LOG_LOCATION=STDOUT 19 ERRBIT_LOG_LOCATION=STDOUT
20 -GITHUB_URL='https://github.com' 20 +GITHUB_URL=https://github.com
21 GITHUB_AUTHENTICATION=true 21 GITHUB_AUTHENTICATION=true
  22 +GITHUB_API_URL=https://api.github.com
22 GITHUB_ACCESS_SCOPE='[repo]' 23 GITHUB_ACCESS_SCOPE='[repo]'
  24 +GITHUB_SITE_TITLE=GitHub
23 DEVISE_MODULES='[database_authenticatable,recoverable,rememberable,trackable,validatable,omniauthable]' 25 DEVISE_MODULES='[database_authenticatable,recoverable,rememberable,trackable,validatable,omniauthable]'
app/controllers/users/omniauth_callbacks_controller.rb
@@ -3,11 +3,13 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController @@ -3,11 +3,13 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
3 github_login = env["omniauth.auth"].extra.raw_info.login 3 github_login = env["omniauth.auth"].extra.raw_info.login
4 github_token = env["omniauth.auth"].credentials.token 4 github_token = env["omniauth.auth"].credentials.token
5 github_user = User.where(:github_login => github_login).first 5 github_user = User.where(:github_login => github_login).first
  6 + github_site_title = Errbit::Config.github_site_title
6 7
7 if github_user.nil? && github_org_id = Errbit::Config.github_org_id 8 if github_user.nil? && github_org_id = Errbit::Config.github_org_id
8 # See if they are a member of the organization that we have access for 9 # See if they are a member of the organization that we have access for
9 # If they are, automatically create an account 10 # If they are, automatically create an account
10 client = Octokit::Client.new(access_token: github_token) 11 client = Octokit::Client.new(access_token: github_token)
  12 + client.api_endpoint = Errbit::Config.github_api_url
11 org_ids = client.organizations.map { |org| org.id } 13 org_ids = client.organizations.map { |org| org.id }
12 if org_ids.include?(github_org_id) 14 if org_ids.include?(github_org_id)
13 github_user = User.create(name: env["omniauth.auth"].extra.raw_info.name, email: env["omniauth.auth"].extra.raw_info.email) 15 github_user = User.create(name: env["omniauth.auth"].extra.raw_info.name, email: env["omniauth.auth"].extra.raw_info.email)
@@ -18,21 +20,21 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController @@ -18,21 +20,21 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
18 if current_user 20 if current_user
19 # ... unless a user is already registered with same github login 21 # ... unless a user is already registered with same github login
20 if github_user && github_user != current_user 22 if github_user && github_user != current_user
21 - flash[:error] = "User already registered with GitHub login '#{github_login}'!" 23 + flash[:error] = "User already registered with #{github_site_title} login '#{github_login}'!"
22 else 24 else
23 # Add github details to current user 25 # Add github details to current user
24 update_user_with_github_attributes(current_user, github_login, github_token) 26 update_user_with_github_attributes(current_user, github_login, github_token)
25 - flash[:success] = "Successfully linked GitHub account!" 27 + flash[:success] = "Successfully linked #{github_site_title} account!"
26 end 28 end
27 # User must have clicked 'link account' from their user page, so redirect there. 29 # User must have clicked 'link account' from their user page, so redirect there.
28 redirect_to user_path(current_user) 30 redirect_to user_path(current_user)
29 elsif github_user 31 elsif github_user
30 # Store OAuth token 32 # Store OAuth token
31 update_user_with_github_attributes(github_user, github_login, github_token) 33 update_user_with_github_attributes(github_user, github_login, github_token)
32 - flash[:success] = I18n.t "devise.omniauth_callbacks.success", :kind => "GitHub" 34 + flash[:success] = I18n.t "devise.omniauth_callbacks.success", :kind => github_site_title
33 sign_in_and_redirect github_user, :event => :authentication 35 sign_in_and_redirect github_user, :event => :authentication
34 else 36 else
35 - flash[:error] = "There are no authorized users with GitHub login '#{github_login}'. Please ask an administrator to register your user account." 37 + flash[:error] = "There are no authorized users with #{github_site_title} login '#{github_login}'. Please ask an administrator to register your user account."
36 redirect_to new_user_session_path 38 redirect_to new_user_session_path
37 end 39 end
38 end 40 end
app/views/devise/sessions/new.html.haml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 - if Errbit::Config.github_authentication 4 - if Errbit::Config.github_authentication
5 - content_for :action_bar do 5 - content_for :action_bar do
6 %div.action-bar 6 %div.action-bar
7 - %span.github= link_to "Sign in with GitHub", user_omniauth_authorize_path(:github) 7 + %span.github= link_to "Sign in with #{Errbit::Config.github_site_title}", user_omniauth_authorize_path(:github)
8 8
9 = form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| 9 = form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
10 .required 10 .required
app/views/shared/_link_github_account.html.haml
1 - if Errbit::Config.github_authentication && user == current_user 1 - if Errbit::Config.github_authentication && user == current_user
2 - if user.github_account? 2 - if user.github_account?
3 - %span.github= link_to "Unlink GitHub account", unlink_github_user_path(user), :method => :delete, :data => { :confirm => "Are you sure?" } 3 + %span.github= link_to "Unlink #{Errbit::Config.github_site_title} account", unlink_github_user_path(user), :method => :delete, :data => { :confirm => "Are you sure?" }
4 - else 4 - else
5 - %span.github= link_to "Link GitHub account", user_omniauth_authorize_path(:github) 5 + %span.github= link_to "Link #{Errbit::Config.github_site_title} account", user_omniauth_authorize_path(:github)
app/views/users/show.html.haml
@@ -21,8 +21,8 @@ @@ -21,8 +21,8 @@
21 %td.main= user.username 21 %td.main= user.username
22 - if Errbit::Config.github_authentication && user.github_login.present? 22 - if Errbit::Config.github_authentication && user.github_login.present?
23 %tr 23 %tr
24 - %th GitHub Login  
25 - %td.main= link_to user.github_login, "https://github.com/#{user.github_login}" 24 + %th= "#{Errbit::Config.github_site_title} Login"
  25 + %td.main= link_to user.github_login, "#{Errbit::Config.github_url}/#{user.github_login}"
26 %tr 26 %tr
27 %th Admin? 27 %th Admin?
28 %td= user.admin? ? 'Y' : 'N' 28 %td= user.admin? ? 'Y' : 'N'
config/initializers/devise.rb
@@ -236,11 +236,20 @@ Devise.setup do |config| @@ -236,11 +236,20 @@ Devise.setup do |config|
236 # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' 236 # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
237 237
238 if Errbit::Config.github_authentication || Rails.env.test? 238 if Errbit::Config.github_authentication || Rails.env.test?
  239 + github_options = {
  240 + :scope => Errbit::Config.github_access_scope.join(','),
  241 + :skip_info => true,
  242 + :client_options => {
  243 + :site => Errbit::Config.github_api_url,
  244 + :authorize_url => "#{Errbit::Config.github_url}/login/oauth/authorize",
  245 + :token_url => "#{Errbit::Config.github_url}/login/oauth/access_token"
  246 + }
  247 + }
  248 +
239 config.omniauth :github, 249 config.omniauth :github,
240 Errbit::Config.github_client_id, 250 Errbit::Config.github_client_id,
241 Errbit::Config.github_secret, 251 Errbit::Config.github_secret,
242 - :scope => Errbit::Config.github_access_scope.join(','),  
243 - :skip_info => true 252 + github_options
244 end 253 end
245 254
246 # ==> Warden configuration 255 # ==> Warden configuration
config/load.rb
@@ -37,6 +37,8 @@ Errbit::Config = Configurator.run({ @@ -37,6 +37,8 @@ Errbit::Config = Configurator.run({
37 github_secret: ['GITHUB_SECRET'], 37 github_secret: ['GITHUB_SECRET'],
38 github_org_id: ['GITHUB_ORG_ID'], 38 github_org_id: ['GITHUB_ORG_ID'],
39 github_access_scope: ['GITHUB_ACCESS_SCOPE'], 39 github_access_scope: ['GITHUB_ACCESS_SCOPE'],
  40 + github_api_url: ['GITHUB_API_URL'],
  41 + github_site_title: ['GITHUB_SITE_TITLE'],
40 42
41 email_delivery_method: ['EMAIL_DELIVERY_METHOD', -> (values) { 43 email_delivery_method: ['EMAIL_DELIVERY_METHOD', -> (values) {
42 values[:email_delivery_method] && values[:email_delivery_method].to_sym 44 values[:email_delivery_method] && values[:email_delivery_method].to_sym
docs/configuration.md
@@ -61,6 +61,9 @@ In order of precedence Errbit uses: @@ -61,6 +61,9 @@ In order of precedence Errbit uses:
61 <dt>GITHUB_URL 61 <dt>GITHUB_URL
62 <dd>Use this URL for interacting github. This is useful if you have a github enterprise account and you're using a URL other than https://github.com 62 <dd>Use this URL for interacting github. This is useful if you have a github enterprise account and you're using a URL other than https://github.com
63 <dd>defaults to https://github.com 63 <dd>defaults to https://github.com
  64 +<dt>GITHUB_API_URL</dt>
  65 +<dd>For github enterprise accounts, the API URL could be something like https://github.example.com/api/v3</dd>
  66 +<dd>defaults to https://api.github.com</dd>
64 <dt>GITHUB_AUTHENTICATION 67 <dt>GITHUB_AUTHENTICATION
65 <dd>Allow github sign-in via OAuth 68 <dd>Allow github sign-in via OAuth
66 <dd>defaults to true 69 <dd>defaults to true
@@ -73,6 +76,9 @@ In order of precedence Errbit uses: @@ -73,6 +76,9 @@ In order of precedence Errbit uses:
73 <dt>GITHUB_ACCESS_SCOPE 76 <dt>GITHUB_ACCESS_SCOPE
74 <dd>OAuth scope to request from users when they sign-in through github 77 <dd>OAuth scope to request from users when they sign-in through github
75 <dd>defaults to [repo] 78 <dd>defaults to [repo]
  79 +<dt>GITHUB_SITE_TITLE</dt>
  80 +<dd>The title to use for GitHub. This value is whatever you want displayed in the Errbit UI when referring to GitHub.</dd>
  81 +<dd>defaults to GitHub</dd>
76 <dt>EMAIL_DELIVERY_METHOD 82 <dt>EMAIL_DELIVERY_METHOD
77 <dd>:smtp or :sendmail, depending on how you want Errbit to send email 83 <dd>:smtp or :sendmail, depending on how you want Errbit to send email
78 <dt>SMTP_SERVER 84 <dt>SMTP_SERVER
spec/initializers/devise_spec.rb 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +describe 'initializers/devise' do
  2 + def load_initializer
  3 + load File.join(Rails.root, 'config', 'initializers', 'devise.rb')
  4 + end
  5 +
  6 + after do
  7 + # reset to the defaults
  8 + load_initializer
  9 + end
  10 +
  11 + describe 'omniauth github' do
  12 + it 'sets the client options correctly for the default github_url' do
  13 + load_initializer
  14 +
  15 + options = Devise.omniauth_configs[:github].options
  16 + expect(options).to have_key(:client_options)
  17 + expect(options[:client_options]).to eq({
  18 + site: 'https://api.github.com',
  19 + authorize_url: 'https://github.com/login/oauth/authorize',
  20 + token_url: 'https://github.com/login/oauth/access_token',
  21 + })
  22 + end
  23 +
  24 + it 'sets the client options correctly for the a GitHub Enterprise github_url' do
  25 + allow(Errbit::Config).to receive(:github_url).and_return('https://github.example.com')
  26 + allow(Errbit::Config).to receive(:github_api_url).and_return('https://github.example.com/api/v3')
  27 + load_initializer
  28 +
  29 + options = Devise.omniauth_configs[:github].options
  30 + expect(options).to have_key(:client_options)
  31 + expect(options[:client_options]).to eq({
  32 + site: 'https://github.example.com/api/v3',
  33 + authorize_url: 'https://github.example.com/login/oauth/authorize',
  34 + token_url: 'https://github.example.com/login/oauth/access_token',
  35 + })
  36 + end
  37 + end
  38 +end