Init version of ldap auth/sync.
This commit is contained in:
parent
579e1dcfb3
commit
409dbe31d1
7 changed files with 170 additions and 30 deletions
2
Gemfile
2
Gemfile
|
@ -46,6 +46,8 @@ gem 'simple-rss'
|
|||
gem 'mysql2'
|
||||
#gem 'sqlite3'
|
||||
|
||||
gem 'net-ldap'
|
||||
|
||||
# Use unicorn as the web server
|
||||
# gem 'unicorn'
|
||||
|
||||
|
|
|
@ -43,15 +43,17 @@ class User < ApplicationModel
|
|||
return if !password || password == ''
|
||||
|
||||
# try to find user based on login
|
||||
user = User.where( :login => username, :active => true ).first
|
||||
user = User.where( :login => username.downcase, :active => true ).first
|
||||
|
||||
# try second lookup with email
|
||||
if !user
|
||||
user = User.where( :email => username, :active => true ).first
|
||||
user = User.where( :email => username.downcase, :active => true ).first
|
||||
end
|
||||
|
||||
# no user found
|
||||
return nil if !user
|
||||
# check failed logins
|
||||
if user
|
||||
# return if user.faild_login > 10
|
||||
end
|
||||
|
||||
# use auth backends
|
||||
config = {
|
||||
|
@ -66,11 +68,21 @@ class User < ApplicationModel
|
|||
},
|
||||
:ldap => {
|
||||
:adapter => 'ldap',
|
||||
:host => 'somehost',
|
||||
:port => '3333',
|
||||
:base_dn => 'some base dn',
|
||||
:bind_user => 'some bind user',
|
||||
:bind_pw => 'some pw',
|
||||
:host => 'localhost',
|
||||
:port => 389,
|
||||
:bind_dn => 'cn=Manager,dc=example,dc=org',
|
||||
:bind_pw => 'example',
|
||||
:uid => 'mail',
|
||||
:base => 'dc=example,dc=org',
|
||||
:always_filter => '',
|
||||
:always_roles => ['Admin', 'Agent'],
|
||||
:always_groups => ['Users'],
|
||||
:sync_params => {
|
||||
:firstname => 'givenName',
|
||||
:lastname => 'sn',
|
||||
:email => 'mail',
|
||||
:login => 'mail',
|
||||
},
|
||||
},
|
||||
:otrs => {
|
||||
:adapter => 'otrs',
|
||||
|
@ -87,15 +99,33 @@ class User < ApplicationModel
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
# try to login against configure auth backends
|
||||
user_auth = nil
|
||||
config.each {|key, c|
|
||||
file = "auth/#{c[:adapter]}"
|
||||
require file
|
||||
user_auth = Auth.const_get("#{c[:adapter].to_s.upcase}").check( user, username, password, c )
|
||||
return user_auth if user_auth
|
||||
user_auth = Auth.const_get("#{c[:adapter].to_s.upcase}").check( username, password, c, user )
|
||||
|
||||
# auth ok
|
||||
if user_auth
|
||||
|
||||
# update last login
|
||||
|
||||
|
||||
# reset login failed
|
||||
|
||||
|
||||
return user_auth
|
||||
end
|
||||
}
|
||||
|
||||
# set login failed +1
|
||||
|
||||
|
||||
# auth failed
|
||||
return false
|
||||
sleep 1
|
||||
return user_auth
|
||||
end
|
||||
|
||||
def self.create_from_hash!(hash)
|
||||
|
@ -113,7 +143,8 @@ class User < ApplicationModel
|
|||
:note => hash['info']['description'],
|
||||
:source => hash['provider'],
|
||||
:roles => roles,
|
||||
:created_by_id => 1
|
||||
:updated_by_id => 1,
|
||||
:created_by_id => 1,
|
||||
)
|
||||
|
||||
end
|
||||
|
@ -122,11 +153,11 @@ class User < ApplicationModel
|
|||
return if !username || username == ''
|
||||
|
||||
# try to find user based on login
|
||||
user = User.where( :login => username, :active => true ).first
|
||||
user = User.where( :login => username.downcase, :active => true ).first
|
||||
|
||||
# try second lookup with email
|
||||
if !user
|
||||
user = User.where( :email => username, :active => true ).first
|
||||
user = User.where( :email => username.downcase, :active => true ).first
|
||||
end
|
||||
|
||||
# check if email address exists
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module Auth
|
||||
end
|
||||
module Auth::ENV
|
||||
def self.check( user, username, password, config )
|
||||
def self.check( username, password, config, user )
|
||||
|
||||
# try to find user based on login
|
||||
if ENV['REMOTE_USER']
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
module Auth
|
||||
end
|
||||
module Auth::INTERNAL
|
||||
def self.check( user, username, password, config )
|
||||
def self.check( username, password, config, user )
|
||||
|
||||
# return if no user exists
|
||||
return nil if !user
|
||||
|
||||
# sha auth check
|
||||
if user.password =~ /^\{sha2\}/
|
||||
|
|
110
lib/auth/ldap.rb
110
lib/auth/ldap.rb
|
@ -1,15 +1,119 @@
|
|||
require 'net/ldap'
|
||||
|
||||
module Auth
|
||||
end
|
||||
module Auth::LDAP
|
||||
def self.check( user, username, password, config )
|
||||
def self.check( username, password, config, user )
|
||||
|
||||
scope = Net::LDAP::SearchScope_WholeSubtree
|
||||
|
||||
# ldap connect
|
||||
ldap = Net::LDAP.new( :host => config[:host], :port => config[:port] )
|
||||
|
||||
# set auth data if needed
|
||||
if config[:bind_dn] && config[:bind_pw]
|
||||
ldap.auth config[:bind_dn], config[:bind_pw]
|
||||
end
|
||||
|
||||
# ldap bind
|
||||
if !ldap.bind
|
||||
puts "NOTICE: Can't connect/bind to '#{host}', #{ldap.get_operation_result.code}, #{ldap.get_operation_result.message}"
|
||||
return
|
||||
end
|
||||
|
||||
# sync roles / groups
|
||||
# return user
|
||||
# search user
|
||||
filter = "(#{config[:uid]}=#{username})"
|
||||
if config[:always_filter]
|
||||
filter = "(&#{filter}#{config[:always_filter]})"
|
||||
end
|
||||
user_dn = nil
|
||||
user_data = {}
|
||||
ldap.search( :base => config[:base], :filter => filter, :scope => scope ) do |entry|
|
||||
user_data = {}
|
||||
user_dn = entry.dn
|
||||
|
||||
# remember attributes for :sync_params
|
||||
entry.each do |attribute, values|
|
||||
user_data[ attribute.to_sym ] = ''
|
||||
values.each do |value|
|
||||
user_data[ attribute.to_sym ] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if user_dn == nil
|
||||
puts "NOTICE: ldap entry found for user '#{username}' with filter #{filter} failed!"
|
||||
return nil
|
||||
end
|
||||
|
||||
# try ldap bind with user credentals
|
||||
auth = ldap.authenticate user_dn, password
|
||||
if !ldap.bind( auth )
|
||||
puts "NOTICE: ldap bind with '#{user_dn}' failed!"
|
||||
return false
|
||||
end
|
||||
|
||||
# create/update user
|
||||
if config[:sync_params]
|
||||
user_attributes = {
|
||||
:source => 'ldap',
|
||||
:updated_by_id => 1,
|
||||
}
|
||||
config[:sync_params].each {| local_data, ldap_data |
|
||||
if user_data[ ldap_data.to_sym ]
|
||||
user_attributes[ local_data.to_sym] = user_data[ ldap_data.to_sym ]
|
||||
end
|
||||
}
|
||||
if !user
|
||||
user_attributes[:created_by_id] = 1
|
||||
user = User.create( user_attributes )
|
||||
puts "NOTICE: user created '#{user.login}'"
|
||||
else
|
||||
user.update_attributes( user_attributes )
|
||||
puts "NOTICE: user updated '#{user.login}'"
|
||||
end
|
||||
end
|
||||
|
||||
# return if it was not possible to create user
|
||||
return if !user
|
||||
|
||||
# sync roles
|
||||
# FIXME
|
||||
|
||||
# sync groups
|
||||
# FIXME
|
||||
|
||||
# set always roles
|
||||
if config[:always_roles]
|
||||
role_ids = user.role_ids
|
||||
config[:always_roles].each {|role_name|
|
||||
role = Role.where( :name => role_name ).first
|
||||
next if !role
|
||||
if !role_ids.include?( role.id )
|
||||
role_ids.push role.id
|
||||
end
|
||||
}
|
||||
user.role_ids = role_ids
|
||||
user.save
|
||||
end
|
||||
|
||||
# set always groups
|
||||
if config[:always_groups]
|
||||
group_ids = user.group_ids
|
||||
config[:always_groups].each {|group_name|
|
||||
group = Group.where( :name => group_name ).first
|
||||
next if !group
|
||||
if !group_ids.include?( group.id )
|
||||
group_ids.push group.id
|
||||
end
|
||||
}
|
||||
user.group_ids = group_ids
|
||||
user.save
|
||||
end
|
||||
|
||||
# take session down
|
||||
# - not needed, done by Net::LDAP -
|
||||
|
||||
return user
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
module Auth
|
||||
end
|
||||
module Auth::OTRS
|
||||
def self.check( user, username, password, config )
|
||||
def self.check( username, password, config, user )
|
||||
|
||||
endpoint = Setting.get('import_otrs_endpoint')
|
||||
return false if !endpoint || endpoint.empty?
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module Auth
|
||||
end
|
||||
module Auth::TEST
|
||||
def self.check( user, username, password, config )
|
||||
def self.check( username, password, config, user )
|
||||
|
||||
# development systems
|
||||
if !ENV['RAILS_ENV'] || ENV['RAILS_ENV'] == 'development'
|
||||
|
|
Loading…
Reference in a new issue