Last active
September 17, 2015 18:40
-
-
Save u1735067/9a1e584b6fc1fc1bca23 to your computer and use it in GitHub Desktop.
LDAP import & enforce script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://www.redmine.org/issues/1838 | |
# https://www.redmine.org/boards/2/topics/34545 | |
require File.expand_path('../../config/environment', __FILE__) | |
class AuthSourceLdap | |
def get_logins_filter(filter) | |
list = Set.new() | |
ldap_con = initialize_ldap_con(self.account, self.account_password) | |
search_filter = filter | |
ldap_con.search( | |
:base => self.base_dn, | |
:filter => search_filter, | |
:attributes => ['dn', self.attr_login] | |
) do | entry | | |
logger.debug("Found entry with DN: #{entry.dn}") if logger | |
login = AuthSourceLdap.get_attr(entry, self.attr_login).downcase | |
list << login | |
end | |
return list | |
end | |
def get_entry(login) | |
ldap_con = initialize_ldap_con(self.account, self.account_password) | |
search_filter = Net::LDAP::Filter.eq(self.attr_login, login) | |
return ldap_con.search( | |
:base => self.base_dn, | |
:filter => search_filter, | |
:attributes => ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail, self.attr_login] | |
)[0] | |
end | |
# admin status : enforced si exists | |
# auth_source_id = enforced si exists et != -1 | |
def import_logins(logins, admin = false, auth_source_id = nil) | |
found = created = enforced = 0 | |
skipped = [] | |
ldap_con = initialize_ldap_con(self.account, self.account_password) | |
logins.each do | login | | |
# Already exists | |
if u = User.find_by(login: login) | |
# Update email if changed | |
#if u.mail != attrs[0][:mail] | |
# u.mail = attrs[0][:mail] | |
# if u.save | |
# logger.debug("Email for user #{login} was updated") if logger | |
# end | |
#end | |
enforce = false | |
if auth_source_id != -1 && u.auth_source_id != auth_source_id | |
logger.debug("User #{login} already there but bad auth_source_id, enforcing.") if logger | |
u.auth_source_id = auth_source_id | |
enforce = true | |
end | |
if u.admin != admin | |
logger.debug("User #{login} already there but bad admin status, enforcing.") if logger | |
u.admin = admin | |
enforce = true | |
end | |
if enforce | |
u.save | |
enforced += 1 | |
else | |
logger.debug("User #{login} already there, skipping...") if logger | |
skipped.push(login+'(exists)') | |
end | |
next | |
end | |
# Otherwise find him ! | |
filter = Net::LDAP::Filter.eq(self.attr_login, login) | |
res = ldap_con.search( | |
:base => self.base_dn, | |
:filter => filter, | |
:attributes => ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail, self.attr_login] | |
) | |
# Found, check, register | |
if !res.empty? && res[0] != nil | |
entry = res[0] | |
logger.debug("Importing entry with DN: #{entry.dn}") if logger | |
found += 1 | |
skip = false | |
attrs = [:firstname => (AuthSourceLdap.get_attr(entry, self.attr_firstname) != nil ? \ | |
AuthSourceLdap.get_attr(entry, self.attr_firstname) : "Unknown"), | |
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname), | |
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail), | |
:auth_source_id => (!auth_source_id.nil?) ? auth_source_id : self.id] | |
#sanity checking (all the above attributes are required) | |
login = AuthSourceLdap.get_attr(entry, self.attr_login).downcase | |
catch :SKIP do | |
skip = false | |
attrs.each { |e| | |
e.each { |k, v| | |
if v == nil | |
# give the admin a clue why importing failed... | |
logger.debug("User #{login} misses value for attribute '#{k}'.") if logger | |
skipped.push(login+"(missing attribute '#{k}')") | |
skip = true | |
throw :SKIP | |
end | |
} | |
} | |
end | |
next if skip | |
#create user | |
begin | |
logger.debug("Trying to create user with attrs: %s" % attrs.to_s) if logger | |
u = User.create(*attrs) | |
u.login = login | |
u.language = Setting.default_language | |
u.admin = admin | |
if u.save | |
created += 1 | |
else | |
skipped.push(login+'(add failed)') | |
end | |
end | |
end # found & register | |
end # logins | |
logger.info("Found #{found} users out of #{logins.length}, imported #{created}, enforced #{enforced}.") if logger | |
logger.info("Skipped users (#{skipped.length}): #{skipped.join(" ")}") if logger | |
return {:found => found, :imported => created, :skipped => skipped} | |
end | |
# Corrigé, non touché | |
def import | |
ldap_con = initialize_ldap_con(self.account, self.account_password) | |
search_filter = Net::LDAP::Filter.eq("objectClass", "user") | |
found = created = 0 | |
skipped = [] | |
ldap_con.search( | |
:base => self.base_dn, | |
:filter => search_filter, | |
:attributes => ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail, self.attr_login] | |
) do | entry | | |
logger.debug("Found entry with DN: #{entry.dn}") if logger | |
found += 1 | |
skip = false | |
attrs = [:firstname => (AuthSourceLdap.get_attr(entry, self.attr_firstname) != nil ? \ | |
AuthSourceLdap.get_attr(entry, self.attr_firstname) : "Unknown"), | |
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname), | |
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail), | |
:auth_source_id => self.id ] | |
#sanity checking (all the above attributes are required) | |
login = AuthSourceLdap.get_attr(entry, self.attr_login).downcase | |
catch :SKIP do | |
skip = false | |
attrs.each { |e| | |
e.each { |k, v| | |
if v == nil | |
# give the admin a clue why importing failed... | |
logger.debug("User #{login} misses value for attribute '#{k}'.") if logger | |
skipped.push(login+"(missing attribute '#{k}')") | |
skip = true | |
throw :SKIP | |
end | |
} | |
} | |
end | |
next if skip | |
if u = User.find_by(login: login) | |
# Update email if changed | |
if u.mail != attrs[0][:mail] | |
u.mail = attrs[0][:mail] | |
if u.save | |
logger.debug("Email for user #{login} was updated") if logger | |
end | |
end | |
logger.debug("User #{login} already there, skipping...") if logger | |
skipped.push(login+'(exists)') | |
next | |
end | |
#create user | |
begin | |
logger.debug("Trying to create user with attrs: %s" % attrs.to_s) if logger | |
u = User.create(*attrs) | |
u.login = login | |
u.language = Setting.default_language | |
if u.save | |
created += 1 | |
else | |
skipped.push(login+'(add failed)') | |
end | |
end | |
end | |
logger.info("Found #{found} users, imported #{created}.") if logger | |
logger.info("Skipped users: #{skipped.join(" ")}") if logger | |
return {:found => found, :imported => created, :skipped => skipped} | |
end | |
# Créé, non utilisé | |
def lock_non_existing_logins(logins) | |
ldap_con = initialize_ldap_con(self.account, self.account_password) | |
found = 0 | |
logger.debug("Locking users that do not exist in LDAP authentication source: #{self.name}.") if logger | |
@users = User.all | |
@users.each { |user| | |
# ignore anonymous (empty login name and instance of AnonymousUser) and admin users | |
if user.login.empty? || user.class == AnonymousUser || user.login == "admin" | |
next | |
end | |
# Is not in the passed/admin list | |
if !logins.include?(user.login) | |
logger.debug("The user with login name: #{user.login} does not exist as admin any more in the LDAP and will be locked") if logger | |
found += 1 | |
user.status=User::STATUS_LOCKED | |
user.save | |
end | |
} | |
logger.info("Locked #{found} users that did not exist as admin in LDAP authentication source: #{self.name}.") if logger | |
end | |
# Non touché | |
def lock_non_existing | |
ldap_con = initialize_ldap_con(self.account, self.account_password) | |
found = 0 | |
logger.debug("Locking users that do not exist in LDAP authentication source: #{self.name}.") if logger | |
@users = User.all | |
@users.each { |user| | |
search_filter = Net::LDAP::Filter.eq(self.attr_login, user.login) | |
entry = ldap_con.search( | |
:base => self.base_dn, | |
:filter => search_filter, | |
:attributes => ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail, self.attr_login] | |
) | |
# ignore anonymous (empty login name and instance of AnonymousUser) and admin users | |
if entry.empty? && !user.login.empty? && user.class != AnonymousUser && user.login != "admin" | |
logger.debug("The user with login name: #{user.login} does not exist any more in LDAP and will be locked") if logger | |
found += 1 | |
user.status=User::STATUS_LOCKED | |
user.save | |
end | |
} | |
logger.info("Locked #{found} users that did not exist in LDAP authentication source: #{self.name}.") if logger | |
end | |
# auth_source_id = nil to remove source | |
def self.unprivilege_non_logins(logins, auth_source_id = -1) | |
found = 0 | |
logger.debug("Removing admin privilege to users not provided in logins list.") if logger | |
@users = User.all | |
@users.each { |user| | |
# ignore anonymous (empty login name and instance of AnonymousUser) and admin users | |
if user.login.empty? || user.class == AnonymousUser || user.login == "admin" | |
next | |
end | |
# Has a login & is not in the admin list | |
if user.admin && !logins.include?(user.login) | |
logger.debug("The user with login name: #{user.login} is not in the privileged users any more and will be unprivileged") if logger | |
found += 1 | |
user.admin = false | |
if auth_source_id != -1 | |
logger.debug("Changing auth_source_id") if logger | |
user.auth_source_id = auth_source_id | |
end | |
user.save | |
end | |
} | |
logger.info("Removed privileges to #{found} users that did not exist in the provided list.") if logger | |
end | |
end | |
ActiveRecord::Base.logger.info("----Starting LDAP Import&Enforce script") if ActiveRecord::Base.logger | |
#@auth_method = AuthSourceLdap.find(1) # Source contenant les uid / logins | |
#AuthSourceLdap.where("name like '%User'") | |
@source_admin = AuthSourceLdap.find_by(name: 'ResEl - Admin') | |
logins = @source_admin.get_logins_filter(Net::LDAP::Filter.eq("droit", "reseladmin")) | |
@source_users = AuthSourceLdap.find_by(name: 'ResEl - User') | |
@source_users.import_logins(logins, true, @source_admin.id) | |
AuthSourceLdap.unprivilege_non_logins(logins, @source_users.id) | |
ActiveRecord::Base.logger.info("----Done LDAP Import&Enforce script") if ActiveRecord::Base.logger |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment