Skip to content
Snippets Groups Projects
Commit 7038440e authored by Patricio Cano's avatar Patricio Cano
Browse files

Adjust the SAML control flow to allow LDAP identities to be added to an existing SAML user.

parent 740a6ecb
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -96,7 +96,7 @@ module Gitlab
# Look for a corresponding person with same uid in any of the configured LDAP providers
Gitlab::LDAP::Config.providers.each do |provider|
adapter = Gitlab::LDAP::Adapter.new(provider)
@ldap_person = Gitlab::LDAP::Person.find_by_uid(auth_hash.uid, adapter)
@ldap_person = Gitlab::LDAP::Person.find_by_dn(auth_hash.uid, adapter)
break if @ldap_person
end
@ldap_person
Loading
Loading
Loading
Loading
@@ -12,12 +12,12 @@ module Gitlab
end
 
def gl_user
@user ||= find_by_uid_and_provider
if auto_link_ldap_user?
@user ||= find_or_create_ldap_user
end
 
@user ||= find_by_uid_and_provider
if auto_link_saml_user?
@user ||= find_by_email
end
Loading
Loading
@@ -62,6 +62,30 @@ module Gitlab
!Gitlab::Saml::Config.external_groups.nil?
end
 
def find_or_create_ldap_user
return unless ldap_person
# If a corresponding person exists with same uid in a LDAP server,
# check if the user already has a GitLab account
user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider)
if user
# Case when a LDAP user already exists in Gitlab. Add the SAML identity to existing account.
user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider)
else
# No account found using LDAP in Gitlab yet: check if there is a SAML account with
# the passed uid and provider
user = find_by_uid_and_provider
if user.nil?
# No SAML account found, build a new user.
user = build_new_user
end
# Correct account is present, add the LDAP Identity to the user.
user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn)
end
user
end
def auth_hash=(auth_hash)
@auth_hash = Gitlab::Saml::AuthHash.new(auth_hash)
end
Loading
Loading
Loading
Loading
@@ -145,6 +145,7 @@ describe Gitlab::Saml::User, lib: true do
allow(ldap_user).to receive(:email) { %w(john@mail.com john2@example.com) }
allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' }
allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(ldap_user)
allow(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(ldap_user)
end
 
context 'and no account for the LDAP user' do
Loading
Loading
@@ -177,6 +178,24 @@ describe Gitlab::Saml::User, lib: true do
])
end
end
context 'user has SAML user, and wants to add their LDAP identity' do
it 'adds the LDAP identity to the existing SAML user' do
create(:omniauth_user, email: 'john@mail.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'saml', username: 'john')
local_hash = OmniAuth::AuthHash.new(uid: 'uid=user1,ou=People,dc=example', provider: provider, info: info_hash, extra: { raw_info: OneLogin::RubySaml::Attributes.new({ 'groups' => %w(Developers Freelancers Designers) }) })
local_saml_user = described_class.new(local_hash)
local_saml_user.save
local_gl_user = local_saml_user.gl_user
expect(local_gl_user).to be_valid
expect(local_gl_user.identities.length).to eql 2
identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } }
expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' },
{ provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' }
])
end
end
end
end
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment