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 'mysql2'
|
||||||
#gem 'sqlite3'
|
#gem 'sqlite3'
|
||||||
|
|
||||||
|
gem 'net-ldap'
|
||||||
|
|
||||||
# Use unicorn as the web server
|
# Use unicorn as the web server
|
||||||
# gem 'unicorn'
|
# gem 'unicorn'
|
||||||
|
|
||||||
|
|
|
@ -43,15 +43,17 @@ class User < ApplicationModel
|
||||||
return if !password || password == ''
|
return if !password || password == ''
|
||||||
|
|
||||||
# try to find user based on login
|
# 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
|
# try second lookup with email
|
||||||
if !user
|
if !user
|
||||||
user = User.where( :email => username, :active => true ).first
|
user = User.where( :email => username.downcase, :active => true ).first
|
||||||
end
|
end
|
||||||
|
|
||||||
# no user found
|
# check failed logins
|
||||||
return nil if !user
|
if user
|
||||||
|
# return if user.faild_login > 10
|
||||||
|
end
|
||||||
|
|
||||||
# use auth backends
|
# use auth backends
|
||||||
config = {
|
config = {
|
||||||
|
@ -65,12 +67,22 @@ class User < ApplicationModel
|
||||||
:adapter => 'env',
|
:adapter => 'env',
|
||||||
},
|
},
|
||||||
:ldap => {
|
:ldap => {
|
||||||
:adapter => 'ldap',
|
:adapter => 'ldap',
|
||||||
:host => 'somehost',
|
:host => 'localhost',
|
||||||
:port => '3333',
|
:port => 389,
|
||||||
:base_dn => 'some base dn',
|
:bind_dn => 'cn=Manager,dc=example,dc=org',
|
||||||
:bind_user => 'some bind user',
|
:bind_pw => 'example',
|
||||||
:bind_pw => 'some pw',
|
: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 => {
|
:otrs => {
|
||||||
:adapter => 'otrs',
|
:adapter => 'otrs',
|
||||||
|
@ -87,15 +99,33 @@ class User < ApplicationModel
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# try to login against configure auth backends
|
||||||
|
user_auth = nil
|
||||||
config.each {|key, c|
|
config.each {|key, c|
|
||||||
file = "auth/#{c[:adapter]}"
|
file = "auth/#{c[:adapter]}"
|
||||||
require file
|
require file
|
||||||
user_auth = Auth.const_get("#{c[:adapter].to_s.upcase}").check( user, username, password, c )
|
user_auth = Auth.const_get("#{c[:adapter].to_s.upcase}").check( username, password, c, user )
|
||||||
return user_auth if user_auth
|
|
||||||
|
# auth ok
|
||||||
|
if user_auth
|
||||||
|
|
||||||
|
# update last login
|
||||||
|
|
||||||
|
|
||||||
|
# reset login failed
|
||||||
|
|
||||||
|
|
||||||
|
return user_auth
|
||||||
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# set login failed +1
|
||||||
|
|
||||||
|
|
||||||
# auth failed
|
# auth failed
|
||||||
return false
|
sleep 1
|
||||||
|
return user_auth
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.create_from_hash!(hash)
|
def self.create_from_hash!(hash)
|
||||||
|
@ -113,7 +143,8 @@ class User < ApplicationModel
|
||||||
:note => hash['info']['description'],
|
:note => hash['info']['description'],
|
||||||
:source => hash['provider'],
|
:source => hash['provider'],
|
||||||
:roles => roles,
|
:roles => roles,
|
||||||
:created_by_id => 1
|
:updated_by_id => 1,
|
||||||
|
:created_by_id => 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -122,11 +153,11 @@ class User < ApplicationModel
|
||||||
return if !username || username == ''
|
return if !username || username == ''
|
||||||
|
|
||||||
# try to find user based on login
|
# 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
|
# try second lookup with email
|
||||||
if !user
|
if !user
|
||||||
user = User.where( :email => username, :active => true ).first
|
user = User.where( :email => username.downcase, :active => true ).first
|
||||||
end
|
end
|
||||||
|
|
||||||
# check if email address exists
|
# check if email address exists
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module Auth
|
module Auth
|
||||||
end
|
end
|
||||||
module Auth::ENV
|
module Auth::ENV
|
||||||
def self.check( user, username, password, config )
|
def self.check( username, password, config, user )
|
||||||
|
|
||||||
# try to find user based on login
|
# try to find user based on login
|
||||||
if ENV['REMOTE_USER']
|
if ENV['REMOTE_USER']
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
module Auth
|
module Auth
|
||||||
end
|
end
|
||||||
module Auth::INTERNAL
|
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
|
# sha auth check
|
||||||
if user.password =~ /^\{sha2\}/
|
if user.password =~ /^\{sha2\}/
|
||||||
crypted = Digest::SHA2.hexdigest( password )
|
crypted = Digest::SHA2.hexdigest( password )
|
||||||
|
|
122
lib/auth/ldap.rb
122
lib/auth/ldap.rb
|
@ -1,15 +1,119 @@
|
||||||
|
require 'net/ldap'
|
||||||
|
|
||||||
module Auth
|
module Auth
|
||||||
end
|
end
|
||||||
module Auth::LDAP
|
module Auth::LDAP
|
||||||
def self.check( user, username, password, config )
|
def self.check( username, password, config, user )
|
||||||
|
|
||||||
# ldap connect
|
|
||||||
|
|
||||||
# ldap bind
|
|
||||||
|
|
||||||
# sync roles / groups
|
|
||||||
# return user
|
|
||||||
|
|
||||||
return false
|
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
|
||||||
|
|
||||||
|
# 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
|
||||||
end
|
end
|
|
@ -1,7 +1,7 @@
|
||||||
module Auth
|
module Auth
|
||||||
end
|
end
|
||||||
module Auth::OTRS
|
module Auth::OTRS
|
||||||
def self.check( user, username, password, config )
|
def self.check( username, password, config, user )
|
||||||
|
|
||||||
endpoint = Setting.get('import_otrs_endpoint')
|
endpoint = Setting.get('import_otrs_endpoint')
|
||||||
return false if !endpoint || endpoint.empty?
|
return false if !endpoint || endpoint.empty?
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module Auth
|
module Auth
|
||||||
end
|
end
|
||||||
module Auth::TEST
|
module Auth::TEST
|
||||||
def self.check( user, username, password, config )
|
def self.check( username, password, config, user )
|
||||||
|
|
||||||
# development systems
|
# development systems
|
||||||
if !ENV['RAILS_ENV'] || ENV['RAILS_ENV'] == 'development'
|
if !ENV['RAILS_ENV'] || ENV['RAILS_ENV'] == 'development'
|
||||||
|
|
Loading…
Reference in a new issue