Re-add support for attribute ranges
This is an alternative implementation of #37 . It doesn't need additional configuration, but enables range retrieval automatic. It also add some testing. Fixes #32
This commit is contained in:
parent
f5b9587eb7
commit
81473fb2b4
5
Gemfile
5
Gemfile
@ -2,3 +2,8 @@ source "https://rubygems.org"
|
|||||||
|
|
||||||
# Specify your gem's dependencies in pg_ldap_sync.gemspec
|
# Specify your gem's dependencies in pg_ldap_sync.gemspec
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "debug"
|
||||||
|
gem "ruby-ldapserver", git: "https://github.com/larskanis/ruby-ldapserver/"
|
||||||
|
end
|
||||||
|
@ -85,17 +85,52 @@ class Application
|
|||||||
return users
|
return users
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def retrieve_array_attribute(entry, attribute_name)
|
||||||
|
array = entry[attribute_name]
|
||||||
|
if array.empty?
|
||||||
|
# Possibly an attribute, which must be retrieved in several ranges
|
||||||
|
|
||||||
|
ranged_attr = entry.attribute_names.find { |n| n =~ /\A#{Regexp.escape(attribute_name)};range=/ }
|
||||||
|
if ranged_attr
|
||||||
|
entry_dn = entry.dn
|
||||||
|
|
||||||
|
loop do
|
||||||
|
array += entry[ranged_attr]
|
||||||
|
log.debug "retrieved attribute range #{ranged_attr.inspect} of dn #{entry_dn}"
|
||||||
|
|
||||||
|
if ranged_attr =~ /;range=\d\-\*\z/
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
attribute_with_range = ranged_attr.to_s.gsub(/;range=.*/, ";range=#{array.size}-*")
|
||||||
|
entry = @ldap.search(
|
||||||
|
base: entry_dn,
|
||||||
|
scope: Net::LDAP::SearchScope_BaseObject,
|
||||||
|
attributes: attribute_with_range).first
|
||||||
|
|
||||||
|
ranged_attr = entry.attribute_names.find { |n| n =~ /\A#{Regexp.escape(attribute_name)};range=/ }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# Values already received -> No ranged attribute
|
||||||
|
end
|
||||||
|
return array
|
||||||
|
end
|
||||||
|
|
||||||
def search_ldap_groups
|
def search_ldap_groups
|
||||||
ldap_group_conf = @config[:ldap_groups]
|
ldap_group_conf = @config[:ldap_groups]
|
||||||
|
name_attribute = ldap_group_conf[:name_attribute]
|
||||||
|
member_attribute = ldap_group_conf[:member_attribute]
|
||||||
|
|
||||||
groups = []
|
groups = []
|
||||||
res = @ldap.search(:base => ldap_group_conf[:base], :filter => ldap_group_conf[:filter]) do |entry|
|
res = @ldap.search(:base => ldap_group_conf[:base], :filter => ldap_group_conf[:filter]) do |entry|
|
||||||
name = entry[ldap_group_conf[:name_attribute]].first
|
name = entry[name_attribute].first
|
||||||
|
|
||||||
unless name
|
unless name
|
||||||
log.warn "user attribute #{ldap_group_conf[:name_attribute].inspect} not defined for #{entry.dn}"
|
log.warn "user attribute #{name_attribute.inspect} not defined for #{entry.dn}"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
log.info "found group-dn: #{entry.dn}"
|
log.info "found group-dn: #{entry.dn}"
|
||||||
|
|
||||||
names = if ldap_group_conf[:bothcase_name]
|
names = if ldap_group_conf[:bothcase_name]
|
||||||
@ -107,7 +142,8 @@ class Application
|
|||||||
end
|
end
|
||||||
|
|
||||||
names.each do |n|
|
names.each do |n|
|
||||||
groups << LdapRole.new(n, entry.dn, entry[ldap_group_conf[:member_attribute]])
|
group_members = retrieve_array_attribute(entry, member_attribute)
|
||||||
|
groups << LdapRole.new(n, entry.dn, group_members)
|
||||||
end
|
end
|
||||||
entry.each do |attribute, values|
|
entry.each do |attribute, values|
|
||||||
log.debug " #{attribute}:"
|
log.debug " #{attribute}:"
|
||||||
|
4
test/fixtures/ldapdb.yaml
vendored
4
test/fixtures/ldapdb.yaml
vendored
@ -2,6 +2,9 @@
|
|||||||
dc=example,dc=com:
|
dc=example,dc=com:
|
||||||
cn:
|
cn:
|
||||||
- Top object
|
- Top object
|
||||||
|
cn=Unknown Flintstone,dc=example,dc=com:
|
||||||
|
cn:
|
||||||
|
- Unknown Flintstone
|
||||||
cn=Fred Flintstone,dc=example,dc=com:
|
cn=Fred Flintstone,dc=example,dc=com:
|
||||||
cn:
|
cn:
|
||||||
- Fred Flintstone
|
- Fred Flintstone
|
||||||
@ -36,3 +39,4 @@ cn=All Users,dc=example,dc=com:
|
|||||||
member:
|
member:
|
||||||
- cn=Wilmas,dc=example,dc=com
|
- cn=Wilmas,dc=example,dc=com
|
||||||
- cn=Fred Flintstone,dc=example,dc=com
|
- cn=Fred Flintstone,dc=example,dc=com
|
||||||
|
- cn=Unknown Flintstone,dc=example,dc=com
|
||||||
|
@ -17,11 +17,10 @@ class HashOperation < LDAP::Server::Operation
|
|||||||
|
|
||||||
def search(basedn, scope, deref, filter)
|
def search(basedn, scope, deref, filter)
|
||||||
basedn.downcase!
|
basedn.downcase!
|
||||||
|
|
||||||
case scope
|
case scope
|
||||||
when LDAP::Server::BaseObject
|
when LDAP::Server::BaseObject
|
||||||
# client asked for single object by DN
|
# client asked for single object by DN
|
||||||
obj = @hash[basedn]
|
obj = @hash.transform_keys(&:downcase)[basedn]
|
||||||
raise LDAP::ResultError::NoSuchObject unless obj
|
raise LDAP::ResultError::NoSuchObject unless obj
|
||||||
send_SearchResultEntry(basedn, obj) if LDAP::Server::Filter.run(filter, obj)
|
send_SearchResultEntry(basedn, obj) if LDAP::Server::Filter.run(filter, obj)
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ class TestPgLdapSync < Minitest::Test
|
|||||||
# :ssl_cert_file => "cert.pem",
|
# :ssl_cert_file => "cert.pem",
|
||||||
# :ssl_on_connect => true,
|
# :ssl_on_connect => true,
|
||||||
:operation_class => HashOperation,
|
:operation_class => HashOperation,
|
||||||
:operation_args => @directory
|
:operation_args => @directory,
|
||||||
|
:attribute_range_limit => 2
|
||||||
)
|
)
|
||||||
@ldap_server.run_tcpserver
|
@ldap_server.run_tcpserver
|
||||||
end
|
end
|
||||||
@ -122,7 +123,7 @@ class TestPgLdapSync < Minitest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def sync_with_config(config="config-ldapdb")
|
def sync_with_config(config="config-ldapdb")
|
||||||
PgLdapSync::Application.run(["-c", "test/fixtures/#{config}.yaml"] + ($DEBUG ? ["-vv"] : ["--no-verbose"]))
|
PgLdapSync::Application.run(["-c", "test/fixtures/#{config}.yaml"] + ($DEBUG ? ["-vvv"] : ["--no-verbose"]))
|
||||||
end
|
end
|
||||||
|
|
||||||
def sync_to_fixture(fixture: "ldapdb", config: "config-ldapdb")
|
def sync_to_fixture(fixture: "ldapdb", config: "config-ldapdb")
|
||||||
|
Reference in New Issue
Block a user