summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2013-09-02 23:35:40 +0300
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2013-09-02 23:35:40 +0300
commit6bf117c601eda2ae3045644ab778d167955cd0c3 (patch)
tree9a11fa1cc2557e4b7dcf5eb303c2ad91ab26998c
parent1f3f874142775ba6d074460a570c69e1fb02e096 (diff)
downloadgitlab-ce-6bf117c601eda2ae3045644ab778d167955cd0c3.tar.gz
Mode User+LDAP functionality from Gitlab::Auth
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb12
-rw-r--r--app/models/user.rb1
-rw-r--r--lib/gitlab/auth.rb17
-rw-r--r--lib/gitlab/ldap/user.rb92
4 files changed, 99 insertions, 23 deletions
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index c4ebf0e4889..b0765672dda 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -16,12 +16,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def ldap
- # We only find ourselves here if the authentication to LDAP was successful.
- @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user)
- if @user.persisted?
- @user.remember_me = true
- end
- sign_in_and_redirect @user
+ # We only find ourselves here
+ # if the authentication to LDAP was successful.
+ @user = Gitlab::LDAP::User.find_or_create(request.env["omniauth.auth"])
+ @user.remember_me = true if @user.persisted?
+
+ sign_in_and_redirect(@user)
end
private
diff --git a/app/models/user.rb b/app/models/user.rb
index b44c063c32f..823e7a24a25 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -159,6 +159,7 @@ class User < ActiveRecord::Base
scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : scoped }
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') }
+ scope :ldap, -> { where(provider: 'ldap') }
scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active }
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index de70c5ce780..5f4b6c22c2c 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -13,23 +13,6 @@ module Gitlab
end
end
- def find_for_ldap_auth(auth, signed_in_resource = nil)
- uid = auth.info.uid
- provider = auth.provider
- email = auth.info.email.downcase unless auth.info.email.nil?
- raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
-
- if @user = User.find_by_extern_uid_and_provider(uid, provider)
- @user
- elsif @user = User.find_by_email(email)
- log.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
- @user.update_attributes(extern_uid: uid, provider: provider)
- @user
- else
- create_from_omniauth(auth, true)
- end
- end
-
def create_from_omniauth(auth, ldap = false)
provider = auth.provider
uid = auth.info.uid || auth.uid
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
new file mode 100644
index 00000000000..a7a11e5a640
--- /dev/null
+++ b/lib/gitlab/ldap/user.rb
@@ -0,0 +1,92 @@
+# LDAP extension for User model
+#
+# * Find or create user from omniauth.auth data
+# * Links LDAP account with existing user
+#
+module Gitlab
+ module LDAP
+ class User
+ class << self
+ def find(uid, email)
+ # Look for user with ldap provider and same uid
+ user = model.ldap.where(extern_uid: uid).last
+ return user if user
+
+ # Look for user with same emails
+ #
+ # Possible cases:
+ # * When user already has account and need to link his LDAP account.
+ # * LDAP uid changed for user with same email and we need to update his uid
+ #
+ user = model.find_by_email(email)
+
+ if user
+ user.update_attributes(extern_uid: uid, provider: 'ldap')
+ log.info("(LDAP) Updating legacy LDAP user #{email} with extern_uid => #{uid}")
+ end
+
+ user
+ end
+
+ def create(uid, email, name)
+ password = Devise.friendly_token[0, 8].downcase
+ username = email.match(/^[^@]*/)[0]
+
+ opts = {
+ extern_uid: uid,
+ provider: 'ldap',
+ name: name,
+ username: username,
+ email: email,
+ password: password,
+ password_confirmation: password,
+ }
+
+ user = model.new(opts, as: :admin).with_defaults
+ user.save!
+ log.info "(LDAP) Creating user #{email} from login with extern_uid => #{uid}"
+
+ user
+ end
+
+ def find_or_create(auth)
+ uid, email, name = uid(auth), email(auth), name(auth)
+
+ if uid.blank? || email.blank?
+ raise_error("Account must provide an uid and email address")
+ end
+
+ user = find(uid, email)
+ user = create(uid, email, name) unless user
+ user
+ end
+
+ private
+
+ def uid(auth)
+ auth.info.uid
+ end
+
+ def email(auth)
+ auth.info.email.downcase unless auth.info.email.nil?
+ end
+
+ def name(auth)
+ auth.info.name.to_s.force_encoding("utf-8")
+ end
+
+ def log
+ Gitlab::AppLogger
+ end
+
+ def raise_error(message)
+ raise OmniAuth::Error, "(LDAP) " + message
+ end
+
+ def model
+ ::User
+ end
+ end
+ end
+ end
+end