* looking for arch@arch.thinkmo.de--2003-archives/moin--main--1.5--patch-347 to compare with
* comparing to arch@arch.thinkmo.de--2003-archives/moin--main--1.5--patch-347
M  MoinMoin/auth.py
M  MoinMoin/multiconfig.py
M  MoinMoin/request.py
M  MoinMoin/user.py
M  MoinMoin/userform.py

* modified files

--- orig/MoinMoin/auth.py
+++ mod/MoinMoin/auth.py
@@ -45,6 +45,7 @@
 
 import Cookie
 from MoinMoin import user
+from MoinMoin.util import securitystring
 
 def moin_cookie(request, **kw):
     """ authenticate via the MOIN_ID cookie """
@@ -58,13 +59,6 @@
             request.setCookie()
             return u, False
         return None, True
-
-    if kw.get('logout'):
-        # clear the cookie in the browser and locally. Does not
-        # check if we have a valid user logged, just make sure we
-        # don't have one after this call.
-        request.deleteCookie()
-        return None, True
     
     try:
         cookie = Cookie.SimpleCookie(request.saved_cookie)
@@ -72,13 +66,72 @@
         # ignore invalid cookies, else user can't relogin
         cookie = None
     if cookie and cookie.has_key('MOIN_ID'):
-        u = user.User(request, id=cookie['MOIN_ID'].value,
+        # Use security_string to handle the Cookie.
+	# So. need to use 
+	#     MoinMoin.util.securitystring.cal_security_userid modify
+	#     to do cookie auth.
+	# Need Pass the user_obj to cal_security_userid. 
+	# Because the MoinMoin.util.securitystring.cal_security_userid
+	#     need to do MoinMoin.user.getUserList, 
+	#     and MoinMoin.user.User.load_from_id
+
+	# FrankieChow: I think in MoinMoin/util/securitystring. 
+	#     If pass the user simple the pass the user.User
+	user_obj = user
+        u = user.User(request, 
+		# if can auth, then 
+		#  MoinMoin.util.securitystring.cal_security_userid
+		#  return the uid.
+		# if cannot match any uid then return None.
+	        id=securitystring.SecurityString(request).cal_security_userid(cookie['MOIN_ID'].value, user_obj),
                       auth_method='moin_cookie', auth_attribs=())
         if u.valid:
-            return u, False
+            if kw.get('logout'):
+	        # Frankie: Why Does not check it?
+		# Please see: http://moinmoin.wikiwikiweb.de/MoinMoinBugs/LogoutHandle
+		#
+                # clear the cookie in the browser and locally. Does not
+                # check if we have a valid user logged, just make sure we
+                # don't have one after this call.
+                request.deleteCookie()
+                # FrankieChow: When the user do global logout then change the
+                # security_string. ( in here. All logout is global logout. )
+                u.security_string = securitystring.gen(30)
+                u.save()
+                return None, True
+	    else:
+                return u, False
+
+        # If the brower don't have MOIN_ID cookie, just delete the cookie.
+        if kw.get('logout'):
+            request.deleteCookie()
+	    # Frankie: I don't know ? why ( None, True ) not ( None, False ) ?
+            return None, True
+	    
     return None, True
 
 
+def moin_url(request, **kw):
+    # The url syntax is like this: action=userform&uid=
+    action = request.form.get('action',[None])[0]
+    uid = request.form.get('uid',[None])[0]
+    user_obj = user
+    if action == 'userform' :
+        u = user.User(request, 
+		# if can auth, then 
+		#  MoinMoin.util.securitystring.cal_security_userid
+		#  return the uid.
+		# if cannot match any uid then return None.
+	        id=securitystring.SecurityString(request).cal_security_userid(uid, user_obj),
+                      auth_method='moin_cookie', auth_attribs=())
+        if u.valid:
+            u.security_string = securitystring.gen(30)
+            u.save()
+	    request.user = u
+            request.setCookie()
+            return u, False
+    return None, True
+
 #
 #   idea: maybe we should call back to the request object like:
 #         username, password, authenticated, authtype = request.getUserPassAuth()


--- orig/MoinMoin/multiconfig.py
+++ mod/MoinMoin/multiconfig.py
@@ -172,7 +172,7 @@
     actions_excluded = [] # ['DeletePage', 'AttachFile', 'RenamePage']
     allow_xslt = 0
     attachments = None # {'dir': path, 'url': url-prefix}
-    auth = [authmodule.moin_cookie]
+    auth = [authmodule.moin_cookie, authmodule.moin_url]
     
     backup_compression = 'gz'
     backup_users = []


--- orig/MoinMoin/request.py
+++ mod/MoinMoin/request.py
@@ -9,7 +9,7 @@
 
 import os, time, sys, cgi, StringIO
 from MoinMoin import config, wikiutil, user
-from MoinMoin.util import MoinMoinNoFooter, IsWin9x
+from MoinMoin.util import MoinMoinNoFooter, IsWin9x, securitystring
 
 # Timing ---------------------------------------------------------------
 
@@ -1216,7 +1216,16 @@
         # Set the cookie
         from Cookie import SimpleCookie
         c = SimpleCookie()
-        c['MOIN_ID'] = self.user.id
+	# Modify the Cookie String Syntax.
+	# Keep the self.user.id in Cookie.
+	#   1. easy for auth.
+	#   2. and don't need to care the 
+	#       securitystring.make_security_key(security_string, self.user.id)
+	#      is unique.
+	c['MOIN_ID'] = '%s%s%s' %(
+	   securitystring.make_security_key(self.user.security_string, self.user.id),
+	   securitystring.luck(),
+	   self.user.id )
         c['MOIN_ID']['max-age'] = maxage
         if self.cfg.cookie_domain:
             c['MOIN_ID']['domain'] = self.cfg.cookie_domain


--- orig/MoinMoin/user.py
+++ mod/MoinMoin/user.py
@@ -17,7 +17,7 @@
 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
 
 from MoinMoin import config, caching, wikiutil
-from MoinMoin.util import datetime, filesys
+from MoinMoin.util import datetime, filesys, securitystring
 
 
 def getUserList(request):
@@ -232,9 +232,10 @@
 
         self.enc_password = ""
         if password:
-            if password.startswith('{SHA}'):
-                self.enc_password = password
-            else:
+             # disable the {SHA} auth.
+#            if password.startswith('{SHA}'):
+#                self.enc_password = password
+#            else:
                 try:
                     self.enc_password = encodePassword(password)
                 except UnicodeError:
@@ -450,6 +451,12 @@
         # First try with default encoded password. Match only non empty
         # passwords. (require non empty enc_password)
         if self.enc_password and self.enc_password == data['enc_password']:
+	    # If the user profile: It is create in moin-1.3 or old.
+	    # then user profile have not security_string.
+	    # MoinMoin will random create it.
+	    if not data.has_key('security_string'):
+	        data['security_string'] = securitystring.gen(30)
+		return True, True
             return True, False
 
         # Try to match using one of pre 1.3 8 bit charsets
@@ -483,6 +490,11 @@
                 # User password match - replace the user password in the
                 # file with self.password
                 data['enc_password'] = self.enc_password
+	        # If the user profile: It is create in pro moin-1.3 or old.
+	        # then user profile have not security_string.
+	        # MoinMoin will random create it.
+		if not data.has_key('security_string'):
+		    data['security_string'] = securitystring.gen(30)
                 return True, True
 
         # No encoded password match, this must be wrong password
@@ -527,6 +539,11 @@
 
         if not self.disabled:
             self.valid = 1
+	
+	# In Now Update the uid2security_hmac_string cache.
+	ss = securitystring.SecurityString(self._request)
+	ss.update_uid2security_hmac_string_cache(
+	              self.security_string, self.id)
 
     # -----------------------------------------------------------------
     # Time and date formatting
@@ -935,14 +952,16 @@
         from MoinMoin.util import mail
         _ = self._request.getText
 
+        # If MoinMoin use security_string logic to do url_auth. 
+	#     When use SSHA to disable the Login Password.
         text = '\n' + _("""\
 Login Name: %s
 
-Login Password: %s
-
 Login URL: %s/?action=userform&uid=%s
 """, formatted=False) % (
-                        self.name, self.enc_password, self._request.getBaseURL(), self.id)
+                        self.name, self._request.getBaseURL(), 
+			securitystring.make_security_key(self.security_string, self.id)
+			)
 
         text = _("""\
 Somebody has requested to submit your account data to this email address.


--- orig/MoinMoin/userform.py
+++ mod/MoinMoin/userform.py
@@ -8,7 +8,7 @@
 
 import string, time, re
 from MoinMoin import user, util, wikiutil
-from MoinMoin.util import web, mail, datetime
+from MoinMoin.util import web, mail, datetime, securitystring
 from MoinMoin.widget import html
 
 _debug = 0
@@ -78,6 +78,10 @@
                 theuser = user.User(self.request, uid)
                 if theuser.valid and theuser.email.lower() == email:
                     msg = theuser.mailAccountData()
+		    # Change the security_string
+		    #    When the user request the account_sendmail.
+		    theuser.security_string = securitystring.gen(30)
+		    theuser.save()
                     return wikiutil.escape(msg)
 
             return _("Found no account matching the given email address '%(email)s'!") % {'email': wikiutil.escape(email)}
@@ -124,7 +128,9 @@
             if not password and newuser:
                 return _("Please specify a password!")
             # Encode password
-            if password and not password.startswith('{SHA}'):
+	    if password.startswith('{SHA}'):
+	        return _("Not Don't Support {SHA} password for create profile.")
+            if password:
                 try:
                     theuser.enc_password = user.encodePassword(password)
                 except UnicodeError, err:
@@ -148,6 +154,8 @@
                     if thisuser.email == theuser.email and not thisuser.disabled:
                         return _("This email already belongs to somebody else.")
 
+            # Before create the user's profile, create the user's security_string.
+	    theuser.security_string = securitystring.gen(30)
             # save data
             theuser.save()
             if form.has_key('create_and_mail'):
@@ -194,8 +202,11 @@
                     return _("Passwords don't match!")
                 if not password and newuser:
                     return _("Please specify a password!")
+                # Don't support SHA auth.
+	        if password.startswith('{SHA}'):
+	            return _("Not Don't Support the {SHA} password")
                 # Encode password
-                if password and not password.startswith('{SHA}'):
+                if password:
                     try:
                         theuser.enc_password = user.encodePassword(password)
                     except UnicodeError, err:

