Commit 6bf117c601eda2ae3045644ab778d167955cd0c3

Authored by Dmitriy Zaporozhets
1 parent 1f3f8741

Mode User+LDAP functionality from Gitlab::Auth

app/controllers/omniauth_callbacks_controller.rb
... ... @@ -16,12 +16,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
16 16 end
17 17  
18 18 def ldap
19   - # We only find ourselves here if the authentication to LDAP was successful.
20   - @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user)
21   - if @user.persisted?
22   - @user.remember_me = true
23   - end
24   - sign_in_and_redirect @user
  19 + # We only find ourselves here
  20 + # if the authentication to LDAP was successful.
  21 + @user = Gitlab::LDAP::User.find_or_create(request.env["omniauth.auth"])
  22 + @user.remember_me = true if @user.persisted?
  23 +
  24 + sign_in_and_redirect(@user)
25 25 end
26 26  
27 27 private
... ...
app/models/user.rb
... ... @@ -159,6 +159,7 @@ class User < ActiveRecord::Base
159 159 scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
160 160 scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : scoped }
161 161 scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') }
  162 + scope :ldap, -> { where(provider: 'ldap') }
162 163  
163 164 scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active }
164 165  
... ...
lib/gitlab/auth.rb
... ... @@ -13,23 +13,6 @@ module Gitlab
13 13 end
14 14 end
15 15  
16   - def find_for_ldap_auth(auth, signed_in_resource = nil)
17   - uid = auth.info.uid
18   - provider = auth.provider
19   - email = auth.info.email.downcase unless auth.info.email.nil?
20   - raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
21   -
22   - if @user = User.find_by_extern_uid_and_provider(uid, provider)
23   - @user
24   - elsif @user = User.find_by_email(email)
25   - log.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
26   - @user.update_attributes(extern_uid: uid, provider: provider)
27   - @user
28   - else
29   - create_from_omniauth(auth, true)
30   - end
31   - end
32   -
33 16 def create_from_omniauth(auth, ldap = false)
34 17 provider = auth.provider
35 18 uid = auth.info.uid || auth.uid
... ...
lib/gitlab/ldap/user.rb 0 → 100644
... ... @@ -0,0 +1,92 @@
  1 +# LDAP extension for User model
  2 +#
  3 +# * Find or create user from omniauth.auth data
  4 +# * Links LDAP account with existing user
  5 +#
  6 +module Gitlab
  7 + module LDAP
  8 + class User
  9 + class << self
  10 + def find(uid, email)
  11 + # Look for user with ldap provider and same uid
  12 + user = model.ldap.where(extern_uid: uid).last
  13 + return user if user
  14 +
  15 + # Look for user with same emails
  16 + #
  17 + # Possible cases:
  18 + # * When user already has account and need to link his LDAP account.
  19 + # * LDAP uid changed for user with same email and we need to update his uid
  20 + #
  21 + user = model.find_by_email(email)
  22 +
  23 + if user
  24 + user.update_attributes(extern_uid: uid, provider: 'ldap')
  25 + log.info("(LDAP) Updating legacy LDAP user #{email} with extern_uid => #{uid}")
  26 + end
  27 +
  28 + user
  29 + end
  30 +
  31 + def create(uid, email, name)
  32 + password = Devise.friendly_token[0, 8].downcase
  33 + username = email.match(/^[^@]*/)[0]
  34 +
  35 + opts = {
  36 + extern_uid: uid,
  37 + provider: 'ldap',
  38 + name: name,
  39 + username: username,
  40 + email: email,
  41 + password: password,
  42 + password_confirmation: password,
  43 + }
  44 +
  45 + user = model.new(opts, as: :admin).with_defaults
  46 + user.save!
  47 + log.info "(LDAP) Creating user #{email} from login with extern_uid => #{uid}"
  48 +
  49 + user
  50 + end
  51 +
  52 + def find_or_create(auth)
  53 + uid, email, name = uid(auth), email(auth), name(auth)
  54 +
  55 + if uid.blank? || email.blank?
  56 + raise_error("Account must provide an uid and email address")
  57 + end
  58 +
  59 + user = find(uid, email)
  60 + user = create(uid, email, name) unless user
  61 + user
  62 + end
  63 +
  64 + private
  65 +
  66 + def uid(auth)
  67 + auth.info.uid
  68 + end
  69 +
  70 + def email(auth)
  71 + auth.info.email.downcase unless auth.info.email.nil?
  72 + end
  73 +
  74 + def name(auth)
  75 + auth.info.name.to_s.force_encoding("utf-8")
  76 + end
  77 +
  78 + def log
  79 + Gitlab::AppLogger
  80 + end
  81 +
  82 + def raise_error(message)
  83 + raise OmniAuth::Error, "(LDAP) " + message
  84 + end
  85 +
  86 + def model
  87 + ::User
  88 + end
  89 + end
  90 + end
  91 + end
  92 +end
... ...