google-code-export / ruby-activeldap

Automatically exported from code.google.com/p/ruby-activeldap
Other
1 stars 1 forks source link

HasManyWrap association should return ANY associated entries that exist in the directory #13

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

1. Create a groupOfUniqueNames group, call it "test", where the uniqueMember 
attribute contains DNs that don't actually exist in the directory.

2.

class Person < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'cn'
end

class Group < ActiveLdap::Base
  ldap_mapping :dn_attribute => 'cn'
  has_many :members, :class => 'Person', :primary_key => 'dn', :wrap => 'uniqueMember'
end

3. group = Group.find('test')

What is the expected output? What do you see instead?

I'd expect group.members to return any people who's DN was listed in the 
uniqueMember 
attribute and exist in the directory.

Instead, I get no results.

What version of the product are you using? On what operating system?

This behavior is present in trunk r805.  I've tried it against the Sun LDAP 
server using OSX and 
Linux clients, both using ruby-ldap (C extension).

Please provide any additional information below.

Not really related to this report, but thanks normalizing the DNs!  I was just 
about to report on 
that one as well.

Original issue reported on code.google.com by ingers...@gmail.com on 26 Jan 2009 at 10:44

GoogleCodeExporter commented 9 years ago
Could you show us sample entries of Person and Group as LDIF? I'll test the 
problem
with the entries.
You can get them like the following:
  puts Person.find("someone").to_ldif
  puts Group.find("something").to_ldif

Original comment by kou...@gmail.com on 27 Jan 2009 at 12:14

GoogleCodeExporter commented 9 years ago
Sure thing.  I've attached an LDIF file that can be loaded into an empty ldap 
directory to create the conditions for 
the bug.

I've also attached a sample ruby file that sets up the classes.

When you load the file into irb and run "Group.find('sales').members.size" you 
should get "0" whereas I'd expect 
to get "2" as two of the 3 DNs listed as uniqueMembers exist in the directory.

Original comment by ingers...@gmail.com on 29 Jan 2009 at 11:03

Attachments:

GoogleCodeExporter commented 9 years ago
Remove :primary_key => 'dn' from Group.has_many. It means that Group#members 
use "dn"
for Person's dn_attribute. But Person's dn_attribute is "uid" in this case.

Perhaps, documentation is lacked... Sorry. (Sure, we welcome to help :-)

Original comment by kou...@gmail.com on 30 Jan 2009 at 1:15

GoogleCodeExporter commented 9 years ago
Removing the :primary_key option doesn't seem to help.  Instead of members 
returning an empty array I get 
an array with 3 instances of Person without any attributes.

Group.find('sales').members.collect(&:cn) => [nil, nil, nil]

I've attached new files that will hopefully better illustrate this.  If you 
load the 'bug' LDIF and load the .rb file 
with irb and run

Group.find('sales').members.collect(&:cn) you get '[]'

if you clear out the directory and then load the 'working' LDIF and run the 
same command in irb you should 
see '["John Doe", "Jane Doe"]'

The first one fails because there is a non-existent DN in the uniqueMembers and 
ActiveLdap::Operations::Find#find_some raises an exception because it searched 
for 3 DNs and only found 2.

I've also attached a patch which fixes the problem, though I'm not sure if it 
does it in the most appropriate 
way.  After applying the patch, you should be able to load the 'bug' LDIF and 
then run

Group.find('sales').members.collect(&:cn)

which should result in

["John Doe", "Jane Doe"]

Original comment by ingers...@gmail.com on 30 Jan 2009 at 6:10

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for more information. I understood your report.

I've fixed it in trunk but there is different behavior what you show:

  Group.find('sales').members.collect(&:cn)
returns
  ["John Doe", "Jane Doe", nil]
not
  ["John Doe", "Jane Doe"]

And
  Group.find('sales').members.collect(&:new_entry?)
returns
  [false, false, true]

Nonexistent entry is created as ForeignClass.new(foreign_key). In this case,
Person.new(dn).

Original comment by kou...@gmail.com on 31 Jan 2009 at 10:25