Merge branch 'auth-icons-labels' into 'master'
Allow custom label to be set for authentication providers. Addresses internal issue https://dev.gitlab.org/gitlab/gitlabhq/issues/2341 Beside the above, I've: - Refactored `OauthHelper` to have clearer method names and behaviour - Moved some of `OauthHelper` behaviour to `Gitlab::OAuth::Provider` - Renamed `OauthHelper` to `AuthHelper` since LDAP, SAML, Kerberos aren't OAuth - Updated the icons for GitHub and GitLab In the examples below, "OurAuth" is a SAML provider with a custom label. ![Screen_Shot_2015-07-02_at_16.29.52](https://gitlab.com/gitlab-org/gitlab-ce/uploads/7d425bde69dc34e1667ebd5375d0266d/Screen_Shot_2015-07-02_at_16.29.52.png) ![Screen_Shot_2015-07-02_at_16.31.40](https://gitlab.com/gitlab-org/gitlab-ce/uploads/cbb273321ecdf4cab3d3ef0dc35553e7/Screen_Shot_2015-07-02_at_16.31.40.png) ![Screen_Shot_2015-07-02_at_16.32.39](https://gitlab.com/gitlab-org/gitlab-ce/uploads/d8dd6e1d0dc45a788e869cdcdc99e178/Screen_Shot_2015-07-02_at_16.32.39.png) ![Screen_Shot_2015-07-02_at_16.33.18](https://gitlab.com/gitlab-org/gitlab-ce/uploads/7dbfe8b0ae229c32a08d6c7442976d83/Screen_Shot_2015-07-02_at_16.33.18.png) See merge request !927
|
@ -77,6 +77,7 @@ v 7.12.2
|
|||
- Faster automerge check and merge itself when source and target branches are in same repository
|
||||
- Audit log for user authentication
|
||||
- Fix transferring of project to another group using the API.
|
||||
- Allow custom label to be set for authentication providers.
|
||||
|
||||
v 7.12.1
|
||||
- Fix error when deleting a user who has projects (Stan Hu)
|
||||
|
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
app/assets/images/auth_buttons/github_64.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/assets/images/auth_buttons/gitlab_64.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 6.4 KiB |
|
@ -299,14 +299,14 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def github_import_enabled?
|
||||
OauthHelper.enabled_oauth_providers.include?(:github)
|
||||
Gitlab::OAuth::Provider.enabled?(:github)
|
||||
end
|
||||
|
||||
def gitlab_import_enabled?
|
||||
OauthHelper.enabled_oauth_providers.include?(:gitlab)
|
||||
Gitlab::OAuth::Provider.enabled?(:gitlab)
|
||||
end
|
||||
|
||||
def bitbucket_import_enabled?
|
||||
OauthHelper.enabled_oauth_providers.include?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
|
||||
Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -72,10 +72,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
end
|
||||
end
|
||||
rescue Gitlab::OAuth::SignupDisabledError => e
|
||||
message = "Signing in using your #{oauth['provider']} account without a pre-existing GitLab account is not allowed."
|
||||
label = Gitlab::OAuth::Provider.label_for(oauth['provider'])
|
||||
message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed."
|
||||
|
||||
if current_application_settings.signup_enabled?
|
||||
message << " Create a GitLab account first, and then connect it to your #{oauth['provider']} account."
|
||||
message << " Create a GitLab account first, and then connect it to your #{label} account."
|
||||
end
|
||||
|
||||
flash[:notice] = message
|
||||
|
|
|
@ -90,7 +90,7 @@ class SessionsController < Devise::SessionsController
|
|||
# Prevent alert from popping up on the first page shown after authentication.
|
||||
flash[:alert] = nil
|
||||
|
||||
redirect_to omniauth_authorize_path(:user, provider.to_sym)
|
||||
redirect_to user_omniauth_authorize_path(provider.to_sym)
|
||||
end
|
||||
|
||||
def valid_otp_attempt?(user)
|
||||
|
|
50
app/helpers/auth_helper.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
module AuthHelper
|
||||
PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2).freeze
|
||||
FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos'].freeze
|
||||
|
||||
def ldap_enabled?
|
||||
Gitlab.config.ldap.enabled
|
||||
end
|
||||
|
||||
def provider_has_icon?(name)
|
||||
PROVIDERS_WITH_ICONS.include?(name.to_s)
|
||||
end
|
||||
|
||||
def auth_providers
|
||||
Gitlab::OAuth::Provider.providers
|
||||
end
|
||||
|
||||
def label_for_provider(name)
|
||||
Gitlab::OAuth::Provider.label_for(name)
|
||||
end
|
||||
|
||||
def form_based_provider?(name)
|
||||
FORM_BASED_PROVIDERS.any? { |pattern| pattern === name.to_s }
|
||||
end
|
||||
|
||||
def form_based_providers
|
||||
auth_providers.select { |provider| form_based_provider?(provider) }
|
||||
end
|
||||
|
||||
def button_based_providers
|
||||
auth_providers.reject { |provider| form_based_provider?(provider) }
|
||||
end
|
||||
|
||||
def provider_image_tag(provider, size = 64)
|
||||
label = label_for_provider(provider)
|
||||
|
||||
if provider_has_icon?(provider)
|
||||
file_name = "#{provider.to_s.split('_').first}_#{size}.png"
|
||||
|
||||
image_tag(image_path("auth_buttons/#{file_name}"), alt: label, title: "Sign in with #{label}")
|
||||
else
|
||||
label
|
||||
end
|
||||
end
|
||||
|
||||
def auth_active?(provider)
|
||||
current_user.identities.exists?(provider: provider.to_s)
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
module OauthHelper
|
||||
def ldap_enabled?
|
||||
Gitlab.config.ldap.enabled
|
||||
end
|
||||
|
||||
def default_providers
|
||||
[:twitter, :github, :gitlab, :bitbucket, :google_oauth2, :ldap]
|
||||
end
|
||||
|
||||
def enabled_oauth_providers
|
||||
Devise.omniauth_providers
|
||||
end
|
||||
|
||||
def enabled_social_providers
|
||||
enabled_oauth_providers.select do |name|
|
||||
[:saml, :twitter, :gitlab, :github, :bitbucket, :google_oauth2].include?(name.to_sym)
|
||||
end
|
||||
end
|
||||
|
||||
def additional_providers
|
||||
enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')}
|
||||
end
|
||||
|
||||
def oauth_image_tag(provider, size = 64)
|
||||
file_name = "#{provider.to_s.split('_').first}_#{size}.png"
|
||||
image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}")
|
||||
end
|
||||
|
||||
def oauth_active?(provider)
|
||||
current_user.identities.exists?(provider: provider.to_s)
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
module ProfileHelper
|
||||
def show_profile_username_tab?
|
||||
current_user.can_change_username?
|
||||
end
|
||||
|
||||
def show_profile_social_tab?
|
||||
enabled_social_providers.any?
|
||||
end
|
||||
|
||||
def show_profile_remove_tab?
|
||||
signup_enabled?
|
||||
end
|
||||
end
|
|
@ -8,7 +8,8 @@
|
|||
.form-group
|
||||
= f.label :provider, class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.select :provider, Gitlab::OAuth::Provider.names, { allow_blank: false }, class: 'form-control'
|
||||
- values = Gitlab::OAuth::Provider.providers.map { |name| ["#{Gitlab::OAuth::Provider.label_for(name)} (#{name})", name] }
|
||||
= f.select :provider, values, { allow_blank: false }, class: 'form-control'
|
||||
.form-group
|
||||
= f.label :extern_uid, "Identifier", class: 'control-label'
|
||||
.col-sm-10
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%tr
|
||||
%td
|
||||
= identity.provider
|
||||
= "#{Gitlab::OAuth::Provider.label_for(identity.provider)} (#{identity.provider})"
|
||||
%td
|
||||
= identity.extern_uid
|
||||
%td
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
%label{for: "remember_me"}
|
||||
= check_box_tag :remember_me, '1', false, id: 'remember_me'
|
||||
%span Remember me
|
||||
= button_tag "#{server['label']} Sign in", class: "btn-save btn"
|
||||
= button_tag "Sign in", class: "btn-save btn"
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
%p
|
||||
%span.light
|
||||
Sign in with
|
||||
- providers = additional_providers
|
||||
- providers = button_based_providers
|
||||
- providers.each do |provider|
|
||||
%span.light
|
||||
- if default_providers.include?(provider)
|
||||
= link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), method: :post, class: 'oauth-image-link'
|
||||
- else
|
||||
= link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), method: :post, class: "btn", "data-no-turbolink" => "true"
|
||||
- has_icon = provider_has_icon?(provider)
|
||||
= link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.login-heading
|
||||
%h3 Sign in
|
||||
.login-body
|
||||
- if ldap_enabled?
|
||||
- if form_based_providers.any?
|
||||
%ul.nav.nav-tabs
|
||||
- @ldap_servers.each_with_index do |server, i|
|
||||
%li{class: (:active if i.zero?)}
|
||||
|
|
|
@ -59,22 +59,22 @@
|
|||
%div
|
||||
= link_to 'Enable Two-factor Authentication', new_profile_two_factor_auth_path, class: 'btn btn-success'
|
||||
|
||||
- if show_profile_social_tab?
|
||||
- if button_based_providers.any?
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
Connected Accounts
|
||||
.panel-body
|
||||
.oauth-buttons.append-bottom-10
|
||||
%p Click on icon to activate signin with one of the following services
|
||||
- enabled_social_providers.each do |provider|
|
||||
- button_based_providers.each do |provider|
|
||||
.btn-group
|
||||
= link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider),
|
||||
method: :post, class: "btn btn-lg #{'active' if oauth_active?(provider)}"
|
||||
- if oauth_active?(provider)
|
||||
= link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true"
|
||||
|
||||
- if auth_active?(provider)
|
||||
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
|
||||
= icon('close')
|
||||
|
||||
- if show_profile_username_tab?
|
||||
- if current_user.can_change_username?
|
||||
.panel.panel-warning.update-username
|
||||
.panel-heading
|
||||
Change Username
|
||||
|
@ -94,7 +94,7 @@
|
|||
%div
|
||||
= f.submit 'Save username', class: "btn btn-warning"
|
||||
|
||||
- if show_profile_remove_tab?
|
||||
- if signup_enabled?
|
||||
.panel.panel-danger.remove-account
|
||||
.panel-heading
|
||||
Remove account
|
||||
|
|
|
@ -209,20 +209,29 @@ production: &base
|
|||
# arguments, followed by optional 'args' which can be either a hash or an array.
|
||||
# Documentation for this is available at http://doc.gitlab.com/ce/integration/omniauth.html
|
||||
providers:
|
||||
# - { name: 'google_oauth2', app_id: 'YOUR_APP_ID',
|
||||
# - { name: 'google_oauth2',
|
||||
# label: 'Google',
|
||||
# app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET',
|
||||
# args: { access_type: 'offline', approval_prompt: '' } }
|
||||
# - { name: 'twitter', app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET'}
|
||||
# - { name: 'github', app_id: 'YOUR_APP_ID',
|
||||
# - { name: 'twitter',
|
||||
# app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET' }
|
||||
# - { name: 'github',
|
||||
# label: 'GitHub',
|
||||
# app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET',
|
||||
# args: { scope: 'user:email' } }
|
||||
# - { name: 'gitlab', app_id: 'YOUR_APP_ID',
|
||||
# - { name: 'gitlab',
|
||||
# label: 'GitLab.com',
|
||||
# app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET',
|
||||
# args: { scope: 'api' } }
|
||||
# - { name: 'bitbucket', app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET'}
|
||||
# - { name: 'bitbucket',
|
||||
# app_id: 'YOUR_APP_ID',
|
||||
# app_secret: 'YOUR_APP_SECRET' }
|
||||
# - { name: 'saml',
|
||||
# label: 'Our SAML Provider',
|
||||
# args: {
|
||||
# assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
|
||||
# idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
|
||||
|
|
|
@ -84,7 +84,7 @@ Existing users can enable OmniAuth for specific providers after the account is c
|
|||
1. Sign in normally - whether standard sign in, LDAP, or another OmniAuth provider.
|
||||
1. Go to profile settings (the silhouette icon in the top right corner).
|
||||
1. Select the "Account" tab.
|
||||
1. Under "Social Accounts" select the desired OmniAuth provider, such as Twitter.
|
||||
1. Under "Connected Accounts" select the desired OmniAuth provider, such as Twitter.
|
||||
1. The user will be redirected to the provider. Once the user authorized GitLab they will be redirected back to GitLab.
|
||||
|
||||
The chosen OmniAuth provider is now active and can be used to sign in to GitLab from then on.
|
||||
|
|
|
@ -3,6 +3,14 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps
|
|||
include SharedPaths
|
||||
include SharedAdmin
|
||||
|
||||
before do
|
||||
allow(Devise).to receive(:omniauth_providers).and_return([:twitter, :twitter_updated])
|
||||
end
|
||||
|
||||
after do
|
||||
allow(Devise).to receive(:omniauth_providers).and_call_original
|
||||
end
|
||||
|
||||
step 'I should see all users' do
|
||||
User.all.each do |user|
|
||||
expect(page).to have_content user.name
|
||||
|
@ -121,7 +129,6 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
step 'I visit "Pete" identities page in admin' do
|
||||
allow(Gitlab::OAuth::Provider).to receive(:names).and_return(%w(twitter twitter_updated))
|
||||
visit admin_user_identities_path(@user)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
module Gitlab
|
||||
module OAuth
|
||||
class Provider
|
||||
def self.names
|
||||
providers = []
|
||||
|
||||
Gitlab.config.ldap.servers.values.each do |server|
|
||||
providers << server['provider_name']
|
||||
def self.providers
|
||||
Devise.omniauth_providers
|
||||
end
|
||||
|
||||
Gitlab.config.omniauth.providers.each do |provider|
|
||||
providers << provider['name']
|
||||
def self.enabled?(name)
|
||||
providers.include?(name.to_sym)
|
||||
end
|
||||
|
||||
providers
|
||||
def self.ldap_provider?(name)
|
||||
name.to_s.start_with?('ldap')
|
||||
end
|
||||
|
||||
def self.config_for(name)
|
||||
name = name.to_s
|
||||
if ldap_provider?(name)
|
||||
Gitlab::LDAP::Config.new(name).options
|
||||
else
|
||||
Gitlab.config.omniauth.providers.find { |provider| provider.name == name }
|
||||
end
|
||||
end
|
||||
|
||||
def self.label_for(name)
|
||||
config = config_for(name)
|
||||
(config && config['label']) || name.to_s.titleize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
20
spec/helpers/auth_helper_spec.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe AuthHelper do
|
||||
describe "button_based_providers" do
|
||||
it 'returns all enabled providers' do
|
||||
allow(helper).to receive(:auth_providers) { [:twitter, :github] }
|
||||
expect(helper.button_based_providers).to include(*[:twitter, :github])
|
||||
end
|
||||
|
||||
it 'does not return ldap provider' do
|
||||
allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] }
|
||||
expect(helper.button_based_providers).to include(:twitter)
|
||||
end
|
||||
|
||||
it 'returns empty array' do
|
||||
allow(helper).to receive(:auth_providers) { [] }
|
||||
expect(helper.button_based_providers).to eq([])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe OauthHelper do
|
||||
describe "additional_providers" do
|
||||
it 'returns all enabled providers' do
|
||||
allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :github] }
|
||||
expect(helper.additional_providers).to include(*[:twitter, :github])
|
||||
end
|
||||
|
||||
it 'does not return ldap provider' do
|
||||
allow(helper).to receive(:enabled_oauth_providers) { [:twitter, :ldapmain] }
|
||||
expect(helper.additional_providers).to include(:twitter)
|
||||
end
|
||||
|
||||
it 'returns empty array' do
|
||||
allow(helper).to receive(:enabled_oauth_providers) { [] }
|
||||
expect(helper.additional_providers).to eq([])
|
||||
end
|
||||
end
|
||||
end
|