CHANGES.txt for the LDAPLoginAdapter This file contains change information for the LDAPLoginAdapter product. LDAPLoginAdapter 1.6 Bugs fixed: * Zope 2.4x complains about "ambiguous security declarations" when using the common idion "manage=manage_main...". Usage of the _setName method prevents this. * Florent Guillaume provided me with completely rewritten unicode support which fixed a lot of issues. Thanks Florent! LDAPLoginAdapter 1.6beta2 Bugs fixed: * findUser was missing a fix which prevented nasty error messages when using the ZMI to search using an empty DN. (Tracker Nr. 54) * getUserDN was unusable from dtml or python since it somehow tickled the security machinery the wrong way. a simplified implementation solved this issue. LDAPLoginAdapter 1.6beta1 Features added: * Added new method "getGroupDetails" which will return all uniqueMember and member values for a given group DN. Bugs fixed: * Fixed _searchResults so that binding with username and password is only done if both user and password are given, whereas the code had only checked for a username before. * When calling getProperty on a LDAPUser object the behavior has been changed slightly to return an empty string instead of None which reduces unexpected code breakages in DTML or having "None" appear in form fields that use getProperty. LDAPLoginAdapter 1.5 Bugs fixed: * Cosmetic fixes to the "Configure" management tab * There was a glaring inconsistency between the default set of LDAP attributes that are available upon instantitaion of a new LDAPLoginAdapter and the set offered in the creation screen as possible RDN-attributes or login names. Whenever a new LDAPLoginAdapter is created or an existing one is edited the code will check for the existence of (and will add if needed) the attributes that are specified as RDN-attribute or login name. (Tracker issue 45) * A logic error on my part rendered some LDAP ACLs useless. When a new user object was created the information from the LDAP server was retrieved using an anonymous bind. This has been changed to binding with that specific user's DN and password when retrieving the user attributes used to instantiate the LDAPUser object. The penalty is an added call into the LDAP server whenever a user is not in the cache or has expired. (Tracker issue 47) LDAPLoginAdapter 1.5beta3 Bugs fixed: * Some python-ldap packages (namely the RPM) name the ldap module wrong and _ldap is not available. This is an error on the part of the python-ldap package. All code now falls back to importing "ldap" if "_ldap" is not available. * When in cookie mode cookies would not be set in a specific border condition where the user was in the cache and got validated but no cookie was on the user's browser. The existence of the cookie is now tested for after validating from cache. (Tracker issue 44) LDAPLoginAdapter 1.5beta2 Bugs fixed: * All direct references to the ldap module have been changed to use the name "_ldap" instead. This is the preferred notation and will fix problems where self-compiled python-ldap modules did not include the "ldap.py" kludge. LDAPLoginAdapter 1.5beta1 Bugs fixed: * The entry field for bind password in the Add-form was not of type "password" Features added: * Methods common to the LDAPLoginAdapter and the LDAPUserManager have been removed from the main module and made into a separate class in module LDAPShared. Both the LDAPLoginAdapter and the LDAPUserManager now subclass from this shared class. This will make it easier to keep core functionality synchronized. * This version introduces the first stab at being able to handle non-ascii characters in attribute values if your version of Python has unicode abilities. Please see README.txt for the gory details. LDAPLoginAdapter 1.4 Bugs fixed: * More documentation in the doc strings and some visual cleanup in the code * Replaced __ac_permissions__ with the new security framework using ClassSecurityInfo * Replaced all instances of HTMLFile with DTMLFile LDAPLoginAdapter 1.4beta3 Features added: * The LDAPUser object now sports a "_expire" method. This method should be called by anyone changing the LDAP-side of the user records, it will guarantee that the cached version in the LDAPLoginAdapter is updated on the next access. Bugs fixed: * The "Purge Caches" button has been moved from the "Advanced" management tab to the "Caches" tab - undoubtedly a better place for it. LDAPLoginAdapter 1.4beta2 Features added: * When building the CMFLDAP product I realized that it is very hard to work with user objects if they do not know their own Distinguished Name attribute. LDAPUser has been expanded to accept the DN in the constructor and to show it using a new method named getUserDN. LDAPLoginAdapter 1.4beta1 Bugs fixed: * Creating a LDAPLoginAdapter object from python has been made easier by giving REQUEST a default value of None. Features added: * Most pesky MessageDialog invocations have been replaced by using the ZMI's built-in "manage_tabs_message" facility. This means that, unless there is an error, normal management screen actions will not throw up a confirmation dialog anymore. This makes it more convenient to work in the management interface. LDAPLoginAdapter 1.3 This release fixes no bugs over 1.3beta4, it just enables me (now that bug reports have died down) to start the 1.4 beta cycle and stop extending the 1.3 beta cycle forever. LDAPLoginAdapter 1.3beta4 Bugs fixed: * The mechanism by which groups (-> roles) were gleaned from records of type groupOfUniqueNames would fail if for some reason the spacing of the user record's DN and the corresponding uniqueMember attribute in the group record was different. A new method, "getGroupsWithInconsistentRecords", was introduced which can be used instead of the normal getGroups method. Since the overhead in the new method is much higher I am requiring anyone who somehow messed up their group records to edit the LDAPLoginAdapter.py file and go to line 28 where it says "USER_GROUP_INCONSISTENCY = 0". If you replace 0 with 1 here the new method will be called and you might see some slowdown. As a general remark, there should never be any spaces between elements in a DN. However, even worse is inconsistent spacing. LDAPLoginAdapter 1.3beta3 Bugs fixed: * The current setup expected a RDN (Relative Distinguished Name) component *cn* on the user record. A lot of schemas, especially those in the Netscape Directory Server, like to use *uid* instead. Those records were not handled correctly. This is now fixed and the manager user can select which of the two to use. RFC 2377 has an explanation on when to use which. * Parsing the comma-separated list of default user roles more carefully to make sure that spacing between commas does not affect the real role names. LDAPLoginAdapter 1.3beta2 Bugs fixed: * Another one in finduser: If the dn from the user record and the dn pulled from the group records are different in small ways, like one of them has spaces after the commas, the record would not be returned with the search results. I am now using the explode_dn utility function from the ldap module to split the dn into components before comparing so that spacing and even separation characters (commas, semicolons) become irrelevant. (Tracker items 32 and 33) LDAPLoginAdapter 1.3beta1 Bugs fixed: * finduser expected that the LDAP server returned the attribute names correctly capitalized, which some servers do not. It handles both cases now in computing the list of valid users in groups. (Tracker item 31) LDAPLoginAdapter 1.2 Bugs fixed: * Added a missing comma in __ac_permissions__ that broke changing roles via the "Security" tab on the LDAPLoginAdapter... * Completely revamped the exception handling in authenticate so that there will always be a (hopefully) helpful output in the log * authenticate had an exeption handler that would try and use a variable left uninitialized when the exception was thrown. LDAPLoginAdapter 1.2beta3 Bugs fixed: * The methods that manipulate the publicly available user object attributes now make sure to flush the cache of user objects and force all of them to be recreated, thereby making the changes "grab" immediately and not just whenever the user object expires all by itself and gets recreated. LDAPLoginAdapter 1.2beta2 Features Added: * A new management tab called "LDAP Schema" allows the manager to enter or delete attributes that describe the LDAP schema used for the LDAP user records. This completely replaces the misleading "Allowable User Attributes" found on the Advanced tab which had been abused to find out more about the LDAP schema in use. All select lists that list LDAP attributes are now driven by the attributes that are shown on the LDAP Schema tab. Features deprecated: * The "Special Users" and "Special User Roles" feature has been deprecated. I considered it a kludge in cases where you cannot set your LDAP schema correctly. With the advent of the LDAPUserManager product it has become trivially easy to add users and groups. This is the much preferred way of conferring roles to users. Bugs fixed: * Mishandled the loop to delete the public attribute mappings in manage_deletePublicUserAttrs which caused index errors * Default handling of method calls through the web or from python was inconsistent in regards to what to return and what to expect. All method signatures that might expect REQUEST now set it to a default value of None and in the method body test to see if it is None. This improves the use of methods from python where no REQUEST is guaranteed. * Change capitalization of manage_AddPublicUserAttrs to bring it in line with the normally used capitalization scheme * Renamed "Contents" tab to "Custom Forms" to clear up the meaning of this tab LDAPLoginAdapter 1.2beta1 Features Added: * Cookie-based authentication with a login page and the ability to simply drop in custom login pages. * Complete rewriting of all code connected to the validate method, which does the actual authentication, to reflect the way it is done in the latest built-in user folder object. Bugs fixed: * The bunduid and bindpwd attributes which hold the DN and password of the LDAP server manager user are now safeguarded from DTML access by changing names to _binduid and _bindpwd. A (protected) method, getProperty, is now used to get them. * The LDAP search string created in _lookupuser, the method which is called by validate to find a user in LDAP, created search expressions with asterisk wildcard characters around the search term. These were removed in the interest of an unambiguous match. LDAPLoginAdapter 1.1 Features Added: * Instead of hardcoding fixed publicly available attributes onto the LDAPUser object you can now take full control of the mapping from LDAP attribute to public user object attribute. A public user object attribute is an attribute that is directly accessible on the user object. DTML code like "AUTHENTICATED_USER.email" is an example of accessing a directly accessible attribute on the user object. A lot of legacy DTML code relies on such attributes. Bugs fixed: * finduser() now lowercases all DN records from valid groups and compares it to a lowercased DN from any search results among user records. This fixes records not showing up if the capitalization in the group and on the user record is different. * When a user object was created the code expected a "mail" attribute on the LDAP record to set the email attribute used for compatibility with the Tracker. This has been repaired and will just default to an empty string. * Users who use tools like PADL's migration script end up with records that do not have the expected "sn" attribute. This is not set to a default value in finduser() to avoid errors in case it is not there. This will make the LDAPLoginAdapter compatible with user records of type posixAccount. LDAPLoginAdapter 1.0 Bugs fixed: * Due to a bug in checking the return values from an LDAP search the cache can be polluted by invalid records for failed logins. This did not constitue a security breach, just more processing than necessary. LDAPLoginAdapter 1.0beta3 Bugs Fixed: * Moved the LDAP search scope translation list from a volatile attribute on the LDAPLoginAdapter to a module-level attribute. This avoids any re-initialization calls. * Eliminated the extra attribute _v_loglines that counted the length of the log. A simple call to len(self._v_log) replaces it where log length info is needed. * Created one centralized method that handles connecting to and searching the LDAP server. This allows centralized error handling and makes for less and cleaner code. So far finduser, getUserDetails, getGroups, getUserNames and _lookupuser have been converted to use it instead of having their own connection code. * Rooted out error that would put a known user into the cache even though the password was not matched. This was not a security error since the broken user had the wrong password and failed any tests in validate() * Rigorous pruning of overly long lines of code to pare everything down to 80 chars width max * Avoiding unnecessary calls to the logging routine by checking for the correct log level *before* the call and not in the logging method. * Added a file, SAMPLE_RECORDS.txt, that shows a sample group- and user record. This will hopefully make it easier to understand the types of LDAP records needed. Features added: * Nicer Search screen adopted from the LDAPUserManager LDAPLoginAdapter 1.0beta2 Features added: * Clearer error messages through refactoring of all code that is responsible for connecting and disconnecting from the LDAP server. * Co-operation with the Zope Tracker software has been ensured by making a full name and email attribute available on the user object returned from the LDAPLoginAdapter. * Added API documentation to the Zope Help System Bugs Fixed: * Various code cleanups * Added check to see if a server address with a prepended "ldap://" was entered. * Updated all docs to clarify the reliance on Zope version 2.3.0 of higher. * Vetted all code to make sure that every connection made to the LDAP server is followed by a formal disconnect, regardless of processing between connect and disconnect. LDAPLoginAdapter 1.0beta1 Features added: * The LDAP record attribute to be used as the user's name can be selected from a list of attributes * The list of LDAP attributes to be used as the user's name can be extended or reduced and custom attributes can be added to it. * A Search screen allows the Manager to search the LDAP database for user records and then view their details. * The python code has been refactored and the code for the LDAPUser class has been split off into a separate module. * All LDAPLoginAdapter-specific management screens have help screens associated with them, accessible through the built-in Zope Help System. * All management screens have been modified to integrate with the new Zope Management Interface, introduced in Zope 2.3.0. * ...and many others I forgot to track. The Beginning This product started from Ross Lazarus' Zope LDAP Adapter, which has since seen many improvement and moved to SourceForge. You can see Ross' and Soren Roug's efforts at: http://sourceforge.net/projects/zldapadapter I decided to use it as a base and develop a customized version for use in authenticating users in Digital Creations' own intranet. I have come to the point where it has matured enough to be released to a wider audience.