Commit 6bf117c601eda2ae3045644ab778d167955cd0c3
1 parent
1f3f8741
Exists in
master
and in
4 other branches
Mode User+LDAP functionality from Gitlab::Auth
Showing
4 changed files
with
99 additions
and
23 deletions
Show diff stats
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 | ... | ... |
... | ... | @@ -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 | ... | ... |