From mortonda at dgrmm.net Tue Jan 1 13:33:57 2008 From: mortonda at dgrmm.net (David Morton) Date: Tue, 1 Jan 2008 12:33:57 -0600 Subject: [Ruby-activeldap-discuss] using multiple credentials In-Reply-To: <20071230.104559.1040217551023407791.kou@cozmixng.org> References: <4776727E.5040203@dgrmm.net> <20071230.104559.1040217551023407791.kou@cozmixng.org> Message-ID: <52F15F85-3D09-4BAC-8038-0DD4D0CF0344@dgrmm.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Dec 29, 2007, at 7:45 PM, Kouhei Sutou wrote: > Hi, > > In <4776727E.5040203 at dgrmm.net> > "[Ruby-activeldap-discuss] using multiple credentials" on Sat, 29 > Dec 2007 10:14:54 -0600, > David Morton wrote: > >> I need to re-bind on every request depending on the user logged in >> - the >> ldap server has acls to help limit the data available per login. a >> year >> ago, this was how I achieved it; it doesn't work now - so how do I >> store that connection now? > > AL Admin(*) is a sample Rails application for that. > (*) http://ruby-activeldap.googlecode.com/svn/trunk/examples/al-admin/ > > LdapUser(*) will help you. > > (*) http://ruby-activeldap.googlecode.com/svn/trunk/examples/al-admin/app/models/ldap_user.rb > > If I understand this right, it doesn't quite meet my needs - I need to make all model requests via the binding of a particular user, so I need to apply the bind to the global or class level of ActiveLdap::Base. I can't use an instance of a particular subclass... Well, I could but the call chain would be unecessarily long: a = User.authenticate (user, pass) # bound as user mydomain = a.clients[0].domains[4] as opposed to mydomain = Domains.find('something') right now it seems that I have to make an instance of a user, bind, check for success, and then call ActiveLdap::Base.establish_connection to make it global for this request. Seems like establishConnection should return an error if the bind fails... I could just test that. David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHeoeVUy30ODPkzl0RAnt6AJ9wuVmDACpVrIKNEfLi3Z9mhkr7VQCfc1Jz vkM+xqSr7MztZI8eWtCaoSE= =d9Ds -----END PGP SIGNATURE----- From mortonda at dgrmm.net Tue Jan 1 19:15:32 2008 From: mortonda at dgrmm.net (David Morton) Date: Tue, 1 Jan 2008 18:15:32 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace Message-ID: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 A year ago I was reading up on a problem of doing a read and increment of a number in a single transaction, and the method explained was to read the number, and then in one modification command delete that number and insert the new number. This used to look like: currentuid = result.first['uidNumber'].first.to_i nextuid = currentuid + 1 UidNext.connection.modify("cn=uidNext,dc=example,dc=net", [ LDAP.mod(LDAP::LDAP_MOD_DELETE, 'uidNumber' , [currentuid.to_s] ), LDAP.mod(LDAP::LDAP_MOD_ADD, 'uidNumber' , [nextuid.to_s] ) ]) return currentuid As I look through the current API, I see some changes, such as symbols to replace the constants.... and it's missing the delete option, but has no delete. It's a simple addition to line 223 of adapter/ldap.rb: when :replace, :add, :delete Next, I had to figure out the syntax to feed the modify routine. This got much uglier in the last year. UidNext.connection.modify("cn=uidNext,,dc=example,dc=net", [ [:delete, 'uidNumber' , {'uidNumber' => [currentuid.to_s]}] , [:add, 'uidNumber' , {'uidNumber' => [nextuid.to_s]}] ]) perhaps I don't understand what "key" is in that array of: type, key, attributes but it looks redundant to the attribute name in the attributes array. At any rate, this area of the code needs more documentation. If someone will help me understand this area of code, I'll try to submit a documentation patch. For the sake of discussion, here's the current code in question: def parse_entries(entries) result = [] entries.each do |type, key, attributes| mod_type = ensure_mod_type(type) binary = schema.attribute(key).binary? mod_type |= LDAP::LDAP_MOD_BVALUES if binary attributes.each do |name, values| result << LDAP.mod(mod_type, name, values) end end result end As I see it, "key" exists only to see if it needs to be binary - but I think it's in the wrong place... shouldn't the binary check be run for each attribute? def parse_entries(entries) result = [] entries.each do |type, attributes| mod_type = ensure_mod_type(type) attributes.each do |name, values| result << LDAP.mod((schema.attribute(name).binary? ? mod_type | LDAP::LDAP_MOD_BVALUES : mod_type), name, values) end end result end Which changes the number of entries in the call: connection.modify("cn=uidNext,dc=example,dc=net", [ [:delete, {'uidNumber' => [currentuid.to_s]}] , [:add, {'uidNumber' => [nextuid.to_s]}] ]) or for another example: connection.modify("cn=foo...", [ [:add {'cn' => ['foo'], 'sn' => ['bar']}], [:delete, {'displayName' => ['goofy']}] ]) It still looks ugly. Can anyone enlighten me? David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHetelUy30ODPkzl0RAmijAJwOzgkmRpS5ge4uoMlMMdKRjBTzdQCfZzIV 2aZzgE0T9GPynU4cmeYLAWQ= =GVmd -----END PGP SIGNATURE----- From kou at cozmixng.org Tue Jan 1 22:14:33 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Wed, 02 Jan 2008 12:14:33 +0900 (JST) Subject: [Ruby-activeldap-discuss] using multiple credentials In-Reply-To: <52F15F85-3D09-4BAC-8038-0DD4D0CF0344@dgrmm.net> References: <4776727E.5040203@dgrmm.net> <20071230.104559.1040217551023407791.kou@cozmixng.org> <52F15F85-3D09-4BAC-8038-0DD4D0CF0344@dgrmm.net> Message-ID: <20080102.121433.1082999731551860225.kou@cozmixng.org> Hi, In <52F15F85-3D09-4BAC-8038-0DD4D0CF0344 at dgrmm.net> "Re: [Ruby-activeldap-discuss] using multiple credentials" on Tue, 1 Jan 2008 12:33:57 -0600, David Morton wrote: > >> I need to re-bind on every request depending on the user logged in > >> - the > >> ldap server has acls to help limit the data available per login. a > >> year > >> ago, this was how I achieved it; it doesn't work now - so how do I > >> store that connection now? > > > > AL Admin(*) is a sample Rails application for that. > > (*) http://ruby-activeldap.googlecode.com/svn/trunk/examples/al-admin/ > > > > LdapUser(*) will help you. > > > > (*) http://ruby-activeldap.googlecode.com/svn/trunk/examples/al-admin/app/models/ldap_user.rb > > > > > > If I understand this right, it doesn't quite meet my needs - I need > to make all model requests via the binding of a particular user, so I > need to apply the bind to the global or class level of > ActiveLdap::Base. I can't use an instance of a particular > subclass... Well, I could but the call chain would be unecessarily > long: > > a = User.authenticate (user, pass) # bound as user > mydomain = a.clients[0].domains[4] > > as opposed to > > mydomain = Domains.find('something') ActiveLdap::Base.connection = a.connection mydomain = Domains.find('something') Thanks, -- kou From kou at cozmixng.org Tue Jan 1 22:37:03 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Wed, 02 Jan 2008 12:37:03 +0900 (JST) Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> Message-ID: <20080102.123703.311478874151151801.kou@cozmixng.org> Hi, In <2B73F3C0-1F3C-4275-B567-F89A25E16D0A at dgrmm.net> "[Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 18:15:32 -0600, David Morton wrote: > As I look through the current API, I see some changes, such as symbols > to replace the constants.... and it's missing the delete option, but > has no delete. In the trunk, there is the API: delete_entry. > def parse_entries(entries) > result = [] > entries.each do |type, key, attributes| > mod_type = ensure_mod_type(type) > binary = schema.attribute(key).binary? > mod_type |= LDAP::LDAP_MOD_BVALUES if binary > attributes.each do |name, values| > result << LDAP.mod(mod_type, name, values) > end > end > result > end > > As I see it, "key" exists only to see if it needs to be binary - but I > think it's in the wrong place... shouldn't the binary check be run for > each attribute? "attributes" is for values of "key" attribute. The values may have "ou" => ..., "ou;lang-ja" => ..., "ou;lang-ja;phonetic" =>, and so on. So "key" is needed. In the current API, an entry should only have a attribute. I'm sorry for ugly APIs. -- kou From mortonda at dgrmm.net Tue Jan 1 22:38:17 2008 From: mortonda at dgrmm.net (David Morton) Date: Tue, 1 Jan 2008 21:38:17 -0600 Subject: [Ruby-activeldap-discuss] using multiple credentials In-Reply-To: <20080102.121433.1082999731551860225.kou@cozmixng.org> References: <4776727E.5040203@dgrmm.net> <20071230.104559.1040217551023407791.kou@cozmixng.org> <52F15F85-3D09-4BAC-8038-0DD4D0CF0344@dgrmm.net> <20080102.121433.1082999731551860225.kou@cozmixng.org> Message-ID: <1617A54B-2771-401E-B2AC-B8F663CFE957@dgrmm.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 1, 2008, at 9:14 PM, Kouhei Sutou wrote: > > ActiveLdap::Base.connection = a.connection > mydomain = Domains.find('something') that would be nice. ActiveLdap::Base.connect=a.connection NoMethodError: undefined method `connect=' for ActiveLdap::Base:Class from (irb):11 from :0 David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHewcqUy30ODPkzl0RAoj4AKCnp+G9gVSNlSDvn+iXNv4xABGHQQCfYHKK XsOdpn41HWUMh8Vr13n6aKI= =D00X -----END PGP SIGNATURE----- From kou at cozmixng.org Tue Jan 1 22:51:54 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Wed, 02 Jan 2008 12:51:54 +0900 (JST) Subject: [Ruby-activeldap-discuss] using multiple credentials In-Reply-To: <1617A54B-2771-401E-B2AC-B8F663CFE957@dgrmm.net> References: <52F15F85-3D09-4BAC-8038-0DD4D0CF0344@dgrmm.net> <20080102.121433.1082999731551860225.kou@cozmixng.org> <1617A54B-2771-401E-B2AC-B8F663CFE957@dgrmm.net> Message-ID: <20080102.125154.904811380799058180.kou@cozmixng.org> Hi, In <1617A54B-2771-401E-B2AC-B8F663CFE957 at dgrmm.net> "Re: [Ruby-activeldap-discuss] using multiple credentials" on Tue, 1 Jan 2008 21:38:17 -0600, David Morton wrote: > > ActiveLdap::Base.connection = a.connection > > mydomain = Domains.find('something') > > that would be nice. > > ActiveLdap::Base.connect=a.connection > NoMethodError: undefined method `connect=' for ActiveLdap::Base:Class > from (irb):11 > from :0 Why do you use 'connect=' instead of 'connection='? Thanks, -- kou From mortonda at dgrmm.net Tue Jan 1 23:00:00 2008 From: mortonda at dgrmm.net (David Morton) Date: Tue, 1 Jan 2008 22:00:00 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: <20080102.123703.311478874151151801.kou@cozmixng.org> References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 1, 2008, at 9:37 PM, Kouhei Sutou wrote: > Hi, > > In <2B73F3C0-1F3C-4275-B567-F89A25E16D0A at dgrmm.net> > "[Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 > 18:15:32 -0600, > David Morton wrote: > >> As I look through the current API, I see some changes, such as >> symbols >> to replace the constants.... and it's missing the delete option, but >> has no delete. > > In the trunk, there is the API: delete_entry. Ah, well, the modify needs it too, so that this one operation can be done in one ldap statement, iirc. It's been a while since I read about this procedure, but it seems like it was an odd one. > > >> def parse_entries(entries) >> result = [] >> entries.each do |type, key, attributes| >> mod_type = ensure_mod_type(type) >> binary = schema.attribute(key).binary? >> mod_type |= LDAP::LDAP_MOD_BVALUES if binary >> attributes.each do |name, values| >> result << LDAP.mod(mod_type, name, values) >> end >> end >> result >> end >> >> As I see it, "key" exists only to see if it needs to be binary - >> but I >> think it's in the wrong place... shouldn't the binary check be run >> for >> each attribute? > > "attributes" is for values of "key" attribute. The values > may have "ou" => ..., "ou;lang-ja" => ..., > "ou;lang-ja;phonetic" =>, and so on. So "key" is needed. In > the current API, an entry should only have a attribute. > > > I'm sorry for ugly APIs. > Hmm. then I wonder if we can make it detect whether attributes.each is an array or a value and act accordingly? It's not very DRY... def parse_entries(entries) result = [] entries.each do |type, key, attributes| mod_type = ensure_mod_type(type) binary = schema.attribute(key).binary? mod_type |= LDAP::LDAP_MOD_BVALUES if binary if attributes.kind_of? Hash attributes.each do |name, values| result << LDAP.mod(mod_type, name, values) end else result << LDAP.mod(mod_type,key, attributes) end end result end which would allow for a simpler: UidNext.connection.modify("cn=uidNext,,dc=example,dc=net", [ [:delete, 'uidNumber' , currentuid.to_s ], [:add, 'uidNumber' , nextuid.to_s] ]) If I understand you right, an entry contains attributes (such as displayName) that can have multiple values keyed on locale info? Not to be confused with attributes that can contain multiple values, such as "mail" I've never seen this "ou;lang-ja" stuff before. David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHewxBUy30ODPkzl0RAov+AJ9gbdLhCqnzwYxcLeC4f+UxRLQbIwCfX/5W 8om29GsBd+tpIOQgo/lNoug= =lpjP -----END PGP SIGNATURE----- From kou at cozmixng.org Tue Jan 1 23:24:20 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Wed, 02 Jan 2008 13:24:20 +0900 (JST) Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> Message-ID: <20080102.132420.776400912768631404.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 22:00:00 -0600, David Morton wrote: > If I understand you right, an entry contains attributes (such as > displayName) that can have multiple values keyed on locale info? Not > to be confused with attributes that can contain multiple values, such > as "mail" The API is based of LDIF concept. If you don't know about the detail, see RFC 2849. Anyway, I can't understand that why you don't use normal ActiveLdap API: uid_next = UidNext.find("XXX") uid_next.uid_number += 1 uid_next.save That does what you do with modify(). Thanks, -- kou From mortonda at dgrmm.net Tue Jan 1 23:56:02 2008 From: mortonda at dgrmm.net (David Morton) Date: Tue, 1 Jan 2008 22:56:02 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: <20080102.132420.776400912768631404.kou@cozmixng.org> References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> <20080102.132420.776400912768631404.kou@cozmixng.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 1, 2008, at 10:24 PM, Kouhei Sutou wrote: > > > Anyway, I can't understand that why you don't use normal > ActiveLdap API: > > uid_next = UidNext.find("XXX") > uid_next.uid_number += 1 > uid_next.save > > That does what you do with modify(). Because there is a race condition if two requests are made at the same time. I'm still not sure about all the ins and outs of the race condition, but I think it's due to the fact that there are no transactions in ldap. user 1 executes the find, gets the number 10. user 2 executes the find, gets number 10. user1 executes the +=1 and saves user2 executes the +=1 and saves Now both have attempted to created a user with the same uid. The only way to handle it is to execute a ldap query that reads the value, and then attempts to delete it and re-add the new value. Note how my delete statement specifies the *value* to delete, so in the scenario above, it would be: user 1 executes the find, gets the number 10. user 2 executes the find, gets number 10. user1 deletes "10" and adds "11" user2 tries to delete "10" and fails. Normally, delete operations specify only the attribute to delete and not the value too, which is why I have to revert down to the raw connection to do this. A nice API to do it *might* be something like: uid_next = UidNext.find(:first) uid = uid_next.uidNext uid_next.delete_attribute('uidNext',uid) #throws error if there was no uidNext with value uid uid_next.uidNext=uid+1 David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHexliUy30ODPkzl0RAjY+AJ4/7zOksFTcb/n7V+ZZ/CO60thy/QCgtUbz srmEdB77Mgs2tO5F6le7RAQ= =m1I7 -----END PGP SIGNATURE----- From mortonda at dgrmm.net Wed Jan 2 00:18:07 2008 From: mortonda at dgrmm.net (David Morton) Date: Tue, 1 Jan 2008 23:18:07 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: <20080102.123703.311478874151151801.kou@cozmixng.org> References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 1, 2008, at 9:37 PM, Kouhei Sutou wrote: > > I'm sorry for ugly APIs. How about: UidNext.connection.modify("cn=uidNext,dc=sentinare,dc=net", [ {:op => :delete, :binopt => '' , :attribute => 'uidNumber' :value => [currentuid.to_s]} , {:add, :binopt => '' , :attribute => 'uidNumber', :value => [nextuid.to_s]} ]) It may be a bit more verbose, but I think it captures the meaning much more clearly. :binopt could then be the 'lang-ja" part. def parse_entries(entries) result = [] entries.each do |entry| mod_type = ensure_mod_type(entry[:op]) binary = schema.attribute(entry[:binopt]).binary? mod_type |= LDAP::LDAP_MOD_BVALUES if binary entry[:value].each do |value| result << LDAP.mod(mod_type, entry[:attribute], value) end end result end David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHex6PUy30ODPkzl0RAtKnAKDHpPD3CB3H6HpMWmFZLVbFadSG+ACfaDcq Nuhc/EKzS0uqEt9hmc0FWAY= =6vsK -----END PGP SIGNATURE----- From kou at cozmixng.org Wed Jan 2 01:01:16 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Wed, 02 Jan 2008 15:01:16 +0900 (JST) Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: References: <20080102.132420.776400912768631404.kou@cozmixng.org> Message-ID: <20080102.150116.919072888197535433.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 22:56:02 -0600, David Morton wrote: > user 1 executes the find, gets the number 10. > user 2 executes the find, gets number 10. > user1 deletes "10" and adds "11" > user2 tries to delete "10" and fails. > > Normally, delete operations specify only the attribute to delete and > not the value too, which is why I have to revert down to the raw > connection to do this. Thanks. I understand. -- kou From kou at cozmixng.org Wed Jan 2 01:08:28 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Wed, 02 Jan 2008 15:08:28 +0900 (JST) Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> Message-ID: <20080102.150828.247953246017175682.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 23:18:07 -0600, David Morton wrote: > :binopt could then be the 'lang-ja" part. > > > def parse_entries(entries) > result = [] > entries.each do |entry| > mod_type = ensure_mod_type(entry[:op]) > binary = schema.attribute(entry[:binopt]).binary? > mod_type |= LDAP::LDAP_MOD_BVALUES if binary > entry[:value].each do |value| > result << LDAP.mod(mod_type, entry[:attribute], value) > end > end > result > end We need to pass attribute name to schema.attribute() not attribute options. -- kou From mortonda at dgrmm.net Wed Jan 2 01:50:30 2008 From: mortonda at dgrmm.net (David Morton) Date: Wed, 2 Jan 2008 00:50:30 -0600 Subject: [Ruby-activeldap-discuss] using multiple credentials In-Reply-To: <20080102.125154.904811380799058180.kou@cozmixng.org> References: <52F15F85-3D09-4BAC-8038-0DD4D0CF0344@dgrmm.net> <20080102.121433.1082999731551860225.kou@cozmixng.org> <1617A54B-2771-401E-B2AC-B8F663CFE957@dgrmm.net> <20080102.125154.904811380799058180.kou@cozmixng.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 1, 2008, at 9:51 PM, Kouhei Sutou wrote: > Hi, > > In <1617A54B-2771-401E-B2AC-B8F663CFE957 at dgrmm.net> > "Re: [Ruby-activeldap-discuss] using multiple credentials" on Tue, > 1 Jan 2008 21:38:17 -0600, > David Morton wrote: > >>> ActiveLdap::Base.connection = a.connection >>> mydomain = Domains.find('something') >> >> that would be nice. >> >> ActiveLdap::Base.connect=a.connection >> NoMethodError: undefined method `connect=' for ActiveLdap::Base:Class >> from (irb):11 >> from :0 > > Why do you use 'connect=' instead of 'connection='? > > Well bugger, I thought I did. That works. I thought that was what I had to begin with. weird. :) David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHezQ2Uy30ODPkzl0RAqxQAKC/h3SHYy1cV2iTyZehngXvgfwpEgCfUf1s GHq3nsTznHofRQbBVh+2S6I= =lBLt -----END PGP SIGNATURE----- From mortonda at dgrmm.net Wed Jan 2 11:30:25 2008 From: mortonda at dgrmm.net (David Morton) Date: Wed, 2 Jan 2008 10:30:25 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: <20080102.150116.919072888197535433.kou@cozmixng.org> References: <20080102.132420.776400912768631404.kou@cozmixng.org> <20080102.150116.919072888197535433.kou@cozmixng.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 2, 2008, at 12:01 AM, Kouhei Sutou wrote: > Hi, > > In > "Re: [Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 > 22:56:02 -0600, > David Morton wrote: > >> user 1 executes the find, gets the number 10. >> user 2 executes the find, gets number 10. >> user1 deletes "10" and adds "11" >> user2 tries to delete "10" and fails. >> >> Normally, delete operations specify only the attribute to delete and >> not the value too, which is why I have to revert down to the raw >> connection to do this. > > Thanks. I understand. > I found the more exact info in RFC 2251, section 4.6: Parameters of the Modify Request are: - object: The object to be modified. The value of this field contains the DN of the entry to be modified. The server will not perform any alias dereferencing in determining the object to be modified. - modification: A list of modifications to be performed on the entry. The entire list of entry modifications MUST be performed in the order they are listed, as a single atomic operation. While individual modifications may violate the directory schema, the resulting entry after the entire list of modifications is performed MUST conform to the requirements of the directory schema. The values that may be taken on by the 'operation' field in each modification construct have the following semantics respectively: add: add values listed to the given attribute, creating the attribute if necessary; delete: delete values listed from the given attribute, removing the entire attribute if no values are listed, or if all current values of the attribute are listed for deletion; replace: replace all existing values of the given attribute with the new values listed, creating the attribute if it did not already exist. A replace with no value will delete the entire attribute if it exists, and is ignored if the attribute does not exist. David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHe7whUy30ODPkzl0RAhhTAKCaZQSkLaJa3BydiqVCXgFd+iPk8QCgyEQP TWqFdFtuMK6VmcO8omKtt7c= =FF65 -----END PGP SIGNATURE----- From mortonda at dgrmm.net Wed Jan 2 13:30:47 2008 From: mortonda at dgrmm.net (David Morton) Date: Wed, 2 Jan 2008 12:30:47 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace In-Reply-To: <20080102.150828.247953246017175682.kou@cozmixng.org> References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> <20080102.150828.247953246017175682.kou@cozmixng.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 2, 2008, at 12:08 AM, Kouhei Sutou wrote: > Hi, > > In > "Re: [Ruby-activeldap-discuss] Atomic replace" on Tue, 1 Jan 2008 > 23:18:07 -0600, > David Morton wrote: > >> :binopt could then be the 'lang-ja" part. >> >> >> def parse_entries(entries) >> result = [] >> entries.each do |entry| >> mod_type = ensure_mod_type(entry[:op]) >> binary = schema.attribute(entry[:binopt]).binary? >> mod_type |= LDAP::LDAP_MOD_BVALUES if binary >> entry[:value].each do |value| >> result << LDAP.mod(mod_type, entry[:attribute], value) >> end >> end >> result >> end > > We need to pass attribute name to schema.attribute() not > attribute options. > OK, right. Does schema.attribute() need the options like "lang- ja;phonetic" ? Also, I guess those options need to be passed on to the LDAP.mod() call. Let me try again. :) Was your original intent to have something like this? I'm wondering what the original data structure was supposed to be... modify("cn=me,dc=example,dc=net", [ [:add, 'sn' , {'sn;lang-en' => 'dave', 'sn;lang-es' => 'Juan'}] , [:add, 'mail' , {'mail' => ['mortonda at dgrmm.net','test at dgrmm.net ']}] ]) Should one row in this data structure allow for for a set of values for an attribute? Oh, by testing, it does. If this is what you were expecting, then maybe this would work: def parse_entries(entries) result = [] entries.each do |mod, attribute, values| mod_type = ensure_mod_type(mod) binary = schema.attribute(attribute).binary? mod_type |= LDAP::LDAP_MOD_BVALUES if binary if values.kind_of? Hash #attribute options are in use values.each do |key, value| if value.kind_of? Array result << LDAP.mod(mod_type, key, value) else result << LDAP.mod(mod_type, key, [value]) end end elsif values.kind_of? Array # list of values for a simple attribute result << LDAP.mod(mod_type, attribute, values) else #a single value needs to be wrapped in an array result << LDAP.mod(mod_type, attribute, [values]) end end result end modify("cn=me,dc=example,dc=net", [ [:add, 'sn' , {'sn;lang-en' => 'John', 'sn;lang-es' => 'Juan'}] , [:delete, 'mail' , ['johndoe at example.net','test at example.net']], [:replace, 'displayName' , 'John Doe'], [:replace, 'sn' , {'sn' => ['Dokes']}] ]) This way there is a simpler API for simple cases. I think I've tested this code - if you'd like I could make a patch against a clean 0.9 source (with comments for documentation!). If I'm reading this right, it's even backwards compatible with what's there now. David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHe9hXUy30ODPkzl0RAlilAKC7FPn/9oDp/cx/2biGI5f74x04WgCfXML3 OayP8L5Kk1ovYfyKL7DifRQ= =ok1J -----END PGP SIGNATURE----- From mortonda at dgrmm.net Wed Jan 2 14:03:57 2008 From: mortonda at dgrmm.net (David Morton) Date: Wed, 2 Jan 2008 13:03:57 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace [PATCH] In-Reply-To: References: <2B73F3C0-1F3C-4275-B567-F89A25E16D0A@dgrmm.net> <20080102.123703.311478874151151801.kou@cozmixng.org> <20080102.150828.247953246017175682.kou@cozmixng.org> Message-ID: <4C5DC7F8-FF9D-4AF6-B004-79D0328B6D04@dgrmm.net> On Jan 2, 2008, at 12:30 PM, David Morton wrote: > > This way there is a simpler API for simple cases. I think I've > tested this code - if you'd like I could make a patch against a clean > 0.9 source (with comments for documentation!). If I'm reading this > right, it's even backwards compatible with what's there now. > Here's a patch against 0.9 that works well for me. -------------- next part -------------- A non-text attachment was scrubbed... Name: modify.patch Type: application/octet-stream Size: 3658 bytes Desc: not available Url : http://rubyforge.org/pipermail/ruby-activeldap-discuss/attachments/20080102/c4884641/attachment.obj -------------- next part -------------- David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 186 bytes Desc: This is a digitally signed message part Url : http://rubyforge.org/pipermail/ruby-activeldap-discuss/attachments/20080102/c4884641/attachment.bin From kou at cozmixng.org Wed Jan 2 21:22:15 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 03 Jan 2008 11:22:15 +0900 (JST) Subject: [Ruby-activeldap-discuss] Atomic replace [PATCH] In-Reply-To: <4C5DC7F8-FF9D-4AF6-B004-79D0328B6D04@dgrmm.net> References: <20080102.150828.247953246017175682.kou@cozmixng.org> <4C5DC7F8-FF9D-4AF6-B004-79D0328B6D04@dgrmm.net> Message-ID: <20080103.112215.461633889411902863.kou@cozmixng.org> Hi, In <4C5DC7F8-FF9D-4AF6-B004-79D0328B6D04 at dgrmm.net> "Re: [Ruby-activeldap-discuss] Atomic replace [PATCH]" on Wed, 2 Jan 2008 13:03:57 -0600, David Morton wrote: > > On Jan 2, 2008, at 12:30 PM, David Morton wrote: > > > > This way there is a simpler API for simple cases. I think I've > > tested this code - if you'd like I could make a patch against a clean > > 0.9 source (with comments for documentation!). If I'm reading this > > right, it's even backwards compatible with what's there now. > > > > Here's a patch against 0.9 that works well for me. Thanks but could you make a patch against trunk? And could you write test cases for that if you can? It's better that modify() document is written in lib/active_ldap/operations.rb not lib/active_ldap/adapter/*.rb. Because lib/active_ldap/operations.rb is an abstract layer of lib/active_ldap/adapter/*.rb. Thanks, -- kou From mortonda at dgrmm.net Wed Jan 2 23:57:56 2008 From: mortonda at dgrmm.net (David Morton) Date: Wed, 2 Jan 2008 22:57:56 -0600 Subject: [Ruby-activeldap-discuss] Atomic replace [PATCH] In-Reply-To: <20080103.112215.461633889411902863.kou@cozmixng.org> References: <20080102.150828.247953246017175682.kou@cozmixng.org> <4C5DC7F8-FF9D-4AF6-B004-79D0328B6D04@dgrmm.net> <20080103.112215.461633889411902863.kou@cozmixng.org> Message-ID: <54100AAE-D243-4468-AABA-7DEE8ADE262A@dgrmm.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Jan 2, 2008, at 8:22 PM, Kouhei Sutou wrote: > Thanks but could you make a patch against trunk? And could > you write test cases for that if you can? > > > It's better that modify() document is written in > lib/active_ldap/operations.rb not > lib/active_ldap/adapter/*.rb. Because > lib/active_ldap/operations.rb is an abstract layer of > lib/active_ldap/adapter/*.rb. > I'll see what I can do... I haven't looked at trunk yet. David Morton Maia Mailguard http://www.maiamailguard.com mortonda at dgrmm.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHfGtUUy30ODPkzl0RAl7AAKChTAYnCGUgje4Luwd8dl+vDpqAIwCgqOt2 7teM5KVkllSkN6//mzv+f9o= =TI+h -----END PGP SIGNATURE----- From me at bjeanes.com Sun Jan 6 21:02:55 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Mon, 7 Jan 2008 12:02:55 +1000 Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: References: <20071227.230943.969981366266496128.kou@cozmixng.org> Message-ID: Thank you. I had been trying that but was trying to use it directly on Base as both a class and instance method, i had not thought to try an instance method on a derived object. It worked perfectly. However I either misunderstand the intended purpose or have found a bug (0.9.0 - have not checked trunk): e.g. (according to my custom find method in my User class definition) bj = User.find("bjeanes") => #... bj.bind("") => true bug? #bind works fine with non-blank passwords, correctly authentication valid password and raising an exception when it is incorrect. Thanks, Bodaniel Jeanes On 12/28/07, Kouhei Sutou wrote: > Hi, > > In > "[Ruby-activeldap-discuss] Establish_connection behaviour" on Thu, 20 Dec 2007 13:15:13 +1000, > "Bodaniel Jeanes" wrote: > > > I have been trying to figure out the best way to authenticate against > > LDAP using the ActiveLdap library. Unfortunately the information in > > http://wiki.rubyonrails.org/rails/pages/HowtoAuthenticateViaLdap is > > evidently very outdated. I have been trying to use > > establish_connection to try to do the same thing but there are some > > things that make it hard. > > See an example Rails application: > http://ruby-activeldap.googlecode.com/svn/trunk/examples/al-admin/app/models/ldap_user.rb > > There is ActiveLdap::Base#bind for your propose since 0.9.0. > Before 0.9.0, ActiveLdap::Base.establish_connection and/or > ActiveLdap::Base#establish_connection are used for that. > > > Thanks, > -- > kou > _______________________________________________ > Ruby-activeldap-discuss mailing list > Ruby-activeldap-discuss at rubyforge.org > http://rubyforge.org/mailman/listinfo/ruby-activeldap-discuss > From kou at cozmixng.org Mon Jan 7 06:18:43 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Mon, 07 Jan 2008 20:18:43 +0900 (JST) Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: References: <20071227.230943.969981366266496128.kou@cozmixng.org> Message-ID: <20080107.201843.1099454952842045273.kou@cozmixng.org> Hi, In "[Ruby-activeldap-discuss] Establish_connection behaviour" on Mon, 7 Jan 2008 12:02:55 +1000, "Bodaniel Jeanes" wrote: > e.g. (according to my custom find method in my User class definition) > > bj = User.find("bjeanes") > => #... > bj.bind("") > => true > > bug? #bind works fine with non-blank passwords, correctly > authentication valid password and raising an exception when it is > incorrect. ActiveLdap::LdapError::UnwillingToPerform is raised on my environment. Should we re-raise ActiveLdap::AuthenticationError for ActiveLdap::LdapError::UnwillingToPerform? Thanks, -- kou From me at bjeanes.com Mon Jan 7 07:07:02 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Mon, 7 Jan 2008 22:07:02 +1000 Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: <20080107.201843.1099454952842045273.kou@cozmixng.org> References: <20071227.230943.969981366266496128.kou@cozmixng.org> <20080107.201843.1099454952842045273.kou@cozmixng.org> Message-ID: It depends. What does the RFC have to say about blank passwords. Perhaps some LDAP implementations allow for empty passwords? Unless zero-length passwords are explicitly prohibited, I think it should return an AuthenticationError for a few reasons. Namely, a programmer only has to rescue from one specific error/exception and the programmer doesn't need a special case for situations when a user doesn't enter a password in a form when it comes to authenticating against ldap. When it comes down to it though, what's really important is that it just doesn't return true like I am getting. > ActiveLdap::LdapError::UnwillingToPerform is raised on my > environment. Is this in the same place where I get true? and is that trunk or 0.9.0. Perhaps I broke something in my ventures into the source code. Good work on this project! Bodaniel Jeanes From kou at cozmixng.org Mon Jan 7 08:12:01 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Mon, 07 Jan 2008 22:12:01 +0900 (JST) Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: References: <20080107.201843.1099454952842045273.kou@cozmixng.org> Message-ID: <20080107.221201.47722570944388978.kou@cozmixng.org> Hi, > It depends. What does the RFC have to say about blank passwords. > Perhaps some LDAP implementations allow for empty passwords? Do you know about that? > Unless > zero-length passwords are explicitly prohibited, I think it should > return an AuthenticationError for a few reasons. Namely, a programmer > only has to rescue from one specific error/exception and the > programmer doesn't need a special case for situations when a user > doesn't enter a password in a form when it comes to authenticating > against ldap. Why "only has to rescue from one specific error/exception"? Is it for convenient? Does the programmer need to show his user an error message like "Do you forget to enter your password?"? > When it comes down to it though, what's really important is that it > just doesn't return true like I am getting. > > > ActiveLdap::LdapError::UnwillingToPerform is raised on my > > environment. > > Is this in the same place where I get true? and is that trunk or > 0.9.0. Perhaps I broke something in my ventures into the source code. My test code is in the repository as test_rebind_with_empty_password: http://ruby-activeldap.googlecode.com/svn/trunk/test/test_connection_per_dn.rb The test code can be work with 0.9.0. You can try that on your environment. Thanks, -- kou From me at bjeanes.com Mon Jan 7 17:48:08 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 8 Jan 2008 08:48:08 +1000 Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: <20080107.221201.47722570944388978.kou@cozmixng.org> References: <20080107.201843.1099454952842045273.kou@cozmixng.org> <20080107.221201.47722570944388978.kou@cozmixng.org> Message-ID: > > It depends. What does the RFC have to say about blank passwords. > > Perhaps some LDAP implementations allow for empty passwords? > > Do you know about that? I am afraid I do not. I am only just beginning out using active directory for an intranet system i am designing. According to a brief google session (http://www.openldap.org/lists/openldap-software/200112/msg00175.html), some servers (OpenLDAP, Sun Directory Server) treat a bind with an empty password as an anonymous bind, even if connecting like a normal bind with a username. Further searching brought me to http://jeftek.spaces.live.com/blog/cns!F2042DC08607EF2!710.entry which highlighted section 5.1 of RFC 2829 (http://www.ietf.org/rfc/rfc2829.txt) which specifies: > An LDAP client MAY also specify anonymous authentication in a bind > request by using a zero-length OCTET STRING with the simple > authentication choice. I am not sure if this behaviour can be discovered from the schema or if a default behaviour should be chosen for ActiveLdap. Perhaps it can be configurable client side? At the very least, users should be somehow aware that a blank password can lead to a false positive when used for authenticating users and hence a security vulnerability if not checked. I.e. user goes to webpage/application and types in username + empty password, and can be logged in as anyone successfully. > Why "only has to rescue from one specific error/exception"? > Is it for convenient? Yes I meant for convenience. But since reading the RFC I think that some form of special exception SHOULD be thrown IF the bind is successful using a blank password. If NOSUCCESS is sent back, it should deny authentication normally (since in that case either anonymous binding is denied or the particular server is not treating it as an anonymous bind. The exception should be something like BlankPasswordTreatedAsAnonymous or something less wordy. > Does the programmer need to show his user an error message > like "Do you forget to enter your password?"? That's the idea, but unless people are aware that blank passwords behave this way, they might not think to do that. > My test code is in the repository as > test_rebind_with_empty_password: > http://ruby-activeldap.googlecode.com/svn/trunk/test/test_connection_per_dn.rb > > The test code can be work with 0.9.0. You can try that on > your environment. I'll have a try a bit later but I suspect it has something to do with the servers we are using. I am using Active Directory -- what about you? Thanks, Bo From me at bjeanes.com Mon Jan 7 19:50:46 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 8 Jan 2008 10:50:46 +1000 Subject: [Ruby-activeldap-discuss] objectClass exclusions in ldap_mapping Message-ID: Is there a way to specify classes that you explicitly DON'T want as part of the Base subclass? For some bizarre reason I have discovered that all the computers in my work's active directory have the following classes: >> comp.classes => ["top", "person", "organizationalPerson", "user", "computer"] My LdapUser class' ldap_mapping classes option specifies "top", "person", and "user". Is there a way to make it exclude objects of class "computer"? My work's active directory is a MESS. They are starting to organise the tree overall (thank god) but there are so many places where things are uselessly overcomplicated. It doesn't help that I have never used active directory or even LDAP before. I don't even know what the difference between person, user, and organizationalPerson is. they all seem the same thing in English! Thanks, Bo From kou at cozmixng.org Tue Jan 8 07:07:50 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 08 Jan 2008 21:07:50 +0900 (JST) Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: References: <20080107.221201.47722570944388978.kou@cozmixng.org> Message-ID: <20080108.210750.221365570354206064.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Establish_connection behaviour" on Tue, 8 Jan 2008 08:48:08 +1000, "Bodaniel Jeanes" wrote: > Further searching brought me to > http://jeftek.spaces.live.com/blog/cns!F2042DC08607EF2!710.entry which > highlighted section 5.1 of RFC 2829 > (http://www.ietf.org/rfc/rfc2829.txt) which specifies: > > > An LDAP client MAY also specify anonymous authentication in a bind > > request by using a zero-length OCTET STRING with the simple > > authentication choice. Thanks. I changed bind("") behavior like the following: bind("") -> AuthenticationError bind("", :allow_anonymous => true) -> no exception. uses anonymous bind with log message. > the servers we are using. I am using Active Directory -- what about > you? I'm using OpenLDAP. It's good news that ActiveLdap works well with Active Directory. Thanks, -- kou From me at bjeanes.com Tue Jan 8 07:18:55 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 8 Jan 2008 22:18:55 +1000 Subject: [Ruby-activeldap-discuss] Establish_connection behaviour In-Reply-To: <20080108.210750.221365570354206064.kou@cozmixng.org> References: <20080107.221201.47722570944388978.kou@cozmixng.org> <20080108.210750.221365570354206064.kou@cozmixng.org> Message-ID: > I changed bind("") behavior like the following: > > bind("") > -> AuthenticationError > bind("", :allow_anonymous => true) > -> no exception. uses anonymous bind with log message. Perfect > > the servers we are using. I am using Active Directory -- what about > > you? > > I'm using OpenLDAP. It's good news that ActiveLdap works > well with Active Directory. Yeah 95% of my issues so far have been due to the organization-specific tree structure, not Active Directory itself. After being confused by numerous rails + ldap authentication wiki pages which are so inaccurate and finally reading the rdocs, it's been mostly smooth sailing =) Bo From kou at cozmixng.org Tue Jan 8 08:07:33 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 08 Jan 2008 22:07:33 +0900 (JST) Subject: [Ruby-activeldap-discuss] objectClass exclusions in ldap_mapping In-Reply-To: References: Message-ID: <20080108.220733.724796701716452407.kou@cozmixng.org> hi, In "[Ruby-activeldap-discuss] objectClass exclusions in ldap_mapping" on Tue, 8 Jan 2008 10:50:46 +1000, "Bodaniel Jeanes" wrote: > Is there a way to specify classes that you explicitly DON'T want as > part of the Base subclass? No. > My LdapUser class' ldap_mapping classes option specifies "top", > "person", and "user". Is there a way to make it exclude objects of > class "computer"? There isn't a convenience way but the following code may work: User.find(:all, :filter => "(objectClass~=computer)") Thanks, -- kou From me at bjeanes.com Wed Jan 9 19:20:29 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 10 Jan 2008 10:20:29 +1000 Subject: [Ruby-activeldap-discuss] dropped connection in rails app Message-ID: Hello again, I've got a beautiful staff directory riding upon the activeldap library, complete with links to manager's and subordinates pages and I am about 2 steps away from having staff photos be viewed. However there seems to be a problem with the library: If I don't view a page that uses LDAP for more than about 5-10 minutes, all of a sudden it stops working. Base.connected? still returns true but every operation just returns nil or an empty array, and behaves like there were no results. The same thing happens in irb if I run a command that returns a Base subclass object or an array of them, wait 10 minutes, then run it again, I just get back []. Again, connected? returns true still. The connection timing out but the framework isn't correctly identifying the fact and re-establishing the connection? If i manually call establish_connection before an operation, it seems to work, but it also seems to take an extra 5-6 seconds for the page to load. If connected? behaved like I think it should (perhaps i misunderstand it's purpose) then i could do something like establish_connection if not connected? As it stands, on some pages I need to do a few queries to get all the information I need (fetch associated users for a list of people in the same department, for example) so it ends up forcefully calling establish_connection 3-4 times. To get around that I have to do: if not @@connected establish_connection @@connected = true end before running the find command. Thoughts? From kou at cozmixng.org Wed Jan 9 23:41:27 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 10 Jan 2008 13:41:27 +0900 Subject: [Ruby-activeldap-discuss] dropped connection in rails app In-Reply-To: References: Message-ID: Hi, 2008/1/10, Bodaniel Jeanes : > Again, connected? returns true still. The connection timing out but > the framework isn't correctly identifying the fact and re-establishing > the connection? In the trunk, auto-reconnection should work well. Thanks, -- kou From me at bjeanes.com Thu Jan 10 00:13:04 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 10 Jan 2008 15:13:04 +1000 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: Message-ID: I forgot to mention. I upgraded to trunk 5 minutes before starting to write that to be sure. The problem persists. Perhaps it's an active directory issue... On that note, saving does not work with active directory (without even changing any attributes): RangeError: bignum too big to convert into `long' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/time.rb:184:in `local' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/time.rb:184:in `make_time' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/time.rb:243:in `parse' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/schema/syntaxes.rb:172:in `type_cast' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/schema.rb:316:in `type_cast' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/schema.rb:447:in `send' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/schema.rb:447:in `send_to_syntax' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/schema.rb:402:in `type_cast' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/base.rb:1008:in `type_cast' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/base.rb:1005:in `type_cast' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/base.rb:1004:in `collect' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/base.rb:1004:in `type_cast' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/base.rb:992:in `get_attribute' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/base.rb:748:in `[]' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/validations.rb:128:in `validate_ldap_values' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/validations.rb:127:in `each' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/validations.rb:127:in `validate_ldap_values' On 1/10/08, Kouhei Sutou wrote: > Hi, > > 2008/1/10, Bodaniel Jeanes : > > > Again, connected? returns true still. The connection timing out but > > the framework isn't correctly identifying the fact and re-establishing > > the connection? > > In the trunk, auto-reconnection should work well. > > Thanks, > -- > kou > _______________________________________________ > Ruby-activeldap-discuss mailing list > Ruby-activeldap-discuss at rubyforge.org > http://rubyforge.org/mailman/listinfo/ruby-activeldap-discuss > From kou at cozmixng.org Thu Jan 10 07:48:46 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 10 Jan 2008 21:48:46 +0900 (JST) Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: Message-ID: <20080110.214846.5295189865763785.kou@cozmixng.org> Hi, In "[Ruby-activeldap-discuss] Fwd: dropped connection in rails app" on Thu, 10 Jan 2008 15:13:04 +1000, "Bodaniel Jeanes" wrote: > I forgot to mention. I upgraded to trunk 5 minutes before starting to > write that to be sure. The problem persists. Perhaps it's an active > directory issue... > > On that note, saving does not work with active directory (without even > changing any attributes): Could you identify a value that causes an exception? You can use the following ways: p entry.attributes or class ActiveLdap::Schema::Syntaxes::GeneralizedTime alias_method(:_type_cast, :type_cast) def type_cast(value) p value _type_cast(value) end end entry.save Thanks, -- kou From me at bjeanes.com Fri Jan 11 01:49:07 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Fri, 11 Jan 2008 16:49:07 +1000 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: <20080110.214846.5295189865763785.kou@cozmixng.org> References: <20080110.214846.5295189865763785.kou@cozmixng.org> Message-ID: > Could you identify a value that causes an exception? > > class ActiveLdap::Schema::Syntaxes::GeneralizedTime > alias_method(:_type_cast, :type_cast) > def type_cast(value) > p value > _type_cast(value) > end > end > entry.save ?> class ActiveLdap::Schema::Syntaxes::GeneralizedTime >> alias_method(:_type_cast, :type_cast) >> def type_cast(value) >> p value >> _type_cast(value) >> end >> end => nil >> entry.save "20080107034615.0Z" RangeError: bignum too big to convert into `long' #...etc Autoreconnect still has problems in trunk. Thanks, Bodaniel Jeanes From me at bjeanes.com Fri Jan 11 02:21:02 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Fri, 11 Jan 2008 17:21:02 +1000 Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations Message-ID: I have been trying to figure out a way to cache ActiveLdap requests effectively, recently. Pulling a staff directory of 300 users takes 11-12 seconds -- longer if it has to reconnect. I was thinking of hacking into the framework so that at a lower level it will use a memcached server to cache entire arrays of results based on a given filter + current date. Caching individual requests (like finding by a unique value) should be easy enough, but those aren't the ones that take the longest. Kouhei, have you done any benchmarking to determine what parts of the code are the slowest? Is it the connection to the directory and waiting for the results or something that can be tweaked, such as the time it takes to parse the information? In my efforts to speed up searches, i've gotten into the habit of only requesting attributes that will be needed for that request, and not ALL attributes. I think it has made a bit of a difference, but I notice that EACH entry object still contains a massive hash, @attribute_aliases, which not only holds aliases for all the attributes i don't need, but is repeated in EACH object. With this in mind I have a few suggestions (if [some of] these changes are impossible, excuse my ignorance into the deeper operation of the framework): 1) could this not be a class variable, hence shared between all objects instead of being an instance variable and using additional resources (not to mention inspecting entries in irb would be so much nicer) 2) is it not possible to only have the attributes that were requested (assuming it has to stay an instance variable) in the find/search operation 3) 75% of the aliases in the hash are IDENTICAL to the real attribute names, and those that ARE different are usually just underscored equivalents (displayName -> display_name) which I am sure can be programmatically converted on the fly. This means the hash would be reserved for those rare cases (such as "msIIS-FTPRoot") where working it out doesn't make sense. something equivalent to the String#underscore and String#camelize (with lowercase first letter) that rails adds would handle most of these needs. So when someone does something like some_user_object.display_name, method_missing first camelizes it (except for first letter), and checks if it's a valid attribute, if not it checks the hash, and finally raises an exception if neither of those return a valid attribute either because the attribute wasn't requested in the bind (so for all intensive purposes, shouldn't exist) or because it isn't a real attribute 4) agree upon a reasonable set of default "sane" attributes to return, instead of ALL of them, because 99% of the time you don't need every attribute, in fact most of the time you might not need more than 10-12. Something like {:attributes => :all} could always be used to restore original functionality. My recommendation for sane values would include ones do to with personal information (phone numbers, emails, names, titles, addresses, etc) + accounting ones (uids, sAMAccountName, whatever), then probably things like manager, groups, parent OU. Anything that is not a DN (of other objects, such as groups/managers) and is not a short string value should be ignored (things like msExchMailboxSecurityDescriptor, userCertificate, and other binary attributes). In short, a measure of effectiveness of the above would be how the object looks in irb. at the moment, it's several screens full of mostly useless data or jibberish. Whereas something like ActiveRecord merely shows you the data and perhaps an @errors hash. For example, a MSSQL object: => # Ldap entries should just show you what you asked for, else a reasonable default set of useful attributes. I know this was lengthy but the thought of ActiveLdap as I have described is so unbelievably appealing. Of course, these are a lot of recommendations, but i'd be willing to help out on some of these (especially the reworking of @attribute_aliases) to see this library be what it truly can be! Thanks a lot for this project guys! Bo From me at bjeanes.com Fri Jan 11 02:32:11 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Fri, 11 Jan 2008 17:32:11 +1000 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: <20080110.214846.5295189865763785.kou@cozmixng.org> Message-ID: > ?> class ActiveLdap::Schema::Syntaxes::GeneralizedTime > >> alias_method(:_type_cast, :type_cast) > >> def type_cast(value) > >> p value > >> _type_cast(value) > >> end > >> end > => nil > >> entry.save > "20080107034615.0Z" > RangeError: bignum too big to convert into `long' > #...etc errors: !ruby/object:ActiveRecord::Errors base: *id291 errors: nTSecurityDescriptor: - is required attribute by objectClass 'top' - is required attribute by objectClass 'person' - is required attribute by objectClass 'organizationalPerson' - is required attribute by objectClass 'user' I noticed that also after trying to save the above was in the @errors variable. Converted to yaml for readability but thought it might also be useful From kou at cozmixng.org Sun Jan 13 07:09:11 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Sun, 13 Jan 2008 21:09:11 +0900 (JST) Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: <20080110.214846.5295189865763785.kou@cozmixng.org> Message-ID: <20080113.210911.1062576197951488437.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app" on Fri, 11 Jan 2008 16:49:07 +1000, "Bodaniel Jeanes" wrote: > > Could you identify a value that causes an exception? > > > > class ActiveLdap::Schema::Syntaxes::GeneralizedTime > > alias_method(:_type_cast, :type_cast) > > def type_cast(value) > > p value > > _type_cast(value) > > end > > end > > entry.save > > ?> class ActiveLdap::Schema::Syntaxes::GeneralizedTime > >> alias_method(:_type_cast, :type_cast) > >> def type_cast(value) > >> p value > >> _type_cast(value) > >> end > >> end > => nil > >> entry.save > "20080107034615.0Z" > RangeError: bignum too big to convert into `long' > #...etc Thanks. I've fixed this in trunk. -- kou From me at bjeanes.com Sun Jan 13 07:11:08 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Sun, 13 Jan 2008 22:11:08 +1000 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: <20080113.210911.1062576197951488437.kou@cozmixng.org> References: <20080110.214846.5295189865763785.kou@cozmixng.org> <20080113.210911.1062576197951488437.kou@cozmixng.org> Message-ID: I'll do a test save tomorrow at work and let you know how it goes. On 1/13/08, Kouhei Sutou wrote: > Hi, > > In > "Re: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app" on Fri, 11 Jan 2008 16:49:07 +1000, > "Bodaniel Jeanes" wrote: > > > > Could you identify a value that causes an exception? > > > > > > class ActiveLdap::Schema::Syntaxes::GeneralizedTime > > > alias_method(:_type_cast, :type_cast) > > > def type_cast(value) > > > p value > > > _type_cast(value) > > > end > > > end > > > entry.save > > > > ?> class ActiveLdap::Schema::Syntaxes::GeneralizedTime > > >> alias_method(:_type_cast, :type_cast) > > >> def type_cast(value) > > >> p value > > >> _type_cast(value) > > >> end > > >> end > > => nil > > >> entry.save > > "20080107034615.0Z" > > RangeError: bignum too big to convert into `long' > > #...etc > > Thanks. > I've fixed this in trunk. > > > -- > kou > _______________________________________________ > Ruby-activeldap-discuss mailing list > Ruby-activeldap-discuss at rubyforge.org > http://rubyforge.org/mailman/listinfo/ruby-activeldap-discuss > From kou at cozmixng.org Sun Jan 13 08:33:00 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Sun, 13 Jan 2008 22:33:00 +0900 (JST) Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: References: Message-ID: <20080113.223300.806728267042418653.kou@cozmixng.org> Hi, In "[Ruby-activeldap-discuss] Thoughts on speed optimizations" on Fri, 11 Jan 2008 17:21:02 +1000, "Bodaniel Jeanes" wrote: > Kouhei, have you done any benchmarking to determine what parts of the > code are the slowest? Is it the connection to the directory and > waiting for the results or something that can be tweaked, such as the > time it takes to parse the information? There is a benchmark script benchmark/bench-al.rb. % ruby benchmark/bench-al.rb --config benchmark/config.yaml Populating... user system total real 1x: AL 0.340000 0.000000 0.340000 ( 0.378149) 1x: AL(No Obj) 0.030000 0.000000 0.030000 ( 0.044548) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003031) 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.070763) Entries processed by Ruby/ActiveLdap: 100 Entries processed by Ruby/ActiveLdap (without object creation): 100 Entries processed by Ruby/LDAP: 100 Entries processed by Net::LDAP: 100 Cleaning... AL <-> AL(No Obj) shows that instantiation (find family) is 10x slower rather than search only operation (search). And AL(No Obj) <-> LDAP shows that ActiveLdap's backend abstraction layer is 10x slower rather than direct LDAP access. > In my efforts to speed up searches, i've gotten into the habit of only > requesting attributes that will be needed for that request, and not > ALL attributes. I think it has made a bit of a difference, but I > notice that EACH entry object still contains a massive hash, > @attribute_aliases, which not only holds aliases for all the > attributes i don't need, but is repeated in EACH object. > > With this in mind I have a few suggestions (if [some of] these changes > are impossible, excuse my ignorance into the deeper operation of the > framework): > > 1) could this not be a class variable, hence shared between all > objects instead of being an instance variable and using additional > resources (not to mention inspecting entries in irb would be so much > nicer) Each instance may have different objectClass even if they is belongs to same class. So, we can't move it to class level simply. But we may use other solution. We may use cache it into a Hash with objectClass set key. > 2) is it not possible to only have the attributes that were requested > (assuming it has to stay an instance variable) in the find/search > operation Do you say about attribute value? If so, the current work is that. > 3) 75% of the aliases in the hash are IDENTICAL to the real attribute > names, and those that ARE different are usually just underscored > equivalents (displayName -> display_name) which I am sure can be > programmatically converted on the fly. This means the hash would be > reserved for those rare cases (such as "msIIS-FTPRoot") where working > it out doesn't make sense. something equivalent to the > String#underscore and String#camelize (with lowercase first letter) > that rails adds would handle most of these needs. > > So when someone does something like some_user_object.display_name, > method_missing first camelizes it (except for first letter), and > checks if it's a valid attribute, if not it checks the hash, and > finally raises an exception if neither of those return a valid > attribute either because the attribute wasn't requested in the bind > (so for all intensive purposes, shouldn't exist) or because it isn't a > real attribute There are many LDAP name <-> Rubyish name conversion and codes that uses available name list like #methods. So I chose name caching instead of on the flay. We need to measure speed to decide how way is the best. > 4) agree upon a reasonable set of default "sane" attributes to return, > instead of ALL of them, because 99% of the time you don't need every > attribute, in fact most of the time you might not need more than > 10-12. Something like {:attributes => :all} could always be used to > restore original functionality. It may be true but I don't know about that until we do some benchmark. > In short, a measure of effectiveness of the above would be how the > object looks in irb. I think this isn't fair. IO cost may be too big. > object looks in irb. at the moment, it's several screens full of > mostly useless data or jibberish. Whereas something like ActiveRecord > merely shows you the data and perhaps an @errors hash. For example, a > MSSQL object: > > => # "###########", signedIn: true, disabled: false> > > Ldap entries should just show you what you asked for, else a > reasonable default set of useful attributes. This is easy. We just re-defined inspect. For now, some information are hidden from inspect. Thanks, -- kou From me at bjeanes.com Sun Jan 13 17:21:24 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Mon, 14 Jan 2008 08:21:24 +1000 Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: <20080113.223300.806728267042418653.kou@cozmixng.org> References: <20080113.223300.806728267042418653.kou@cozmixng.org> Message-ID: > AL <-> AL(No Obj) shows that instantiation (find family) is > 10x slower rather than search only operation (search). And > AL(No Obj) <-> LDAP shows that ActiveLdap's backend > abstraction layer is 10x slower rather than direct LDAP > access. Wow that's pretty intense. The object creation is what I expected would take the longest since it's processing a decent amount of data for each object. That's why my earlier blabbering was my attempt to find how some of that object processing could be modified to be more intelligent such that attributes are parsed as they are needed or something. > Each instance may have different objectClass even if they is > belongs to same class. So, we can't move it to class level > simply. But we may use other solution. We may use > cache it into a Hash with objectClass set key. I realized the objectClass problem after I sent that. Caching would certainly be a brilliant idea as it would cut out extraneous schema parsing such that it only ran once. > > 2) is it not possible to only have the attributes that were requested > > (assuming it has to stay an instance variable) in the find/search > > operation > > Do you say about attribute value? If so, the current work is > that. I don't understand. What i meant is if you did a find where your options[:attributes] was set to something like ["sAMAccountName", "displayName", "ipPhone"], then whatever happens to setup the objectClasses schema and represent in the object can simply skip processing of everything except those attributes. > There are many LDAP name <-> Rubyish name conversion and > codes that uses available name list like #methods. So I > chose name caching instead of on the flay. We need to > measure speed to decide how way is the best. I see, i just think that at least if we could find a way to ignore unneeded attributes (especially if a default set can be presented as per below). > > 4) agree upon a reasonable set of default "sane" attributes to return, > > instead of ALL of them, because 99% of the time you don't need every > > attribute, in fact most of the time you might not need more than > > 10-12. Something like {:attributes => :all} could always be used to > > restore original functionality. > > It may be true but I don't know about that until we do some > benchmark. I am thinking not only of speed performance but resource usage. There is simply a *lot* of data in an ldap node. > I think this isn't fair. IO cost may be too big. Sorry you are right. Don't get me wrong, i LOVE ruby-activeldap so a lot of this is just blabbering as I think of things. > This is easy. We just re-defined inspect. > For now, some information are hidden from inspect. True, I think this is a good idea. I don't think think anything except the attribute=>value should be returned, and only for the attributes that were requested. Thanks From kou at cozmixng.org Mon Jan 14 09:10:04 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Mon, 14 Jan 2008 23:10:04 +0900 (JST) Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: <20080113.223300.806728267042418653.kou@cozmixng.org> References: <20080113.223300.806728267042418653.kou@cozmixng.org> Message-ID: <20080114.231004.1068217702134201150.kou@cozmixng.org> > There is a benchmark script benchmark/bench-al.rb. > > % ruby benchmark/bench-al.rb --config benchmark/config.yaml > Populating... > user system total real > 1x: AL 0.340000 0.000000 0.340000 ( 0.378149) > 1x: AL(No Obj) 0.030000 0.000000 0.030000 ( 0.044548) > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003031) > 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.070763) > Entries processed by Ruby/ActiveLdap: 100 > Entries processed by Ruby/ActiveLdap (without object creation): 100 > Entries processed by Ruby/LDAP: 100 > Entries processed by Net::LDAP: 100 > Cleaning... The current result: % ruby benchmark/bench-al.rb --config benchmark/config.yaml Populating... Rehearsal ------------------------------------------------------- 1x: AL 0.160000 0.020000 0.180000 ( 0.199191) 1x: AL(No Obj) 0.010000 0.000000 0.010000 ( 0.015404) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003221) 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.060900) ---------------------------------------------- total: 0.240000sec user system total real 1x: AL 0.130000 0.020000 0.150000 ( 0.156565) 1x: AL(No Obj) 0.020000 0.000000 0.020000 ( 0.020263) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003824) 1x: Net::LDAP 0.060000 0.010000 0.070000 ( 0.074886) Entries processed by Ruby/ActiveLdap: 100 Entries processed by Ruby/ActiveLdap (without object creation): 100 Entries processed by Ruby/LDAP: 100 Entries processed by Net::LDAP: 100 Cleaning... -- kou From me at bjeanes.com Mon Jan 14 15:49:37 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 06:49:37 +1000 Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: <20080114.231004.1068217702134201150.kou@cozmixng.org> References: <20080113.223300.806728267042418653.kou@cozmixng.org> <20080114.231004.1068217702134201150.kou@cozmixng.org> Message-ID: > > % ruby benchmark/bench-al.rb --config benchmark/config.yaml > > Populating... > > user system total real > > 1x: AL 0.340000 0.000000 0.340000 ( 0.378149) > > 1x: AL(No Obj) 0.030000 0.000000 0.030000 ( 0.044548) > > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003031) > > 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.070763) > > Entries processed by Ruby/ActiveLdap: 100 > > Entries processed by Ruby/ActiveLdap (without object creation): 100 > > Entries processed by Ruby/LDAP: 100 > > Entries processed by Net::LDAP: 100 > > Cleaning... > > The current result: > > % ruby benchmark/bench-al.rb --config benchmark/config.yaml > Populating... > Rehearsal ------------------------------------------------------- > 1x: AL 0.160000 0.020000 0.180000 ( 0.199191) > 1x: AL(No Obj) 0.010000 0.000000 0.010000 ( 0.015404) > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003221) > 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.060900) > ---------------------------------------------- total: 0.240000sec > > user system total real > 1x: AL 0.130000 0.020000 0.150000 ( 0.156565) > 1x: AL(No Obj) 0.020000 0.000000 0.020000 ( 0.020263) > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003824) > 1x: Net::LDAP 0.060000 0.010000 0.070000 ( 0.074886) > Entries processed by Ruby/ActiveLdap: 100 > Entries processed by Ruby/ActiveLdap (without object creation): 100 > Entries processed by Ruby/LDAP: 100 > Entries processed by Net::LDAP: 100 Excellent work! What did you change to make such a difference. That's just under half the speed. :-)!! From me at bjeanes.com Mon Jan 14 23:47:48 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 14:47:48 +1000 Subject: [Ruby-activeldap-discuss] Rails plugin tweak Message-ID: I recommend changing the first line of init.rb in the rails plugin to: require_library_or_gem 'active_ldap' unless defined?(ActiveLdap::VERSION) Thanks, Bo From me at bjeanes.com Tue Jan 15 00:22:17 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 15:22:17 +1000 Subject: [Ruby-activeldap-discuss] Reconnect issues and :attributes issues Message-ID: Kouhei, I remember you saying that the auto reconnect should be working much better in trunk. I upgraded to the latest trunk today and found that the if the rails site or an irb console using Base subclasses isn't used for several minutes, empty result sets are returned. The only way i can remedy this issue is overriding the find method and doing something like: r = super(mode, opts) if r.nil? or (r.is_a? Array and r.empty?) # sometimes it thinks there's no results but really no connection establish_connection r = super(mode, opts) end r Also I mentioned this in another post -- if you specify attributes to be returned, ActiveLdap throws an exception if you don't include "objectClass" as an attribute. Since it seems to be required in all circumstances, why not always ensure that objectClass is present in the attributes array. Thanks for your ongoing work. From kou at cozmixng.org Tue Jan 15 05:32:24 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 15 Jan 2008 19:32:24 +0900 (JST) Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: <20080114.231004.1068217702134201150.kou@cozmixng.org> References: <20080113.223300.806728267042418653.kou@cozmixng.org> <20080114.231004.1068217702134201150.kou@cozmixng.org> Message-ID: <20080115.193224.756400480747503619.kou@cozmixng.org> Hi, In <20080114.231004.1068217702134201150.kou at cozmixng.org> "Re: [Ruby-activeldap-discuss] Thoughts on speed optimizations" on Mon, 14 Jan 2008 23:10:04 +0900 (JST), Kouhei Sutou wrote: > > There is a benchmark script benchmark/bench-al.rb. > > > > % ruby benchmark/bench-al.rb --config benchmark/config.yaml > > Populating... > > user system total real > > 1x: AL 0.340000 0.000000 0.340000 ( 0.378149) > > 1x: AL(No Obj) 0.030000 0.000000 0.030000 ( 0.044548) > > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003031) > > 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.070763) > > Entries processed by Ruby/ActiveLdap: 100 > > Entries processed by Ruby/ActiveLdap (without object creation): 100 > > Entries processed by Ruby/LDAP: 100 > > Entries processed by Net::LDAP: 100 > > Cleaning... > > The current result: > > % ruby benchmark/bench-al.rb --config benchmark/config.yaml > Populating... > Rehearsal ------------------------------------------------------- > 1x: AL 0.160000 0.020000 0.180000 ( 0.199191) > 1x: AL(No Obj) 0.010000 0.000000 0.010000 ( 0.015404) > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003221) > 1x: Net::LDAP 0.040000 0.010000 0.050000 ( 0.060900) > ---------------------------------------------- total: 0.240000sec > > user system total real > 1x: AL 0.130000 0.020000 0.150000 ( 0.156565) > 1x: AL(No Obj) 0.020000 0.000000 0.020000 ( 0.020263) > 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003824) > 1x: Net::LDAP 0.060000 0.010000 0.070000 ( 0.074886) > Entries processed by Ruby/ActiveLdap: 100 > Entries processed by Ruby/ActiveLdap (without object creation): 100 > Entries processed by Ruby/LDAP: 100 > Entries processed by Net::LDAP: 100 > Cleaning... And now: % ruby benchmark/bench-al.rb --config benchmark/config.yaml Populating... Rehearsal ------------------------------------------------------- 1x: AL 0.090000 0.000000 0.090000 ( 0.114157) 1x: AL(No Obj) 0.010000 0.000000 0.010000 ( 0.015025) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.002718) 1x: Net::LDAP 0.050000 0.000000 0.050000 ( 0.066982) ---------------------------------------------- total: 0.150000sec user system total real 1x: AL 0.080000 0.020000 0.100000 ( 0.105487) 1x: AL(No Obj) 0.010000 0.000000 0.010000 ( 0.019393) 1x: LDAP 0.000000 0.000000 0.000000 ( 0.003786) 1x: Net::LDAP 0.030000 0.010000 0.040000 ( 0.048660) Entries processed by Ruby/ActiveLdap: 100 Entries processed by Ruby/ActiveLdap (without object creation): 100 Entries processed by Ruby/LDAP: 100 Entries processed by Net::LDAP: 100 Cleaning... Is it good enough for now? Thanks, -- kou From kou at cozmixng.org Tue Jan 15 05:33:25 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 15 Jan 2008 19:33:25 +0900 (JST) Subject: [Ruby-activeldap-discuss] Rails plugin tweak In-Reply-To: References: Message-ID: <20080115.193325.43095368952716902.kou@cozmixng.org> HI, > I recommend changing the first line of init.rb in the rails plugin to: > > require_library_or_gem 'active_ldap' unless defined?(ActiveLdap::VERSION) Why? Could you explain (with your code?) your situation? Thanks, -- kou From kou at cozmixng.org Tue Jan 15 05:41:11 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 15 Jan 2008 19:41:11 +0900 (JST) Subject: [Ruby-activeldap-discuss] Reconnect issues and :attributes issues In-Reply-To: References: Message-ID: <20080115.194111.562675606692617125.kou@cozmixng.org> Hi, In "[Ruby-activeldap-discuss] Reconnect issues and :attributes issues" on Tue, 15 Jan 2008 15:22:17 +1000, "Bodaniel Jeanes" wrote: > I remember you saying that the auto reconnect should be working much > better in trunk. I upgraded to the latest trunk today and found that > the if the rails site or an irb console using Base subclasses isn't > used for several minutes, empty result sets are returned. It works on my environment, OpenLDAP server and Ruby/LDAP backend on Debian GNU/Linux sid. Ruby/LDAP on my environment set error code (LDAP::Conn.err) when search is failed by losing remote server connection. I will not debug this problem on your environment. :< If you solve the problem and patch is sent to me, I'll apply it. > Also I mentioned this in another post -- if you specify attributes to > be returned, ActiveLdap throws an exception if you don't include > "objectClass" as an attribute. Since it seems to be required in all > circumstances, why not always ensure that objectClass is present in > the attributes array. That has been solved in trunk. Thanks, -- kou From kou at cozmixng.org Tue Jan 15 05:50:46 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 15 Jan 2008 19:50:46 +0900 (JST) Subject: [Ruby-activeldap-discuss] [API CHANGE] {"binary" => "..."} -> "..." Message-ID: <20080115.195046.489856247069218717.kou@cozmixng.org> Hi, I spent a few days to improve speed. One of the effects is that ActiveLdap doesn't convert passed value on set_attribute. ActiveLdap had converted passed value to internal data format before the effect. e.g.: before: user.user_certificate = "..." user.user_certificate # => {"binary" => "..."} But now, ActiveLdap only do the conversion on save. now: user.user_certificate = "..." user.user_certificate # => "..." There is a problem. In the conversion rule, we will get inconsistent behavior to use attribute value. user.user_certificate = "..." user.user_certificate # => "..." user.user_certificate = {"binary" => "..."} user.user_certificate # => {"binary" => "..."} We need to check the value is a Hash or not. So ActiveLdap always removes {"binary" => ...} from attribute value: user.user_certificate = "..." user.user_certificate # => "..." user.user_certificate = {"binary" => "..."} user.user_certificate # => "..." But this causes API break. Is it OK? Thanks, -- kou From me at bjeanes.com Tue Jan 15 06:52:04 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 21:52:04 +1000 Subject: [Ruby-activeldap-discuss] Rails plugin tweak In-Reply-To: <20080115.193325.43095368952716902.kou@cozmixng.org> References: <20080115.193325.43095368952716902.kou@cozmixng.org> Message-ID: Yes. My project is in svn and i set activeldap lib folder as an external in my lib directory. The require_library_or_gem doesn't find it there (since it has to be put into a subdirectory of lib for the external to work) so the options are to modify the require manually (which is needed after every update of the rails plugin [also externaled]) or to manually include activeldap in environment.rb That line just takes into account any situation such as mine where the library might have been included earlier for any reason. Truth be told i probably don't need the rails plugin installed anyway so it's not that important. Just thought it might be nice. From me at bjeanes.com Tue Jan 15 06:52:43 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 21:52:43 +1000 Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: <20080115.193224.756400480747503619.kou@cozmixng.org> References: <20080113.223300.806728267042418653.kou@cozmixng.org> <20080114.231004.1068217702134201150.kou@cozmixng.org> <20080115.193224.756400480747503619.kou@cozmixng.org> Message-ID: > Is it good enough for now? holy bleep that's fantastic work. The more optimization the better but almost quadrupling the speed is a stunning difference for a few rounds of refactoring. I am truly impressed. I am still curious to know what change made such a large difference... From me at bjeanes.com Tue Jan 15 06:56:43 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 21:56:43 +1000 Subject: [Ruby-activeldap-discuss] Reconnect issues and :attributes issues In-Reply-To: <20080115.194111.562675606692617125.kou@cozmixng.org> References: <20080115.194111.562675606692617125.kou@cozmixng.org> Message-ID: > I will not debug this problem on your environment. :< If you solve the > problem and patch is sent to me, I'll apply it. Fair enough. If i figure out what causes it I will do that. For now my conditional does the job. For reference by development environment is Active Directory server, Ruby/LDAP backend on Mac OS X 10.5.1. I have not tested on my gentoo based production environment (same server and backend). > That has been solved in trunk. I am on trunk. In fact it was working without objectClass then when i upgraded to trunk about 12 hours ago, the exception reappeared. I'll do another update tomorrow to be sure From kou at cozmixng.org Tue Jan 15 07:00:45 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 15 Jan 2008 21:00:45 +0900 (JST) Subject: [Ruby-activeldap-discuss] Rails plugin tweak In-Reply-To: References: <20080115.193325.43095368952716902.kou@cozmixng.org> Message-ID: <20080115.210045.511077586483172777.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Rails plugin tweak" on Tue, 15 Jan 2008 21:52:04 +1000, "Bodaniel Jeanes" wrote: > Yes. My project is in svn and i set activeldap lib folder as an > external in my lib directory. The require_library_or_gem doesn't find > it there (since it has to be put into a subdirectory of lib for the > external to work) so the options are to modify the require manually > (which is needed after every update of the rails plugin [also > externaled]) or to manually include activeldap in environment.rb What about config.load_paths in config/environment? examples/al-admin/ uses config.load_paths to load ActiveLdap in lib/. Thanks, -- kou From kou at cozmixng.org Tue Jan 15 07:02:28 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Tue, 15 Jan 2008 21:02:28 +0900 (JST) Subject: [Ruby-activeldap-discuss] Thoughts on speed optimizations In-Reply-To: References: <20080114.231004.1068217702134201150.kou@cozmixng.org> <20080115.193224.756400480747503619.kou@cozmixng.org> Message-ID: <20080115.210228.346567984674197855.kou@cozmixng.org> Hi, In "Re: [Ruby-activeldap-discuss] Thoughts on speed optimizations" on Tue, 15 Jan 2008 21:52:43 +1000, "Bodaniel Jeanes" wrote: > I am still curious to know what change made such a large difference... You can see Subversion repository. They are all there. Thanks, -- kou From me at bjeanes.com Tue Jan 15 07:27:05 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Tue, 15 Jan 2008 22:27:05 +1000 Subject: [Ruby-activeldap-discuss] Rails plugin tweak In-Reply-To: <20080115.210045.511077586483172777.kou@cozmixng.org> References: <20080115.193325.43095368952716902.kou@cozmixng.org> <20080115.210045.511077586483172777.kou@cozmixng.org> Message-ID: > What about config.load_paths in config/environment? > examples/al-admin/ uses config.load_paths to load ActiveLdap > in lib/. Thank you I'll just do that. the unless defined? method is just what i was using internally so i thought I'd share From gcowsar at gmail.com Wed Jan 16 17:58:15 2008 From: gcowsar at gmail.com (George Cowsar) Date: Wed, 16 Jan 2008 16:58:15 -0600 Subject: [Ruby-activeldap-discuss] accessing modifyTimestamp Message-ID: Is there a way to access the modifyTimestamp or modifiersName attributes? thanks, George From me at bjeanes.com Wed Jan 16 18:12:22 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 09:12:22 +1000 Subject: [Ruby-activeldap-discuss] Timeout vs. Timeout_stub Message-ID: I noticed in the source there is the following: if RUBY_PLATFORM.match('linux') require 'active_ldap/timeout' else require 'active_ldap/timeout_stub' end I assume it's presence is to provide some degree of Windows compatibility with all the forking and such. However I think the condition could be modified to be: if RUBY_PLATFORM.match('linux') or RUBY_PLATFORM.match('darwin') RUBY_PLATFORM returns something along the lines of 'universal-darwin9.0' on OS X. I am not sure about the universal and 9.0 parts, but darwin would always be consistent. Considering under OS X's hood lies a unix core, I would think the timeout.rb code should work fine. If you have tested this and know it to be wrong then ignore this, otherwise i can test it (would it just fail to start, or is there some particular functionality I could look out for?). Thank you, Bodaniel Jeanes From kou at cozmixng.org Wed Jan 16 18:55:42 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 08:55:42 +0900 Subject: [Ruby-activeldap-discuss] accessing modifyTimestamp In-Reply-To: References: Message-ID: Hi, 2008/1/17, George Cowsar : > Is there a way to access the modifyTimestamp or modifiersName attributes? :attributes => ["*", "+"] find/search option will help you. Thanks, -- kou From me at bjeanes.com Wed Jan 16 19:09:57 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 10:09:57 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk Message-ID: Hi, I realized recently that while I thought I was running on trunk, I actually wasn't. When i moved active_ldap to an svn:externals folder, I included the main active_ldap.rb file and everything went along, what i didn't realize however was that the file actually then included the 0.9.0 gem (which although i had "gem uninstall"ed was still on my system oddly). Long story short, i am running trunk now and simple finds don't work. While I know the ordinary warnings for using trunk etc apply and I'll go back to 0.9.0 if necessary, I thought i should still share. In this pastie is the trace of the method missing error: http://pastie.caboo.se/private/llogdpeazcjyjkyo4moda I tried going into the framework for a little debugging and found that this error gets raised on many attributes but not all. homeMTA= is another one that gets raised. Any ideas? I really want to use trunk for the speed increases ^_^ Thanks, Bo From kou at cozmixng.org Wed Jan 16 19:56:45 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 09:56:45 +0900 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > Long story short, i am running trunk now and simple finds don't work. > While I know the ordinary warnings for using trunk etc apply and I'll > go back to 0.9.0 if necessary, I thought i should still share. > In this pastie is the trace of the method missing error: > > http://pastie.caboo.se/private/llogdpeazcjyjkyo4moda This has been fixed in the trunk now. Thanks, -- kou From me at bjeanes.com Wed Jan 16 20:13:57 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 11:13:57 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: > This has been fixed in the trunk now. Yup I just saw the commit message. Thanks a lot. Line 214 of operations.rb (return results if sort_by.nil? and order.nil?) should also return if results is not an array. I have a situation where it programmatically decides whether it should find :first or :all. When :first is provided, as well as a :sort_by it throws a method missing error. This is because find_initial relies on find_every I think, and find_every blindly tries to sort all results objects even if they can't be sorted. I have made my own code smarter to avoid it, but it's a simple change that might save someone else some woe later on. Thanks for the fix everything is working again! From kou at cozmixng.org Wed Jan 16 20:35:52 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 10:35:52 +0900 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > Line 214 of operations.rb (return results if sort_by.nil? and > order.nil?) should also return if results is not an array. I have a > situation where it programmatically decides whether it should find > :first or :all. When :first is provided, as well as a :sort_by it > throws a method missing error. This is because find_initial relies on > find_every I think, and find_every blindly tries to sort all results > objects even if they can't be sorted. search should returns an array. Could you show your sample code? Thanks, -- kou From me at bjeanes.com Wed Jan 16 21:01:27 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:01:27 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: > search should returns an array. Could you show your sample Well I have a wrapper around Base#find() to fix a few issues i had with default behaviour. For example, if a filter is supplied, :attribute and :value are ignored, so i manually build it. Also, I had issues using :sort_by in ldap_mapping (there was no indication that it even worked for me) so I also specify it in my wrapper. Basically I manually build up the :options i want. Here is the wrapper: class << self def find(mode, opts={}) #adding the unless to prevent a method missing error on :first searches unless mode == :first opts[:sort_by] ||= "displayName" opts[:order] ||= :asc end # rebuild attribute/value searching cuz it doesn't seem to work if a filter is # specified: attribute = opts.delete(:attribute) || "cn" value = opts.delete(:value) || "*" opts[:filter] ||= "(#{attribute}=#{value})" # specify objectCategory because in AD all the Computers # are also objectClass of user. until exclude_class is added # specifying an objectCategory on all searches to filter out computers opts[:filter] << "(objectCategory=person)" # Don't fetch disabled users opts[:filter] << "(!(userAccountControl:1.2.840.113556.1.4.803:=2))" # Let's see the filter used logger.debug opts[:filter] # execute find super(mode, opts) end end If I comment out the "unless mode == :first" section and run LdapUser.find(:first) i get: >> LdapUser.find(:first) NoMethodError: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.<=> from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:220:in `sort_by' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:220:in `find_every' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:189:in `find_initial' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:178:in `find' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/app/models/ldap_user.rb:131:in `find' from (irb):1 I took out my function entirely and ran a raw find with :first and a :sort_by option and it stil resulted in the error: >> LdapUser.find(:first, :sort_by => "displayName", :order => :asc) # same trace I realize sort_by doesn't make sense in the context of a :first search because in activeldap the sorting happens AFTER the results are fetched. Though really the results should be sorted and then the first "row" the resultset should be returned (much slower unless the sorting can be done server side, i know) similar to an sql query with a LIMIT and an ORDER BY. Speaking of which, doesn't LDAP provide means to specify the sorting as part of the query, so that the server handles the sorting? I am fairly sure it does. From me at bjeanes.com Wed Jan 16 21:10:27 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:10:27 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: As a follow up to that post, I just did the following check in trunk... I took out my sort_by stuff in my overridden find method and put it back in ldap_mapping. Sort still does not work when specified in ldap_mapping. Perhaps this is related to specifying a filter/other options in the same way that specifying a filter stops :attribute and :value from being used? From me at bjeanes.com Wed Jan 16 21:24:51 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:24:51 +1000 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: <20080110.214846.5295189865763785.kou@cozmixng.org> <20080113.210911.1062576197951488437.kou@cozmixng.org> Message-ID: > > I've fixed this in trunk. >> pl.class LdapUser # subclass of ActiveLdap::Base >> pk.title => "Project Manager" >> pk.title << "!" => "Project Manager!" >> pk.save SystemStackError: stack level too deep from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:322:in `callback' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/callbacks.rb:20:in `callback' from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:270:in `valid_without_callbacks?' from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:273:in `valid?' from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/validations.rb:933:in `save' from (irb):18 from :0 From kou at cozmixng.org Wed Jan 16 21:34:14 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 11:34:14 +0900 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > Well I have a wrapper around Base#find() to fix a few issues i had > with default behaviour. For example, if a filter is supplied, > :attribute and :value are ignored, so i manually build it. :attribute and :value is for convenience. If you want to use :filter, you do all what you want to do is in :filter. > I took out my function entirely and ran a raw find with :first and a > :sort_by option and it stil resulted in the error: > > >> LdapUser.find(:first, :sort_by => "displayName", :order => :asc) > # same trace It seems that some of your ldap users doesn't have displayName. > I realize sort_by doesn't make sense in the context of a :first search > because in activeldap the sorting happens AFTER the results are > fetched. Though really the results should be sorted and then the first > "row" the resultset should be returned (much slower unless the sorting > can be done server side, i know) similar to an sql query with a LIMIT > and an ORDER BY. > > Speaking of which, doesn't LDAP provide means to specify the sorting > as part of the query, so that the server handles the sorting? I am > fairly sure it does. Do you know a way how to sort on LDAP server? From me at bjeanes.com Wed Jan 16 21:35:38 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:35:38 +1000 Subject: [Ruby-activeldap-discuss] ArgumentError: Anonymous modules have no name to be referenced by Message-ID: Hi, Have a strange issue popping up now and just wondering if anyone else has seen this. In my rails application (development mode), the first page request that involves activeldap goes off without a hitch. Every subsequent request however, I get ArgumentError: Anonymous modules have no name to be referenced by Similarly in irb, the first time i do something like LdapUser.find(...) I get results normally. If I then do a reload! and try running that line again I get the same error raised. The only way to stop getting the request is to restart the server or console. None of this occurs in production environment so it distinctly has something to do with reloading the files. This started when I upgraded to latest trunk. The trace is below: ArgumentError: Anonymous modules have no name to be referenced by from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:402:in `to_constant_name' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:214:in `qualified_name_for' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:477:in `const_missing' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/get_text_support.rb:20:in `included' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/get_text_support.rb:19:in `class_eval' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/get_text_support.rb:19:in `included' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/base.rb:47:in `include' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/base.rb:47 from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_without_new_constant_marking' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_file' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in `load_file' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in `require_or_load' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in `load_missing_constant' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in `const_missing' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap.rb:964 ... 3 levels... from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in `load_file' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in `require_or_load' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in `load_missing_constant' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in `const_missing' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:465:in `const_missing' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/app/models/ldap_user.rb:1 from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_without_new_constant_marking' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_file' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in `load_file' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in `require_or_load' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in `load_missing_constant' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in `const_missing' from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:465:in `const_missing' from (irb):20 from :0>> Thanks From kou at cozmixng.org Wed Jan 16 21:47:26 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 11:47:26 +0900 Subject: [Ruby-activeldap-discuss] ArgumentError: Anonymous modules have no name to be referenced by In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > The trace is below: > > ArgumentError: Anonymous modules have no name to be referenced by > from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:402:in > `to_constant_name' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:214:in > `qualified_name_for' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:477:in > `const_missing' > from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/get_text_support.rb:20:in > `included' Does this patch fix the problem? Index: lib/active_ldap/get_text_support.rb =================================================================== --- lib/active_ldap/get_text_support.rb (revision 672) +++ lib/active_ldap/get_text_support.rb (working copy) @@ -17,7 +17,7 @@ class << self def included(base) base.class_eval do - include(GetText) + include(::ActiveLdap::GetText) bindtextdomain("active-ldap") end end Thanks, -- kou From me at bjeanes.com Wed Jan 16 21:48:45 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:48:45 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: > :attribute and :value is for convenience. > If you want to use :filter, you do all what you want to do is in :filter. I figured as much which is why I wrote that part of the code in my find method. > It seems that some of your ldap users doesn't have displayName. Well well in my attempt to test that look what I found: >> LdapUser.find(:all).collect{|u| puts "-- #{u.displayName}"}; nil NoMethodError: undefined method `<=>' for nil:NilClass from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:220:in `sort_by' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:220:in `find_every' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:181:in `find' from /Users/bjeanes/_PROJECTS/Intranet/rails-site/app/models/ldap_user.rb:101:in `find' from (irb):1 It isn't just find(:first) then. Something else is going wrong in that sort_by? Or if that is because of a non-existent displayName, why wouldn't putting sort_by in ldap_mapping throw this error instead of just returning an unsorted array. In ldap_mapping it doesn't even seem to try to sort it! > Do you know a way how to sort on LDAP server? Alas, I do not. Perhaps i am wrong about this possibility. But it surely makes more sense than expecting clients to sort it. Especially since LDAP is used in such large networks where there could be possibly thousands and thousands of objects. It certainly would be nice and would shave a few more milliseconds of those benchmarks though wouldn't it! http://search.cpan.org/~gbarr/perl-ldap-0.34/lib/Net/LDAP/Control/Sort.pm seems to indicate that it performs a Server Side Sort (SSS) as defined in RFC-2891 (http://www.ietf.org/rfc/rfc2891.txt) I suppose this really depends on if the lower-level ldap libraries support it (net/ldap and ruby-ldap ... i hope they do) I am really starting to hate the reply button ... no way to make define the reply-to: header in these mailing lists? From kou at cozmixng.org Wed Jan 16 21:52:24 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 11:52:24 +0900 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: <20080110.214846.5295189865763785.kou@cozmixng.org> <20080113.210911.1062576197951488437.kou@cozmixng.org> Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > >> pl.class > LdapUser # subclass of ActiveLdap::Base > >> pk.title > => "Project Manager" > >> pk.title << "!" > => "Project Manager!" > >> pk.save > SystemStackError: stack level too deep > from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:322:in > `callback' > from /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/callbacks.rb:20:in > `callback' > from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:270:in > `valid_without_callbacks?' > from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:273:in > `valid?' > from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/validations.rb:933:in > `save' > from (irb):18 > from :0 Is the stack trace all of what you got? I can't find infinite lopp from the stack trace. Thanks, -- kou From me at bjeanes.com Wed Jan 16 21:52:40 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:52:40 +1000 Subject: [Ruby-activeldap-discuss] ArgumentError: Anonymous modules have no name to be referenced by In-Reply-To: References: Message-ID: > Does this patch fix the problem? Well, it changes the problem. Now in development mode I get Expected /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/get_text.rb to define ActiveLdap::GetText From me at bjeanes.com Wed Jan 16 21:55:36 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 12:55:36 +1000 Subject: [Ruby-activeldap-discuss] Fwd: dropped connection in rails app In-Reply-To: References: <20080110.214846.5295189865763785.kou@cozmixng.org> <20080113.210911.1062576197951488437.kou@cozmixng.org> Message-ID: > Is the stack trace all of what you got? > I can't find infinite lopp from the stack trace. Yeah that's all I got. It's odd, it doesn't look like an infinite loop stack trace, it doesn't even call the same method twice as far as I can tell. Perhaps the other issue with GetText is interfering. Perhaps it will be wise to put this issue on hold until the other one is resolved? Bo From kou at cozmixng.org Wed Jan 16 22:16:40 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 12:16:40 +0900 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > > It seems that some of your ldap users doesn't have displayName. > > Well well in my attempt to test that look what I found: > > >> LdapUser.find(:all).collect{|u| puts "-- #{u.displayName}"}; nil > NoMethodError: undefined method `<=>' for nil:NilClass /Users/bjeanes/_PROJECTS/Intranet/rails-site/lib/active_ldap/active_ldap/operations.rb:220:in > `sort_by' Do you specify :sort_by in ldap_mapping? Please remove and try again. > > Do you know a way how to sort on LDAP server? > seems to indicate that it performs a Server Side Sort (SSS) as defined > in RFC-2891 (http://www.ietf.org/rfc/rfc2891.txt) > > I suppose this really depends on if the lower-level ldap libraries > support it (net/ldap and ruby-ldap ... i hope they do) It seems that OpenLDAP server doesn't support that. So I can't test that... If I receive a patch, I'll apply. > I am really starting to hate the reply button ... no way to make > define the reply-to: header in these mailing lists? Will, could you set reply-to: header? Thanks, -- kou From kou at cozmixng.org Wed Jan 16 22:21:21 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 12:21:21 +0900 Subject: [Ruby-activeldap-discuss] ArgumentError: Anonymous modules have no name to be referenced by In-Reply-To: References: Message-ID: 2008/1/17, Bodaniel Jeanes : > > Does this patch fix the problem? > > Well, it changes the problem. Now in development mode I get Ah, you can't put ActiveLdap into RAILS_ROOT/lib/. Did you see this page: http://code.google.com/p/ruby-activeldap/wiki/UsingTrunkWithRails Thanks, -- kou From me at bjeanes.com Wed Jan 16 22:33:31 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 13:33:31 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: > Do you specify :sort_by in ldap_mapping? > Please remove and try again. It isn't specified in ldap_mapping (that doesn't do anything). But it's in my wrapper. I have removed and ran again and you are correct not all users have displayNames. (because it is returning some non-users still ... damn active directory messing with objectClasses!) I am now sorting by cn which resolves the method missing errors. But putting sort_by in the ldap mapping still has no effect and the results remain unsorted. everything must have a cn so that can't be the issue... > It seems that OpenLDAP server doesn't support that. > So I can't test that... If I receive a patch, I'll apply. That's an awful shame that it doesn't support it. Unfortunately I still don't understand the workings of this library well enough yet to tackle this. Otherwise I would. If i do stumble upon an answer I will try to write a patch. Of course I'll have to set up an AD server somewhere because the only one i have access to is at work. Any other volunteers? From kou at cozmixng.org Wed Jan 16 23:41:58 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 13:41:58 +0900 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > putting sort_by in the ldap mapping still has no effect and the > results remain unsorted. Really? A test in r675 works well for me. def test_find_with_sort_by_in_ldap_mapping @user_class.ldap_mapping(:dn_attribute => @user_class.dn_attribute, :prefix => @user_class.prefix, :scope => @user_class.scope, :classes => @user_class_classes, :sort_by => "uid", :order => "asc") make_temporary_user(:uid => "user1") do |user1,| make_temporary_user(:uid => "user2") do |user2,| make_temporary_user(:uid => "user3") do |user3,| users = @user_class.find(:all) assert_equal(["user3", "user2", "user1"].sort, users.collect {|u| u.uid}.sort) users = @user_class.find(:all, :order => "desc") assert_equal(["user1", "user2", "user3"].sort, users.collect {|u| u.uid}.sort) end end end end Thanks, -- kou From me at bjeanes.com Wed Jan 16 23:59:31 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 14:59:31 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: > Really? A test in r675 works well for me. I just saw that commit. of course i'd have to rewrite that for active directory, as the uid attribute does not exist. I have my sort_by options permanently in ldap_mapping but unless i explicitly specify it in a find, the results are always unsorted. From me at bjeanes.com Thu Jan 17 00:02:37 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 15:02:37 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Wait .... you are calling #sort manually on the returned list. I was under the impression sort_by in ldap_mapping made sure that #find sorted the results BEFORE returning it. That's the behavior when you pass sort_by directrory. On 1/17/08, Bodaniel Jeanes wrote: > > Really? A test in r675 works well for me. > > I just saw that commit. of course i'd have to rewrite that for active > directory, as the uid attribute does not exist. I have my sort_by > options permanently in ldap_mapping but unless i explicitly specify it > in a find, the results are always unsorted. > From kou at cozmixng.org Thu Jan 17 00:16:34 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Thu, 17 Jan 2008 14:16:34 +0900 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: Hi, 2008/1/17, Bodaniel Jeanes : > Wait .... you are calling #sort manually on the returned list. I was > under the impression sort_by in ldap_mapping made sure that #find > sorted the results BEFORE returning it. That's the behavior when you > pass sort_by directrory. Ah, sorry. I've fixed. Thanks, -- kou From me at bjeanes.com Thu Jan 17 00:24:09 2008 From: me at bjeanes.com (Bodaniel Jeanes) Date: Thu, 17 Jan 2008 15:24:09 +1000 Subject: [Ruby-activeldap-discuss] undefined method `legacyExchangeDN=' (and others) in trunk In-Reply-To: References: Message-ID: > Ah, sorry. I've fixed. That did the trick! From graf0 at post.pl Sun Jan 20 20:49:05 2008 From: graf0 at post.pl (=?ISO-8859-2?Q?Grzegorz_Marsza=B3ek?=) Date: Mon, 21 Jan 2008 02:49:05 +0100 Subject: [Ruby-activeldap-discuss] has_many with dn attribute? Message-ID: <519720D8-9705-47D6-9343-B9F5EBD2F1C7@post.pl> Hello! I'm new to activeldap - so I've stucked and don't now how to procced. I've got attribute "deliverTo" - it holds dn of other object, that is user. Now I'm defining classes: class User < ActiveLdap::Base ldap_mapping :dn_attribute => 'cn', :prefix => 'ou=Users,ou=Auth', :classes => ['inetOrgPerson','posixAccount','sambaSamAccount'] end class ExternalMailAccount < ActiveLdap::Base ldap_mapping :dn_attribute => 'cn', :prefix => 'ou=Mail,ou=Data', :classes => ['externalMailAccount'] has_many :members, :class => "User", :wrap => "deliverTo", :primary_key => 'dn' end ex=ExternalMailAccount.find(:all,'*') ex.each do |accc| puts accc.members end Unfortunately this code gives me: /usr/lib/ruby/1.8/active_ldap/base.rb:445:in `initialize': '#"testuser testuser"}, {"ou"=>"Users"}, {"ou"=>"Auth"}, {"dc"=>"c0000"}, {"dc"=>"local"}]>' must be either nil, DN value as String or Array or attributes as Hash (ArgumentError) I'm using activeldap 0.90. Where do I make error? --- Grzegorz Marsza?ek alias Ojciec Dyrektor ;) --- Grzegorz Marsza?ek graf0 at post.pl From kou at cozmixng.org Sun Jan 20 21:25:46 2008 From: kou at cozmixng.org (Kouhei Sutou) Date: Mon, 21 Jan 2008 11:25:46 +0900 Subject: [Ruby-activeldap-discuss] has_many with dn attribute? In-Reply-To: <519720D8-9705-47D6-9343-B9F5EBD2F1C7@post.pl> References: <519720D8-9705-47D6-9343-B9F5EBD2F1C7@post.pl> Message-ID: Hi, 2008/1/21, Grzegorz Marsza?ek : > I'm new to activeldap - so I've stucked and don't now how to procced. > I've got attribute "deliverTo" - it holds dn of other object, that is > user. Now I'm defining classes: > Unfortunately this code gives me: > /usr/lib/ruby/1.8/active_ldap/base.rb:445:in `initialize': > '#"testuser > testuser"}, {"ou"=>"Users"}, {"ou"=>"Auth"}, {"dc"=>"c0000"}, > {"dc"=>"local"}]>' must be either nil, DN value as String or Array or > attributes as Hash (ArgumentError) This should have been fixed in trunk. Thanks, -- kou