changeset 3668:1a5fe473e649

docs/CHANGES MoinMoin/auth/ldap_login.py reverted to changeset 3664:d027dd4948d7
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Thu, 05 Jun 2008 11:18:40 +0200
parents 4e59423375ce
children 86f8f213d044
files MoinMoin/auth/ldap_login.py docs/CHANGES
diffstat 2 files changed, 51 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/auth/ldap_login.py	Thu Jun 05 10:40:56 2008 +0200
+++ b/MoinMoin/auth/ldap_login.py	Thu Jun 05 11:18:40 2008 +0200
@@ -118,10 +118,9 @@
         # we require non-empty password as ldap bind does a anon (not password
         # protected) bind if the password is empty and SUCCEEDS!
         if not password:
-            return ContinueLogin(user_obj, _('Missing password. Please enter user name and password.LDAP'))
+            return ContinueLogin(user_obj, _('Missing password. Please enter user name and password.'))
 
         try:
-            logging.debug("uso ")
             try:
                 u = None
                 dn = None
@@ -167,39 +166,15 @@
                 # you can use %(username)s here to get the stuff entered in the form:
                 filterstr = self.search_filter % locals()
                 logging.debug("Searching %r" % filterstr)
-                # try:
-                # lusers = l.search_st(self.base_dn, self.scope, filterstr.encode(coding))
-                # except(ldap.NO_SUCH_OBJECT), err:
-                # logging.debug("veliki moji problemi sa .")
-                # raise
+                attrs = [getattr(self, attr) for attr in [
+                                         'email_attribute',
+                                         'aliasname_attribute',
+                                         'surname_attribute',
+                                         'givenname_attribute',
+                                         ] if getattr(self, attr) is not None]
+                lusers = l.search_st(self.base_dn, self.scope, filterstr.encode(coding),
+                                     attrlist=attrs, timeout=self.timeout)
                 # we remove entries with dn == None to get the real result list:
-                # lusers = [(dn, ldap_dict) for dn, ldap_dict in lusers if dn is not None]
-                # for dn, ldap_dict in lusers:
-                #    logging.debug("dn:%r" % dn)
-                #    for key, val in ldap_dict.items():
-                #        logging.debug("    %r: %r" % (key, val))
-
-                # result_length = len(lusers)
-                # if result_length != 1:
-                #    if result_length > 1:
-                #        logging.debug("Search found more than one (%d) matches for %r." % (result_length, filterstr))
-                result_length = 0
-                if result_length == 0:
-                    logging.debug("Search found no matches for %r." % (filterstr, ))
-                    return CancelLogin(_("Invalid username or password."))
-                lusers = [(dn, ldap_dict) for dn, ldap_dict in lusers if dn is not None]
-                for dn, ldap_dict in lusers:
-                    logging.debug("dn:%r" % dn)
-                    for key, val in ldap_dict.items():
-                        logging.debug("    %r: %r" % (key, val))
-
-                result_length = len(lusers)
-                if result_length != 1:
-                    if result_length > 1:
-                        logging.debug("Search found more than one (%d) matches for %r." % (result_length, filterstr))
-                    if result_length == 0:
-                        logging.debug("Search found no matches for %r." % (filterstr, ))
-                    return CancelLogin(_("Invalid username or password."))
                 lusers = [(dn, ldap_dict) for dn, ldap_dict in lusers if dn is not None]
                 for dn, ldap_dict in lusers:
                     logging.debug("dn:%r" % dn)
@@ -214,80 +189,6 @@
                         logging.debug("Search found no matches for %r." % (filterstr, ))
                     return ContinueLogin(user_obj, _("Invalid username or password."))
 
-                #dn, ldap_dict = lusers[0]
-                #if not self.bind_once:
-                #    logging.debug("DN found is %r, trying to bind with pw" % dn)
-                #    l.simple_bind_s(dn, password.encode(coding))
-                #    logging.debug("Bound with dn %r (username: %r)" % (dn, username))
-
-                #if self.email_callback is None:
-                #    if self.email_attribute:
-                #        email = ldap_dict.get(self.email_attribute, [''])[0].decode(coding)
-                #    else:
-                #        email = None
-                # else:
-                #    email = self.email_callback(ldap_dict)
-
-                # aliasname = ''
-                # try:
-                #    aliasname = ldap_dict[self.aliasname_attribute][0]
-                # except (KeyError, IndexError):
-                #    pass
-                # if not aliasname:
-                #    sn = ldap_dict.get(self.surname_attribute, [''])[0]
-                #    gn = ldap_dict.get(self.givenname_attribute, [''])[0]
-                #    if sn and gn:
-                #        aliasname = "%s, %s" % (sn, gn)
-                #    elif sn:
-                #        aliasname = sn
-                # aliasname = aliasname.decode(coding)
-
-                #if email:
-                #    u = user.User(request, auth_username=username, password="{SHA}NotStored", auth_method=self.name, auth_attribs=('name', 'password', 'email', 'mailto_author', ))
-                #   u.email = email
-                # else:
-                #    u = user.User(request, auth_username=username, password="{SHA}NotStored", auth_method=self.name, auth_attribs=('name', 'password', 'mailto_author', ))
-                # u.name = username
-                # u.aliasname = aliasname
-                # u.remember_me = 0 # 0 enforces cookie_lifetime config param
-                # logging.debug("creating userprefs with name %r email %r alias %r" % (username, email, aliasname))
-                dn, ldap_dict = lusers[0]
-                if not self.bind_once:
-                    logging.debug("DN found is %r, trying to bind with pw" % dn)
-                    l.simple_bind_s(dn, password.encode(coding))
-                    logging.debug("Bound with dn %r (username: %r)" % (dn, username))
-
-                if self.email_callback is None:
-                    if self.email_attribute:
-                        email = ldap_dict.get(self.email_attribute, [''])[0].decode(coding)
-                    else:
-                        email = None
-                else:
-                    email = self.email_callback(ldap_dict)
-
-                aliasname = ''
-                try:
-                    aliasname = ldap_dict[self.aliasname_attribute][0]
-                except (KeyError, IndexError):
-                    pass
-                if not aliasname:
-                    sn = ldap_dict.get(self.surname_attribute, [''])[0]
-                    gn = ldap_dict.get(self.givenname_attribute, [''])[0]
-                    if sn and gn:
-                        aliasname = "%s, %s" % (sn, gn)
-                    elif sn:
-                        aliasname = sn
-                aliasname = aliasname.decode(coding)
-
-                if email:
-                    u = user.User(request, auth_username=username, password="{SHA}NotStored", auth_method=self.name, auth_attribs=('name', 'password', 'email', 'mailto_author', ))
-                    u.email = email
-                else:
-                    u = user.User(request, auth_username=username, password="{SHA}NotStored", auth_method=self.name, auth_attribs=('name', 'password', 'mailto_author', ))
-                u.name = username
-                u.aliasname = aliasname
-                u.remember_me = 0 # 0 enforces cookie_lifetime config param
-                logging.debug("creating userprefs with name %r email %r alias %r" % (username, email, aliasname))
                 dn, ldap_dict = lusers[0]
                 if not self.bind_once:
                     logging.debug("DN found is %r, trying to bind with pw" % dn)
--- a/docs/CHANGES	Thu Jun 05 10:40:56 2008 +0200
+++ b/docs/CHANGES	Thu Jun 05 11:18:40 2008 +0200
@@ -27,28 +27,61 @@
     USE BOTH ON YOUR OWN RISK!
 
 
-Version 1.8-ldapgroups-mmihaljevic
-   Developer notes (these should be moved to the end in the release):
-    * done ldap_login testing - still got skiped tests 
-    * read about python-ldap and searchiing ldap groups - done some coding but not finished functionality  
-    *
-
-Version 1.7.0current:
+Version 1.8.0current:
 
   Bug Fixes:
+    * ...
+
+
+Version 1.7.0rc2:
+
+  Bug Fixes:
+    * Security Fix: fixed MoinMoinBugs/DummyPasswordInAutoCreatedLdapUserProfiles
+      (bug was present since some auth refactoring in 1.7.0alpha).
     * Fix editor preview not working for new pages.
     * Add ssh protocol to url_schemas.
     * Fix PageList macro with search errors.
     * Center the message icons and fix their spacing. Add a class to the
       "Clear message" link, make the link text smaller and lower.
     * Better handling of ImportErrors (farmconfig, macros, wikiserverconfig).
-    * Xapian mimetype search: fixes, use text/<format> as mimetype for pages
     * Builtin search: support mimetype: search for builtin engine, too
+    * Xapian search/indexing:
+      * use text/<format> as mimetype for pages
+      * index also major and minor for mimetypes, so it will find 'text' or
+        'plain' as well as 'text/plain'
+      * remove crappy num regex from WikiAnalyzer, improve tokenization
     * Fix the second hmac use for python 2.4
-    * csv parser: fix delimiter sniffing troubles, fix tests
+    * csv parser:
+      * fix delimiter sniffing troubles, fix tests
+      * remove empty lines above the csv table
     * Event notifications: send notifies in the language of the message
       recipient (not of the current wiki user), other fixes.
 
+  Other changes:
+    * HINT: ldap_login behaves a bit different now:
+      In previous moin versions, ldap_login tended to either successfully
+      authenticate a user or to completely cancel the whole login process in
+      any other case (including ldap server down or exceptions happening).
+      This made subsequent auth list entries rather pointless.
+      Now it behaves like this:
+        * user not found in LDAP -> give subsequent auth list entries a
+          chance to authenticate the user (same happens if it finds multiple
+          LDAP entries when searching - it logs an additional warning then).
+        * user found, but wrong password -> cancel login
+        * ldap server not reachable or other exceptions -> give subsequent
+          auth list entries a chance
+      So please make sure that you really trust every auth list entry you have
+      configured when upgrading or it might maybe change behaviour in a
+      unexpected or unwanted way.
+    * ldap_login now supports failover: if it can't contact your LDAP server
+      (e.g. because it is down or unreachable), it will just continue and
+      try to authenticate with other authenticators (if there are any in
+      cfg.auth list). So if you have some mirroring LDAP backup server, just
+      put another authenticator querying it there:
+          ldap_auth1 = LDAPAuth(server_uri='ldap://mainserver', ...)
+          ldap_auth2 = LDAPAuth(server_uri='ldap://backupserver', ...)
+          auth = [ldap_auth1, ldap_auth2, ]
+
 
 Version 1.7.0rc1: