Index: acct_mgr/web_ui.py
===================================================================
--- acct_mgr/web_ui.py	(revision 4111)
+++ acct_mgr/web_ui.py	(working copy)
@@ -13,12 +13,16 @@
 import os
 import random
 import string
+import time
+import re
+import urlparse
 
 from trac import perm, util
 from trac.core import *
 from trac.config import IntOption
 from trac.notification import NotificationSystem, NotifyEmail
 from trac.prefs import IPreferencePanelProvider
+from trac.util.text import unicode_urlencode
 from trac.web import auth
 from trac.web.api import IAuthenticator
 from trac.web.main import IRequestHandler, IRequestFilter
@@ -53,6 +57,9 @@
     if password != req.args.get('password_confirm'):
         raise TracError('The passwords must match.')
 
+    if not req.args.get('email'):
+        raise TracError('You must enter a valid Email address.')
+
     mgr.set_password(user, password)
 
     db = env.get_db_cnx()
@@ -157,6 +164,25 @@
                           'store does not support writing.')
         return writable
 
+
+    def _redirect_to_scheme(self, req, scheme):
+        self.log.debug("Forwarding to '%s' for '%s%s'" % (scheme, req.base_path, req.path_info))
+        referer_param = req.args.get('referer')
+        if referer_param:
+            referer_param = "referer=%s" % referer_param
+        req.redirect(urlparse.urlunparse((scheme, req.server_name, req.base_path + req.path_info, None, referer_param, None)))
+
+    def _needs_ssl(self, path_info):
+        return re.match('/prefs(?:/([^/]+))?', path_info) \
+               or path_info == '/reset_password' \
+               or path_info == '/register' \
+               or path_info == '/login' \
+               or path_info == '/admin/accounts/users'
+
+    def _needs_session_cookie(self, path_info):
+        return re.match('/admin(?:/([^/]+))?', path_info) \
+               or path_info == '/prefs/account'
+
     #IPreferencePanelProvider methods
     def get_preference_panels(self, req):
         if not self._write_check():
@@ -179,6 +205,23 @@
 
     # IRequestFilter methods
     def pre_process_request(self, req, handler):
+
+        ssl_path = self._needs_ssl(req.path_info)
+        # Catch the user leaving an ssl path /prefs and redirect to non-secure
+        if req.scheme.lower() == 'https' and not ssl_path:
+            self._redirect_to_scheme(req, 'http')
+        # Catch the user entering /prefs or and redirect to secure
+        elif ssl_path:
+            if req.scheme.lower() != 'https':
+                self._redirect_to_scheme(req, 'https')
+
+        # If we're accessing a page that you should be logged in the current session for, deal with it
+        if self._needs_session_cookie(req.path_info) \
+                and not req.incookie.has_key('trac_auth_session'):
+            self.log.debug("Accessing %s requires a session login, forwarding to login screen." % req.path_info)
+            referal_url = urlparse.urlunparse((ssl_path and 'https' or 'http', req.server_name, req.base_path + req.path_info, None, None, None))
+            req.redirect(self.env.href.login() + '?%s' % unicode_urlencode({'referer' : referal_url, 'force_session' : '1'}))
+
         return handler
 
     def post_process_request(self, req, template, data, content_type):
@@ -377,7 +420,11 @@
             except TracError, e:
                 data['registration_error'] = e.message
             else:
-                req.redirect(req.href.login())
+                redirect_url = None
+                referer = req.args.get('referer')
+                if referer:
+                    redirect_url = "%s?referer=%s" % (req.href.login(), referer)
+                req.redirect(redirect_url or req.href.login())
         data['reset_password_enabled'] = \
             (self.env.is_component_enabled(AccountModule)
              and NotificationSystem(self.env).smtp_enabled)
@@ -422,7 +469,7 @@
     match_request = if_enabled(auth.LoginModule.match_request)
 
     def process_request(self, req):
-        if req.path_info.startswith('/login') and req.authname == 'anonymous':
+        if req.path_info.startswith('/login') and (req.authname == 'anonymous' or req.args.get('force_session')):
             data = {
                 'referer': self._referer(req),
                 'reset_password_enabled': AccountModule(self.env).reset_password_enabled
@@ -432,11 +479,50 @@
             return 'login.html', data, 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
+            req.outcookie['trac_auth_session'] = '1'
+            req.outcookie['trac_auth_session']['path'] = self.env.href()
+        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')
@@ -449,9 +535,12 @@
     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] and u[1] != r[1]:
+                # don't redirect to external sites
+                referer = None
         req.redirect(referer or self.env.abs_href())
 
     def _referer(self, req):
@@ -576,3 +665,4 @@
     def _send_email(self, req):
         notifier = EmailVerificationNotification(self.env)
         notifier.notify(req.authname, req.session['email_verification_token'])
+
Index: acct_mgr/templates/register.html
===================================================================
--- acct_mgr/templates/register.html	(revision 4111)
+++ acct_mgr/templates/register.html	(working copy)
@@ -24,6 +24,7 @@
       </div>
 
       <form method="post" id="acctmgr_registerform" action="">
+        <input type="hidden" name="referer" value="${req.args.get('referer')}" />
         <fieldset>
           <legend>Required</legend>
           <div>
@@ -43,9 +44,6 @@
                      class="textwidget" size="20" />
             </label>
           </div>
-        </fieldset>
-        <fieldset>
-          <legend>Optional</legend>
           <div>
             <label>Name:
               <input type="text" name="name" class="textwidget" size="20" />
Index: acct_mgr/templates/login.html
===================================================================
--- acct_mgr/templates/login.html	(revision 4111)
+++ acct_mgr/templates/login.html	(working copy)
@@ -28,12 +28,16 @@
         <input type="hidden" name="referer" value="${referer}" />
         <div>
           <label for="user">Username:</label>
-          <input type="text" id="user" name="user" class="textwidget" size="20" />
+          <input type="text" id="user" name="user" class="textwidget" size="20" value="${req.authname != 'anonymous' and req.authname or None}"/>
         </div>
         <div>
           <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" checked="${req.authname != 'anonymous' and req.authname or None}"/>  
+          <label for="rememberme">Remember me</label>  
+        </div>  
         <input type="submit" value="Login" />
 
         <p py:if="reset_password_enabled">
