Revision: 8118
          http://svn.sourceforge.net/mailman/?rev=8118&view=rev
Author:   bwarsaw
Date:     2006-12-27 15:45:41 -0800 (Wed, 27 Dec 2006)

Log Message:
-----------
Utils.list_names(): Use a database query to get all the list names.

dbcontext.py: Added api_get_list_names() to support Utils.list_names().

listdata.py: Added two additional MailList attributes which need to be stored
in the database.  The first is 'admin_member_chunksize' which isn't modifiable
from the web.  The second is 'password' which holds the list's password.

HTMLFormatObject: item strings can now be unicodes.

bin/list_lists.py: Must call initialize() to get the database properly
initialized, not just config.load().  This will be a common theme.

SecurityManager.py:
    - Remove md5 and crypt support
    - Added mailman.debug logger, though it will be only used during
      debugging.
    - The 'secret' can be a unicode now.
    - A few coding style updates; repr() instead of backticks, 'key in dict'
      instead of 'dict.has_key(key)'

Modified Paths:
--------------
    branches/tmp-sqlalchemy-branch/Mailman/SecurityManager.py
    branches/tmp-sqlalchemy-branch/Mailman/Utils.py
    branches/tmp-sqlalchemy-branch/Mailman/bin/list_lists.py
    branches/tmp-sqlalchemy-branch/Mailman/database/dbcontext.py
    branches/tmp-sqlalchemy-branch/Mailman/database/listdata.py
    branches/tmp-sqlalchemy-branch/Mailman/htmlformat.py

Modified: branches/tmp-sqlalchemy-branch/Mailman/SecurityManager.py
===================================================================
--- branches/tmp-sqlalchemy-branch/Mailman/SecurityManager.py   2006-12-12 
03:58:06 UTC (rev 8117)
+++ branches/tmp-sqlalchemy-branch/Mailman/SecurityManager.py   2006-12-27 
23:45:41 UTC (rev 8118)
@@ -28,7 +28,7 @@
 #
 # Each cookie has the following ingredients: the authorization context's
 # secret (i.e. the password, and a timestamp.  We generate an SHA1 hex
-# digest of these ingredients, which we call the `mac'.  We then marshal
+# digest of these ingredients, which we call the 'mac'.  We then marshal
 # up a tuple of the timestamp and the mac, hexlify that and return that as
 # a cookie keyed off the authcontext.  Note that authenticating the user
 # also requires the user's email address to be included in the cookie.
@@ -48,7 +48,6 @@
 
 import os
 import re
-import md5
 import sha
 import time
 import urllib
@@ -64,12 +63,8 @@
 from Mailman import Utils
 from Mailman.configuration import config
 
-try:
-    import crypt
-except ImportError:
-    crypt = None
-
 log = logging.getLogger('mailman.error')
+dlog = logging.getLogger('mailman.debug')
 
 SLASH = '/'
 
@@ -77,8 +72,6 @@
 
 class SecurityManager:
     def InitVars(self):
-        # We used to set self.password here, from a crypted_password argument,
-        # but that's been removed when we generalized the mixin architecture.
         # self.password is really a SecurityManager attribute, but it's set in
         # MailList.InitVars().
         self.mod_password = None
@@ -146,50 +139,15 @@
                 if ok:
                     return Defaults.AuthSiteAdmin
             elif ac == Defaults.AuthListAdmin:
-                def cryptmatchp(response, secret):
-                    try:
-                        salt = secret[:2]
-                        if crypt and crypt.crypt(response, salt) == secret:
-                            return True
-                        return False
-                    except TypeError:
-                        # BAW: Hard to say why we can get a TypeError here.
-                        # SF bug report #585776 says crypt.crypt() can raise
-                        # this if salt contains null bytes, although I don't
-                        # know how that can happen (perhaps if a MM2.0 list
-                        # with USE_CRYPT = 0 has been updated?  Doubtful.
-                        return False
                 # The password for the list admin and list moderator are not
                 # kept as plain text, but instead as an sha hexdigest.  The
                 # response being passed in is plain text, so we need to
-                # digestify it first.  Note however, that for backwards
-                # compatibility reasons, we'll also check the admin response
-                # against the crypted and md5'd passwords, and if they match,
-                # we'll auto-migrate the passwords to sha.
+                # digestify it first.
                 key, secret = self.AuthContextInfo(ac)
                 if secret is None:
                     continue
                 sharesponse = sha.new(response).hexdigest()
-                upgrade = ok = False
                 if sharesponse == secret:
-                    ok = True
-                elif md5.new(response).digest() == secret:
-                    ok = upgrade = True
-                elif cryptmatchp(response, secret):
-                    ok = upgrade = True
-                if upgrade:
-                    save_and_unlock = False
-                    if not self.Locked():
-                        self.Lock()
-                        save_and_unlock = True
-                    try:
-                        self.password = sharesponse
-                        if save_and_unlock:
-                            self.Save()
-                    finally:
-                        if save_and_unlock:
-                            self.Unlock()
-                if ok:
                     return ac
             elif ac == Defaults.AuthListModerator:
                 # The list moderator password must be sha'd
@@ -234,17 +192,17 @@
 
     def MakeCookie(self, authcontext, user=None):
         key, secret = self.AuthContextInfo(authcontext, user)
-        if key is None or secret is None or not isinstance(secret, str):
+        if key is None or secret is None or not isinstance(secret, basestring):
             raise ValueError
         # Timestamp
         issued = int(time.time())
         # Get a digest of the secret, plus other information.
-        mac = sha.new(secret + `issued`).hexdigest()
+        mac = sha.new(secret + repr(issued)).hexdigest()
         # Create the cookie object.
         c = Cookie.SimpleCookie()
         c[key] = binascii.hexlify(marshal.dumps((issued, mac)))
         c[key]['path'] = self._cookie_path()
-        # We use session cookies, so don't set `expires' or `max-age' keys.
+        # We use session cookies, so don't set 'expires' or 'max-age' keys.
         # Set the RFC 2109 required header.
         c[key]['version'] = 1
         return c
@@ -293,7 +251,7 @@
                 for k in c.keys():
                     if k.startswith(prefix):
                         usernames.append(k[len(prefix):])
-            # If any check out, we're golden.  Note: `@'s are no longer legal
+            # If any check out, we're golden.  Note: '@'s are no longer legal
             # values in cookie keys.
             for user in [Utils.UnobscureEmail(u) for u in usernames]:
                 ok = self.__checkone(c, authcontext, user)
@@ -310,7 +268,7 @@
             key, secret = self.AuthContextInfo(authcontext, user)
         except Errors.NotAMemberError:
             return False
-        if not c.has_key(key) or not isinstance(secret, str):
+        if key not in c or not isinstance(secret, basestring):
             return False
         # Undo the encoding we performed in MakeCookie() above.  BAW: I
         # believe this is safe from exploit because marshal can't be forced to
@@ -332,7 +290,7 @@
             return False
         # Calculate what the mac ought to be based on the cookie's timestamp
         # and the shared secret.
-        mac = sha.new(secret + `issued`).hexdigest()
+        mac = sha.new(secret + repr(issued)).hexdigest()
         if mac <> received_mac:
             return False
         # Authenticated!

Modified: branches/tmp-sqlalchemy-branch/Mailman/Utils.py
===================================================================
--- branches/tmp-sqlalchemy-branch/Mailman/Utils.py     2006-12-12 03:58:06 UTC 
(rev 8117)
+++ branches/tmp-sqlalchemy-branch/Mailman/Utils.py     2006-12-27 23:45:41 UTC 
(rev 8118)
@@ -76,12 +76,9 @@
 
 
 def list_names():
-    """Return the names of all lists in default list directory."""
-    got = set()
-    for fn in os.listdir(config.LIST_DATA_DIR):
-        if list_exists(fn):
-            got.add(fn)
-    return got
+    """Return the fqdn names of all lists in default list directory."""
+    return ['[EMAIL PROTECTED]' % (listname, hostname)
+            for listname, hostname in database.get_list_names()]
 
 
 def split_listname(listname):

Modified: branches/tmp-sqlalchemy-branch/Mailman/bin/list_lists.py
===================================================================
--- branches/tmp-sqlalchemy-branch/Mailman/bin/list_lists.py    2006-12-12 
03:58:06 UTC (rev 8117)
+++ branches/tmp-sqlalchemy-branch/Mailman/bin/list_lists.py    2006-12-27 
23:45:41 UTC (rev 8118)
@@ -21,7 +21,7 @@
 from Mailman import MailList
 from Mailman import Utils
 from Mailman import Version
-from Mailman.configuration import config
+from Mailman.initialize import initialize
 from Mailman.i18n import _
 
 __i18n_templates__ = True
@@ -65,7 +65,7 @@
 
 def main():
     parser, opts, args = parseargs()
-    config.load(opts.config)
+    initialize(opts.config)
 
     names = list(Utils.list_names())
     names.sort()

Modified: branches/tmp-sqlalchemy-branch/Mailman/database/dbcontext.py
===================================================================
--- branches/tmp-sqlalchemy-branch/Mailman/database/dbcontext.py        
2006-12-12 03:58:06 UTC (rev 8117)
+++ branches/tmp-sqlalchemy-branch/Mailman/database/dbcontext.py        
2006-12-27 23:45:41 UTC (rev 8118)
@@ -22,7 +22,7 @@
 
 from Mailman import Version
 from Mailman.configuration import config
-from Mailman.database import address 
+from Mailman.database import address
 from Mailman.database import listdata
 from Mailman.database import version
 from Mailman.database.txnsupport import txn
@@ -132,6 +132,13 @@
             return mlists[0]
         return None
 
+    @txn
+    def api_get_list_names(self):
+        table = self.tables['Listdata']
+        results = table.select().execute()
+        return [(row[table.c.list_name], row[table.c.host_name])
+                for row in results.fetchall()]
 
+
 
 dbcontext = DBContext()

Modified: branches/tmp-sqlalchemy-branch/Mailman/database/listdata.py
===================================================================
--- branches/tmp-sqlalchemy-branch/Mailman/database/listdata.py 2006-12-12 
03:58:06 UTC (rev 8117)
+++ branches/tmp-sqlalchemy-branch/Mailman/database/listdata.py 2006-12-27 
23:45:41 UTC (rev 8118)
@@ -25,9 +25,10 @@
     table = Table(
         'Listdata', metadata,
         # Attributes not directly modifiable via the web u/i
-        Column('list_id',           Integer, primary_key=True),
-        Column('list_name',         Unicode),
-        Column('web_page_url',      Unicode),
+        Column('list_id',                   Integer, primary_key=True),
+        Column('list_name',                 Unicode),
+        Column('web_page_url',              Unicode),
+        Column('admin_member_chunksize',    Integer),
         # OldStyleMemberships attributes, temporarily stored as pickles.
         Column('bounce_info',           PickleType),
         Column('delivery_status',       PickleType),
@@ -119,6 +120,7 @@
         Column('owner',                                         PickleType),
         Column('pass_filename_extensions',                      PickleType),
         Column('pass_mime_types',                               PickleType),
+        Column('password',                                      Unicode),
         Column('personalize',                                   Integer),
         Column('preferred_language',                            Unicode),
         Column('private_roster',                                Boolean),

Modified: branches/tmp-sqlalchemy-branch/Mailman/htmlformat.py
===================================================================
--- branches/tmp-sqlalchemy-branch/Mailman/htmlformat.py        2006-12-12 
03:58:06 UTC (rev 8117)
+++ branches/tmp-sqlalchemy-branch/Mailman/htmlformat.py        2006-12-27 
23:45:41 UTC (rev 8118)
@@ -36,12 +36,11 @@
 # Format an arbitrary object.
 def HTMLFormatObject(item, indent):
     "Return a presentation of an object, invoking their Format method if any."
-    if type(item) == type(''):
-        return item
-    elif not hasattr(item, "Format"):
-        return `item`
-    else:
+    if hasattr(item, 'Format'):
         return item.Format(indent)
+    if isinstance(item, basestring):
+        return item
+    return str(item)
 
 def CaseInsensitiveKeyedDict(d):
     result = {}


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to