diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2013-09-02 23:35:40 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2013-09-02 23:35:40 +0300 |
commit | 6bf117c601eda2ae3045644ab778d167955cd0c3 (patch) | |
tree | 9a11fa1cc2557e4b7dcf5eb303c2ad91ab26998c | |
parent | 1f3f874142775ba6d074460a570c69e1fb02e096 (diff) | |
download | gitlab-ce-6bf117c601eda2ae3045644ab778d167955cd0c3.tar.gz |
Mode User+LDAP functionality from Gitlab::Auth
-rw-r--r-- | app/controllers/omniauth_callbacks_controller.rb | 12 | ||||
-rw-r--r-- | app/models/user.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/auth.rb | 17 | ||||
-rw-r--r-- | lib/gitlab/ldap/user.rb | 92 |
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 |