Index: acct_mgr/web_ui.py
===================================================================
--- acct_mgr/web_ui.py	(revision 1709)
+++ acct_mgr/web_ui.py	(working copy)
@@ -10,6 +10,8 @@
 # Author: Matthew Good <trac@matt-good.net>
 
 from __future__ import generators
+import time
+import urlparse
 
 import random
 import string
@@ -20,7 +22,7 @@
 from trac.notification import NotificationSystem, NotifyEmail
 from trac.web import auth
 from trac.web.api import IAuthenticator
-from trac.web.main import IRequestHandler
+from trac.web.main import IRequestHandler, IRequestFilter
 from trac.web.chrome import INavigationContributor, ITemplateProvider
 from trac.util import Markup
 
@@ -114,7 +116,7 @@
     module must be set in trac.ini in order to use this.
     """
 
-    implements(INavigationContributor, IRequestHandler, ITemplateProvider)
+    implements(INavigationContributor, IRequestHandler, ITemplateProvider, IRequestFilter)
 
     _password_chars = string.ascii_letters + string.digits
     password_length = IntOption('account-manager', 'generated_password_length', 8,
@@ -132,6 +134,19 @@
                           'store does not support writing.')
         return writable 
 
+    #IRequestFilter methods
+    def pre_process_request(self, req, handler):
+        # Catch the user leaving /account and redirect to non-secure
+        if (req.scheme == 'https' and req.path_info != '/account'):
+            r = req.get_header('Referer') or ''
+	    if (r.find('/account') != -1):
+	    	req.redirect(urlparse.urlunparse(('http', req.server_name, req.base_path + req.path_info, None, None, None)))
+
+        return handler
+
+    def post_process_request(self, req, template, content_type):
+        return template, content_type
+
     #INavigationContributor methods
     def get_active_navigation_item(self, req):
         return 'account'
@@ -150,12 +165,17 @@
 
     def process_request(self, req):
         if req.path_info == '/account':
+	    if req.scheme.lower() != 'https':
+	    	req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, None, None)))
             self._do_account(req)
             return 'account.cs', None
         elif req.path_info == '/reset_password':
+	    if req.scheme.lower() != 'https':
+	    	req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, None, None)))
             self._do_reset_password(req)
             return 'reset_password.cs', None
 
+
     def _do_account(self, req):
         if req.authname == 'anonymous':
             req.redirect(self.env.href.wiki())
@@ -296,6 +316,8 @@
     def process_request(self, req):
         if req.authname != 'anonymous':
             req.redirect(self.env.href.account())
+	if req.scheme.lower() != 'https':
+	    req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, None, None)))
         action = req.args.get('action')
         if req.method == 'POST' and action == 'create':
             try:
@@ -303,7 +325,7 @@
             except TracError, e:
                 req.hdf['registration.error'] = e.message
             else:
-                req.redirect(self.env.href.login())
+                req.redirect(self.env.href.login() + '?referer=/')
         req.hdf['reset_password_enabled'] = \
             (self.env.is_component_enabled(AccountModule)
              and NotificationSystem(self.env).smtp_enabled)
@@ -355,14 +377,59 @@
                 req.hdf['trac.href.reset_password'] = req.href.reset_password()
             if req.method == 'POST':
                 req.hdf['login.error'] = 'Invalid username or password'
+
+	    if req.scheme.lower() != 'https':
+	        querystr = ''
+	        if req.hdf['referer']:
+		    querystr = 'referer=' + req.hdf['referer']
+
+	    	req.redirect(urlparse.urlunparse(('https', req.server_name, req.base_path + req.path_info, None, querystr, None)))
+
             return 'login.cs', None
         return auth.LoginModule.process_request(self, req)
 
+    def _get_name_for_cookie(self, req, cookie):
+        name = auth.LoginModule._get_name_for_cookie(self, req, cookie)
+        if name and not req.incookie.has_key('trac_auth_session'):
+            self.env.log.debug('Updating auth cookie %s for user %s' % 
+                               (cookie.value, name))
+            db = self.env.get_db_cnx()
+            cursor = db.cursor()
+            cursor.execute('UPDATE auth_cookie SET time=%s WHERE cookie=%s',
+                           (int(time.time()), cookie.value))
+            req.outcookie['trac_auth'] = cookie.value
+            req.outcookie['trac_auth']['path'] = self.env.href()
+            req.outcookie['trac_auth']['expires'] = 86400 * 30
+            req.outcookie['trac_auth_session'] = '1'
+            req.outcookie['trac_auth_session']['path'] = self.env.href()
+        return name
+        
     def _do_login(self, req):
         if not req.remote_user:
             req.redirect(self.env.abs_href())
-        return auth.LoginModule._do_login(self, req)
+        res = auth.LoginModule._do_login(self, req)
+        if req.args.get('rememberme', '0') == '1':
+            req.outcookie['trac_auth']['expires'] = 86400 * 30
+        return res
 
+    def _do_logout(self, req):
+        """Log the user out.
+
+        Simply deletes the corresponding record from the auth_cookie table.
+        """
+        if req.authname == 'anonymous':
+            # Not logged in
+            return
+
+        # While deleting this cookie we also take the opportunity to delete
+        # cookies older than 30 days
+        db = self.env.get_db_cnx()
+        cursor = db.cursor()
+        cursor.execute("DELETE FROM auth_cookie WHERE name=%s OR time < %s",
+                       (req.authname, int(time.time()) - 86400 * 30))
+        db.commit()
+        self._expire_cookie(req)
+        
     def _remote_user(self, req):
         user = req.args.get('user')
         password = req.args.get('password')
@@ -375,9 +442,16 @@
     def _redirect_back(self, req):
         """Redirect the user back to the URL she came from."""
         referer = self._referer(req)
-        if referer and not referer.startswith(req.base_url):
-            # don't redirect to external sites
-            referer = None
+        if referer:
+            u = urlparse.urlparse(referer)
+            r = urlparse.urlparse(req.base_url)
+	    if u[1] != r[1]:
+                # don't redirect to external sites
+                referer = self.env.abs_href()
+                u = urlparse.urlparse(referer)
+	    r = tuple(['http', u[1], u[2], None, None, None])
+	    referer = urlparse.urlunparse(r)
+
         req.redirect(referer or self.env.abs_href())
 
     def _referer(self, req):
Index: acct_mgr/templates/login.cs
===================================================================
--- acct_mgr/templates/login.cs	(revision 1709)
+++ acct_mgr/templates/login.cs	(working copy)
@@ -24,6 +24,9 @@
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" class="textwidget" size="20" />
   </div>
+  <div>
+    <input type="checkbox" id="rememberme" name="rememberme" value="1" /> <label for="rememberme">Remember me</label>
+  </div>
   <input type="submit" value="Login" />
 
   <?cs if trac.href.reset_password ?>
