Refactor, fix rubocop lint errors
This commit is contained in:
parent
bcd179756b
commit
b62ff3b37a
2 changed files with 143 additions and 90 deletions
4
.rubocop.yml
Normal file
4
.rubocop.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Metrics/MethodLength:
|
||||||
|
Max: 25
|
||||||
|
Metrics/AbcSize:
|
||||||
|
Enabled: false
|
|
@ -3,120 +3,169 @@
|
||||||
require 'toml'
|
require 'toml'
|
||||||
require 'net/ldap'
|
require 'net/ldap'
|
||||||
|
|
||||||
@configuration_file = "/etc/unipoly-mlmmj-ldap-sync.toml"
|
@configuration_file = '/etc/unipoly-mlmmj-ldap-sync.toml'
|
||||||
|
@configuration = nil
|
||||||
|
|
||||||
def read_configuration(path)
|
def read_configuration(path)
|
||||||
TOML.load_file(path)
|
begin
|
||||||
|
TOML.load_file(path)
|
||||||
|
rescue Errno::ENOENT => raisedError
|
||||||
|
puts "Could not open configuration file: #{raisedError}"
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def connect_ldap(conf)
|
def connect_ldap(conf)
|
||||||
conn = Net::LDAP.new(
|
conn = Net::LDAP.new(
|
||||||
:host => conf["ldap"]["host"],
|
host: conf['ldap']['host'],
|
||||||
:port => conf["ldap"]["port"],
|
port: conf['ldap']['port'],
|
||||||
:auth => {
|
auth: {
|
||||||
:method => :simple,
|
method: :simple,
|
||||||
:username => conf["ldap"]["auth"]["username"],
|
username: @configuration['ldap']['auth']['username'],
|
||||||
:password => conf["ldap"]["auth"]["password"]
|
password: @configuration['ldap']['auth']['password']
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if conn.bind
|
if conn.bind
|
||||||
conn
|
conn
|
||||||
else
|
else
|
||||||
puts "Failed to authenticate against LDAP server: \
|
puts "Failed to authenticate against LDAP server: \
|
||||||
#{conf["ldap"]["host"]}:#{conf["ldap"]["port"]}"
|
#{conf['ldap']['host']}:#{conf['ldap']['port']}"
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
rescue
|
rescue LdapError => raised_error
|
||||||
puts "Failed to contact LDAP server: \
|
puts "Failed to contact LDAP server: \
|
||||||
#{conf["ldap"]["host"]}:#{conf["ldap"]["port"]}"
|
#{conf['ldap']['host']}:#{conf['ldap']['port']}"
|
||||||
exit(1)
|
puts raised_error
|
||||||
|
exit(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_mlmmj_subscribers(list_name)
|
||||||
|
mlmmj_list_binary = @configuration['mlmmj']['list_binary']
|
||||||
|
mlmmj_basepath = @configuration['mlmmj']['basepath']
|
||||||
|
list = "#{mlmmj_basepath}/#{list_name}@#{@configuration['domain']}"
|
||||||
|
|
||||||
|
unless File.executable?(mlmmj_list_binary)
|
||||||
|
puts "could not execute #{mlmmj_list_binary}"
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Execute mlmmj-list and check whether it exited successfuly
|
||||||
|
raw = `#{mlmmj_list_binary} -L #{list} -s`
|
||||||
|
unless $CHILD_STATUS.exitstatus.zero?
|
||||||
|
puts 'FAIL'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return a list of mail addresses.
|
||||||
|
raw.split("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_subscriber_to(list_name, subscribers, list, addr)
|
||||||
|
if subscribers.include?(addr)
|
||||||
|
# The address is already subscribed to the list: we're done with it.
|
||||||
|
subscribers.delete(addr)
|
||||||
|
else
|
||||||
|
# The address is not subscribed to the list yet.
|
||||||
|
print "Adding #{addr}... "
|
||||||
|
|
||||||
|
# Since the configuration file doesn't say we have to add new subscribers
|
||||||
|
# to this list, we ignore this action.
|
||||||
|
unless @configuration['lists_add'].include?(list_name)
|
||||||
|
puts 'IGNORED'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# Subscribe the address to the list.
|
||||||
|
mlmmj_sub_binary = @configuration['mlmmj']['sub_binary']
|
||||||
|
`#{mlmmj_sub_binary} -L #{list} -a #{addr} -q -f -s`
|
||||||
|
if $CHILD_STATUS.exitstatus.zero?
|
||||||
|
puts 'OK'
|
||||||
|
else
|
||||||
|
puts 'FAILED'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_subscriber_from(list_name, list, addr)
|
||||||
|
print "Removing #{addr}... "
|
||||||
|
|
||||||
|
# We ignore this action if the configuration file doesn't say we are allowed
|
||||||
|
# to remove addresses from this list.
|
||||||
|
unless conf['lists_remove'].include?(list_name)
|
||||||
|
puts 'IGNORED'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unsubscribe the address from the list.
|
||||||
|
mlmmj_unsub_binary = conf['mlmmj']['unsub_binary']
|
||||||
|
`#{mlmmj_unsub_binary} -L #{list} -a #{s} -q -s`
|
||||||
|
if $CHILD_STATUS.exitstatus.zero?
|
||||||
|
puts 'OK'
|
||||||
|
else
|
||||||
|
puts 'FAILED'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sync_list(list_name, ldap_group_entry)
|
||||||
|
# Members are formatted as
|
||||||
|
# 'mail=user@domain.tld,ou=Users,dc=unipoly,dc=epfl,dc=ch': we extract the
|
||||||
|
# mail address.
|
||||||
|
ldap_members = ldap_group_entry.uniquemember.map do |dn|
|
||||||
|
/mail=([^,]+),/.match(dn).values_at(1).first.downcase
|
||||||
|
end
|
||||||
|
puts "Found #{entry.dn} with #{members.size} members"
|
||||||
|
|
||||||
|
# Extract mail addresses from Mlmmj
|
||||||
|
print 'Searchin mlmmj... '
|
||||||
|
mlmmj_subscribers = get_mlmmj_subscribers(list_name)
|
||||||
|
puts 'OK'
|
||||||
|
puts "Found #{entry.cn}@#{@configuration['domain']} with #{subscribers.size} \
|
||||||
|
subscribers"
|
||||||
|
print "\n"
|
||||||
|
|
||||||
|
# Add to the subscribers any missing entry
|
||||||
|
# Remove successful matches
|
||||||
|
ldap_members.each do |addr|
|
||||||
|
add_subscriber_to(list_name, subscribers, list, addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Remove remaining "subcribers" (= they did not match with LDAP members)
|
||||||
|
mlmmj_subscribers.each do |addr|
|
||||||
|
remove_subscriber_from(list_name, list, addr)
|
||||||
|
end
|
||||||
|
print "\n"
|
||||||
|
end
|
||||||
|
|
||||||
def main
|
def main
|
||||||
conf = read_configuration(@configuration_file)
|
# Parse configuration, bind to LDAP server
|
||||||
|
@configuration = read_configuration(@configuration_file)
|
||||||
conn = connect_ldap(conf)
|
conn = connect_ldap(conf)
|
||||||
|
|
||||||
domain = conf["domain"]
|
domain = @configuration['domain']
|
||||||
basetree = conf["ldap"]["lists"]["basetree"]
|
basetree = @configuration['ldap']['lists']['basetree']
|
||||||
lists = (conf["lists_add"] + conf["lists_remove"]).uniq
|
lists = (@configuration['lists_add'] + @configuration['lists_remove']).uniq
|
||||||
lists.each do |cn|
|
|
||||||
puts ">> Processing list #{cn}@#{domain}"
|
|
||||||
|
|
||||||
filter = Net::LDAP::Filter.eq("cn", cn)
|
# Sync Mlmmj lists with LDAP groups
|
||||||
|
lists.each do |list_name|
|
||||||
|
puts ">> Processing list #{list_name}@#{domain}"
|
||||||
|
print 'Searching LDAP... '
|
||||||
|
|
||||||
print "Searching LDAP... "
|
filter = Net::LDAP::Filter.eq('cn', list_name)
|
||||||
match = conn.search(:base => basetree, :filter => filter)
|
matched_ldap_groups = conn.search(base: basetree, filter: filter)
|
||||||
if (match.size > 0)
|
if matched_ldap_groups.empty?
|
||||||
entry = match.first
|
# Could not find matching LDAP group
|
||||||
members = entry.uniquemember.map do |dn|
|
puts 'NOT FOUND'
|
||||||
/mail=([^,]+),/.match(dn).values_at(1).first.downcase
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "OK"
|
|
||||||
puts "Found #{entry.dn} with #{members.size} members"
|
|
||||||
|
|
||||||
print "Searchin mlmmj... "
|
|
||||||
mlmmj_list_binary = conf["mlmmj"]["list_binary"]
|
|
||||||
mlmmj_basepath = conf["mlmmj"]["basepath"]
|
|
||||||
list = "#{mlmmj_basepath}/#{cn}@#{domain}"
|
|
||||||
if (File.executable?(mlmmj_list_binary))
|
|
||||||
raw = %x(#{mlmmj_list_binary} -L #{list} -s)
|
|
||||||
|
|
||||||
if ($?.exitstatus == 0)
|
|
||||||
puts "OK"
|
|
||||||
subscribers = raw.split("\n")
|
|
||||||
puts "Found #{cn}@#{domain} with #{subscribers.size} subscribers"
|
|
||||||
print "\n"
|
|
||||||
|
|
||||||
# Add to the subscribers any missing entry
|
|
||||||
# Remove successful matches
|
|
||||||
members.each do |m|
|
|
||||||
if (subscribers.include?(m))
|
|
||||||
subscribers.delete(m)
|
|
||||||
else
|
|
||||||
print "Adding #{m}... "
|
|
||||||
if (conf["lists_add"].include?(cn))
|
|
||||||
mlmmj_sub_binary = conf["mlmmj"]["sub_binary"]
|
|
||||||
%x(#{mlmmj_sub_binary} -L #{list} -a #{m} -q -f -s)
|
|
||||||
if ($?.exitstatus == 0)
|
|
||||||
puts "OK"
|
|
||||||
else
|
|
||||||
puts "FAILED"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
puts "IGNORED"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remove remaining "subcribers" (= they did not match with members)
|
|
||||||
subscribers.each do |s|
|
|
||||||
print "Removing #{s}... "
|
|
||||||
if (conf["lists_remove"].include?(cn))
|
|
||||||
mlmmj_unsub_binary = conf["mlmmj"]["unsub_binary"]
|
|
||||||
%x(#{mlmmj_unsub_binary} -L #{list} -a #{s} -q -s)
|
|
||||||
if ($?.exitstatus == 0)
|
|
||||||
puts "OK"
|
|
||||||
else
|
|
||||||
puts "FAILED"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
puts "IGNORED"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print "\n"
|
|
||||||
else
|
|
||||||
puts "FAIL"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
puts "could not execute #{mlmmj_list_binary}"
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
puts "FAIL"
|
puts 'OK'
|
||||||
|
ldap_group_entry = matched_ldap_groups.first
|
||||||
|
sync_list_with(list_name, ldap_group_entry)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
main()
|
###
|
||||||
|
# Execute script:
|
||||||
|
main
|
||||||
|
|
Loading…
Reference in a new issue