From dfcea8ed514c7ef1aea78ce15525e617a10bf6bb Mon Sep 17 00:00:00 2001 From: Alex Lossent Date: Tue, 2 Jun 2015 12:01:29 +0200 Subject: Add option to automatically link omniauth and LDAP identities Until now, a user needed to first sign in with his LDAP identity and then manually link his/her account with an omniauth identity from their profile. Only when this is done can the user authenticate with the omniauth provider and at the same time benefit from the LDAP integration (HTTPS authentication with LDAP username/password and in EE: LDAP groups, SSH keys etc.). This feature automates the process by looking up a corresponding LDAP person when a user connects with omniauth for the first time and then automatically linking the LDAP and omniauth identities (of course, like the existing allow_single_sign_on setting, this is meant to be used with trusted omniauth providers). The result is identical to a manual account link. Add config initializers for other omniauth settings. --- lib/gitlab/o_auth/user.rb | 62 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index ba5caed6131..040d0ab34ff 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -46,6 +46,10 @@ module Gitlab def gl_user @user ||= find_by_uid_and_provider + if auto_link_ldap_user? + @user ||= find_or_create_ldap_user + end + if signup_enabled? @user ||= build_new_user end @@ -55,8 +59,52 @@ module Gitlab protected + def find_or_create_ldap_user + return unless ldap_person + #If a corresponding person exists with same uid in a LDAP server, + #set up a Gitlab user with dual LDAP and Omniauth identities. + if user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn.downcase, ldap_person.provider) + #case when a LDAP user already exists in Gitlab. Add the Omniauth identity to existing account. + user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) + else + #no account in Gitlab yet: create it and add the LDAP identity + user = build_new_user + user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn) + end + user + end + + def auto_link_ldap_user? + Gitlab.config.omniauth.auto_link_ldap_user + end + + def creating_linked_ldap_user? + auto_link_ldap_user? && ldap_person + end + + def ldap_person + return @ldap_person if defined?(@ldap_person) + + #looks 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) + break if @ldap_person #exit on first person found + end + @ldap_person #may be nil if we could not find a match + end + + def ldap_config + ldap_person && Gitlab::LDAP::Config.new(ldap_person.provider) + end + def needs_blocking? - new? && block_after_signup? + return false unless new? + if creating_linked_ldap_user? + ldap_config.block_auto_created_users + else + block_after_signup? + end end def signup_enabled? @@ -84,10 +132,16 @@ module Gitlab end def user_attributes - { + # Give preference to LDAP for sensitive information when creating a linked account + username, email = if creating_linked_ldap_user? + [ ldap_person.username, ldap_person.email.first ] + else + [ auth_hash.username, auth_hash.email ] + end + return { name: auth_hash.name, - username: ::Namespace.clean_path(auth_hash.username), - email: auth_hash.email, + username: ::Namespace.clean_path(username), + email: email, password: auth_hash.password, password_confirmation: auth_hash.password, password_automatically_set: true -- cgit v1.2.3 From 45e9150a517970d3782bed642b091ad60a46634f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 5 Jun 2015 12:32:01 +0200 Subject: Tweak code. --- lib/gitlab/o_auth/user.rb | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 040d0ab34ff..c4971b5bcc6 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -61,16 +61,18 @@ module Gitlab def find_or_create_ldap_user return unless ldap_person - #If a corresponding person exists with same uid in a LDAP server, - #set up a Gitlab user with dual LDAP and Omniauth identities. + + # If a corresponding person exists with same uid in a LDAP server, + # set up a Gitlab user with dual LDAP and Omniauth identities. if user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn.downcase, ldap_person.provider) - #case when a LDAP user already exists in Gitlab. Add the Omniauth identity to existing account. + # Case when a LDAP user already exists in Gitlab. Add the Omniauth identity to existing account. user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) else - #no account in Gitlab yet: create it and add the LDAP identity + # No account in Gitlab yet: create it and add the LDAP identity user = build_new_user user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn) end + user end @@ -85,26 +87,20 @@ module Gitlab def ldap_person return @ldap_person if defined?(@ldap_person) - #looks for a corresponding person with same uid in any of the configured LDAP providers - Gitlab::LDAP::Config.providers.each do |provider| + # looks for a corresponding person with same uid in any of the configured LDAP providers + @ldap_person = Gitlab::LDAP::Config.providers.find do |provider| adapter = Gitlab::LDAP::Adapter.new(provider) - @ldap_person = Gitlab::LDAP::Person.find_by_uid(auth_hash.uid, adapter) - break if @ldap_person #exit on first person found + + Gitlab::LDAP::Person.find_by_uid(auth_hash.uid, adapter) end - @ldap_person #may be nil if we could not find a match end def ldap_config - ldap_person && Gitlab::LDAP::Config.new(ldap_person.provider) + Gitlab::LDAP::Config.new(ldap_person.provider) if ldap_person end def needs_blocking? - return false unless new? - if creating_linked_ldap_user? - ldap_config.block_auto_created_users - else - block_after_signup? - end + new? && block_after_signup? end def signup_enabled? @@ -112,7 +108,11 @@ module Gitlab end def block_after_signup? - Gitlab.config.omniauth.block_auto_created_users + if creating_linked_ldap_user? + ldap_config.block_auto_created_users + else + Gitlab.config.omniauth.block_auto_created_users + end end def auth_hash=(auth_hash) @@ -133,12 +133,15 @@ module Gitlab def user_attributes # Give preference to LDAP for sensitive information when creating a linked account - username, email = if creating_linked_ldap_user? - [ ldap_person.username, ldap_person.email.first ] + if creating_linked_ldap_user? + username = ldap_person.username + email = ldap_person.email.first else - [ auth_hash.username, auth_hash.email ] + username = auth_hash.username + email = auth_hash.email end - return { + + { name: auth_hash.name, username: ::Namespace.clean_path(username), email: email, -- cgit v1.2.3