mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-10 05:06:46 +10:00
The blocked? method is used to check whether a user exists in LDAP. Prior to this change, if the LDAP server had more objects below the one pointed to by the DN, those objects would also be picked up by the search, causing the method to determine the user should be blocked. One case where this can happen is when using Active Directory and a user have a mobile phone assigned. In this case, Exchange will add an entry called ExchangeActiveSyncDevices under the users entry. The user-visible behaviour is then that a user loses Gitlab access when he enables a mobile device. This fix sets the search scope to BaseObject in order to ensure that only the user itself is returned.
105 lines
3.0 KiB
Ruby
105 lines
3.0 KiB
Ruby
require 'gitlab/oauth/user'
|
|
|
|
# LDAP extension for User model
|
|
#
|
|
# * Find or create user from omniauth.auth data
|
|
# * Links LDAP account with existing user
|
|
# * Auth LDAP user with login and password
|
|
#
|
|
module Gitlab
|
|
module LDAP
|
|
class User < Gitlab::OAuth::User
|
|
class << self
|
|
def find_or_create(auth)
|
|
@auth = auth
|
|
|
|
if uid.blank? || email.blank?
|
|
raise_error("Account must provide an uid and email address")
|
|
end
|
|
|
|
user = find(auth)
|
|
|
|
unless 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 = find_user(email)
|
|
|
|
if user
|
|
user.update_attributes(extern_uid: uid, provider: provider)
|
|
log.info("(LDAP) Updating legacy LDAP user #{email} with extern_uid => #{uid}")
|
|
else
|
|
# Create a new user inside GitLab database
|
|
# based on LDAP credentials
|
|
#
|
|
#
|
|
user = create(auth)
|
|
end
|
|
end
|
|
|
|
user
|
|
end
|
|
|
|
def find_user(email)
|
|
user = model.find_by_email(email)
|
|
|
|
# If no user found and allow_username_or_email_login is true
|
|
# we look for user by extracting part of his email
|
|
if !user && email && ldap_conf['allow_username_or_email_login']
|
|
uname = email.partition('@').first
|
|
user = model.find_by_username(uname)
|
|
end
|
|
|
|
user
|
|
end
|
|
|
|
def authenticate(login, password)
|
|
# Check user against LDAP backend if user is not authenticated
|
|
# Only check with valid login and password to prevent anonymous bind results
|
|
return nil unless ldap_conf.enabled && login.present? && password.present?
|
|
|
|
ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf)
|
|
ldap_user = ldap.bind_as(
|
|
filter: Net::LDAP::Filter.eq(ldap.uid, login),
|
|
size: 1,
|
|
password: password
|
|
)
|
|
|
|
find_by_uid(ldap_user.dn) if ldap_user
|
|
end
|
|
|
|
# Check LDAP user existance by dn. User in git over ssh check
|
|
#
|
|
# It covers 2 cases:
|
|
# * when ldap account was removed
|
|
# * when ldap account was deactivated by change of OU membership in 'dn'
|
|
def blocked?(dn)
|
|
ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf)
|
|
ldap.connection.search(base: dn, scope: Net::LDAP::SearchScope_BaseObject, size: 1).blank?
|
|
end
|
|
|
|
private
|
|
|
|
def find_by_uid(uid)
|
|
model.where(provider: provider, extern_uid: uid).last
|
|
end
|
|
|
|
def provider
|
|
'ldap'
|
|
end
|
|
|
|
def raise_error(message)
|
|
raise OmniAuth::Error, "(LDAP) " + message
|
|
end
|
|
|
|
def ldap_conf
|
|
Gitlab.config.ldap
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|