Commit c7460469 authored by Marin Jankovski's avatar Marin Jankovski

Merge branch 'external-omniauth-providers' into 'master'

Allow Omniauth providers to be marked as external

Related to #4009 

With this MR we will be able to allow the user to set which Omniauth Providers they would like to have as external. All users login in via these providers will be marked as external, even if they already had an account before. If the provider is removed form the list of external providers, the users will be marked as internal at their next login.

MR for Omnibus: gitlab-org/omnibus-gitlab!727

/cc @dblessing @DouweM 

See merge request !3657
parents ab4ea372 61fc9aa8
...@@ -22,6 +22,7 @@ v 8.7.0 (unreleased) ...@@ -22,6 +22,7 @@ v 8.7.0 (unreleased)
- Fix avatar stretching by providing a cropping feature - Fix avatar stretching by providing a cropping feature
- API: Expose `subscribed` for issues and merge requests (Robert Schilling) - API: Expose `subscribed` for issues and merge requests (Robert Schilling)
- Allow SAML to handle external users based on user's information !3530 - Allow SAML to handle external users based on user's information !3530
- Allow Omniauth providers to be marked as `external` !3657
- Add endpoints to archive or unarchive a project !3372 - Add endpoints to archive or unarchive a project !3372
- Add links to CI setup documentation from project settings and builds pages - Add links to CI setup documentation from project settings and builds pages
- Handle nil descriptions in Slack issue messages (Stan Hu) - Handle nil descriptions in Slack issue messages (Stan Hu)
......
...@@ -316,6 +316,13 @@ production: &base ...@@ -316,6 +316,13 @@ production: &base
# (default: false) # (default: false)
auto_link_saml_user: false auto_link_saml_user: false
# Set different Omniauth providers as external so that all users creating accounts
# via these providers will not be able to have access to internal projects. You
# will need to use the full name of the provider, like `google_oauth2` for Google.
# Refer to the examples below for the full names of the supported providers.
# (default: [])
external_providers: []
## Auth providers ## Auth providers
# Uncomment the following lines and fill in the data of the auth provider you want to use # Uncomment the following lines and fill in the data of the auth provider you want to use
# If your favorite auth provider is not listed you can use others: # If your favorite auth provider is not listed you can use others:
......
...@@ -129,6 +129,7 @@ Settings['omniauth'] ||= Settingslogic.new({}) ...@@ -129,6 +129,7 @@ Settings['omniauth'] ||= Settingslogic.new({})
Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil? Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil?
Settings.omniauth['auto_sign_in_with_provider'] = false if Settings.omniauth['auto_sign_in_with_provider'].nil? Settings.omniauth['auto_sign_in_with_provider'] = false if Settings.omniauth['auto_sign_in_with_provider'].nil?
Settings.omniauth['allow_single_sign_on'] = false if Settings.omniauth['allow_single_sign_on'].nil? Settings.omniauth['allow_single_sign_on'] = false if Settings.omniauth['allow_single_sign_on'].nil?
Settings.omniauth['external_providers'] = [] if Settings.omniauth['external_providers'].nil?
Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block_auto_created_users'].nil? Settings.omniauth['block_auto_created_users'] = true if Settings.omniauth['block_auto_created_users'].nil?
Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil? Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil?
Settings.omniauth['auto_link_saml_user'] = false if Settings.omniauth['auto_link_saml_user'].nil? Settings.omniauth['auto_link_saml_user'] = false if Settings.omniauth['auto_link_saml_user'].nil?
......
...@@ -120,6 +120,29 @@ OmniAuth provider for an existing user. ...@@ -120,6 +120,29 @@ OmniAuth provider for an existing user.
The chosen OmniAuth provider is now active and can be used to sign in to GitLab from then on. The chosen OmniAuth provider is now active and can be used to sign in to GitLab from then on.
## Configure OmniAuth Providers as External
>**Note:**
This setting was introduced with version 8.7 of GitLab
You can define which OmniAuth providers you want to be `external` so that all users
creating accounts via these providers will not be able to have access to internal
projects. You will need to use the full name of the provider, like `google_oauth2`
for Google. Refer to the examples for the full names of the supported providers.
**For Omnibus installations**
```ruby
gitlab_rails['omniauth_external_providers'] = ['twitter', 'google_oauth2']
```
**For installations from source**
```yaml
omniauth:
external_providers: ['twitter', 'google_oauth2']
```
## Using Custom Omniauth Providers ## Using Custom Omniauth Providers
>**Note:** >**Note:**
......
...@@ -54,6 +54,12 @@ module Gitlab ...@@ -54,6 +54,12 @@ module Gitlab
@user ||= build_new_user @user ||= build_new_user
end end
if external_provider? && @user
@user.external = true
elsif @user
@user.external = false
end
@user @user
end end
...@@ -113,6 +119,10 @@ module Gitlab ...@@ -113,6 +119,10 @@ module Gitlab
end end
end end
def external_provider?
Gitlab.config.omniauth.external_providers.include?(auth_hash.provider)
end
def block_after_signup? def block_after_signup?
if creating_linked_ldap_user? if creating_linked_ldap_user?
ldap_config.block_auto_created_users ldap_config.block_auto_created_users
......
...@@ -15,20 +15,20 @@ describe Gitlab::OAuth::User, lib: true do ...@@ -15,20 +15,20 @@ describe Gitlab::OAuth::User, lib: true do
end end
let(:ldap_user) { Gitlab::LDAP::Person.new(Net::LDAP::Entry.new, 'ldapmain') } let(:ldap_user) { Gitlab::LDAP::Person.new(Net::LDAP::Entry.new, 'ldapmain') }
describe :persisted? do describe '#persisted?' do
let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') } let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') }
it "finds an existing user based on uid and provider (facebook)" do it "finds an existing user based on uid and provider (facebook)" do
expect( oauth_user.persisted? ).to be_truthy expect( oauth_user.persisted? ).to be_truthy
end end
it "returns false if use is not found in database" do it 'returns false if user is not found in database' do
allow(auth_hash).to receive(:uid).and_return('non-existing') allow(auth_hash).to receive(:uid).and_return('non-existing')
expect( oauth_user.persisted? ).to be_falsey expect( oauth_user.persisted? ).to be_falsey
end end
end end
describe :save do describe '#save' do
def stub_omniauth_config(messages) def stub_omniauth_config(messages)
allow(Gitlab.config.omniauth).to receive_messages(messages) allow(Gitlab.config.omniauth).to receive_messages(messages)
end end
...@@ -40,8 +40,27 @@ describe Gitlab::OAuth::User, lib: true do ...@@ -40,8 +40,27 @@ describe Gitlab::OAuth::User, lib: true do
let(:provider) { 'twitter' } let(:provider) { 'twitter' }
describe 'signup' do describe 'signup' do
shared_examples "to verify compliance with allow_single_sign_on" do shared_examples 'to verify compliance with allow_single_sign_on' do
context "with new allow_single_sign_on enabled syntax" do context 'provider is marked as external' do
it 'should mark user as external' do
stub_omniauth_config(allow_single_sign_on: ['twitter'], external_providers: ['twitter'])
oauth_user.save
expect(gl_user).to be_valid
expect(gl_user.external).to be_truthy
end
end
context 'provider was external, now has been removed' do
it 'should mark existing user internal' do
create(:omniauth_user, extern_uid: 'my-uid', provider: 'twitter', external: true)
stub_omniauth_config(allow_single_sign_on: ['twitter'], external_providers: ['facebook'])
oauth_user.save
expect(gl_user).to be_valid
expect(gl_user.external).to be_falsey
end
end
context 'with new allow_single_sign_on enabled syntax' do
before { stub_omniauth_config(allow_single_sign_on: ['twitter']) } before { stub_omniauth_config(allow_single_sign_on: ['twitter']) }
it "creates a user from Omniauth" do it "creates a user from Omniauth" do
...@@ -67,16 +86,16 @@ describe Gitlab::OAuth::User, lib: true do ...@@ -67,16 +86,16 @@ describe Gitlab::OAuth::User, lib: true do
end end
end end
context "with new allow_single_sign_on disabled syntax" do context 'with new allow_single_sign_on disabled syntax' do
before { stub_omniauth_config(allow_single_sign_on: []) } before { stub_omniauth_config(allow_single_sign_on: []) }
it "throws an error" do it 'throws an error' do
expect{ oauth_user.save }.to raise_error StandardError expect{ oauth_user.save }.to raise_error StandardError
end end
end end
context "with old allow_single_sign_on disabled (Default)" do context 'with old allow_single_sign_on disabled (Default)' do
before { stub_omniauth_config(allow_single_sign_on: false) } before { stub_omniauth_config(allow_single_sign_on: false) }
it "throws an error" do it 'throws an error' do
expect{ oauth_user.save }.to raise_error StandardError expect{ oauth_user.save }.to raise_error StandardError
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment