<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 6/6/2014 12:10 AM,
      <a class="moz-txt-link-abbreviated" href="mailto:shaohef@linux.vnet.ibm.com">shaohef@linux.vnet.ibm.com</a> wrote:<br>
    </div>
    <blockquote
      cite="mid:1401984638-13103-6-git-send-email-shaohef@linux.vnet.ibm.com"
      type="cite">
      <pre wrap="">From: ShaoHe Feng <a class="moz-txt-link-rfc2396E" href="mailto:shaohef@linux.vnet.ibm.com">&lt;shaohef@linux.vnet.ibm.com&gt;</a>

When session timeout, come back to login page with an
error message.

When session logout, close session directly.

Signed-off-by: ShaoHe Feng <a class="moz-txt-link-rfc2396E" href="mailto:shaohef@linux.vnet.ibm.com">&lt;shaohef@linux.vnet.ibm.com&gt;</a>
---
 src/kimchi/auth.py       | 21 +++++++++++++++++++--
 src/kimchi/config.py.in  |  4 ++++
 src/kimchi/server.py     |  2 ++
 ui/js/src/kimchi.main.js |  3 ++-
 ui/pages/login.html.tmpl |  2 ++
 5 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 9cb40d3..dcdd74a 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -161,7 +161,7 @@ def check_auth_session():
                     cherrypy.session.timeout * 60):
                 cherrypy.session[USER_NAME] = None
                 cherrypy.lib.sessions.expire()
-                raise cherrypy.HTTPError(401)
+                raise cherrypy.HTTPError(401, "sessionTimeout")
         else:
             cherrypy.session[REFRESH] = time.time()
         return True
@@ -223,7 +223,7 @@ def logout():
     cherrypy.session[USER_NAME] = None
     cherrypy.session[REFRESH] = 0
     cherrypy.session.release_lock()
-    cherrypy.lib.sessions.expire()
+    cherrypy.lib.sessions.close()


 def has_permission(admin_methods):
@@ -238,6 +238,7 @@ def has_permission(admin_methods):

 def kimchiauth(admin_methods=None):
     debug("Entering kimchiauth...")
+    session_missing = cherrypy.session.missing
     if check_auth_session():
         if not has_permission(admin_methods):
             raise cherrypy.HTTPError(403)
@@ -252,8 +253,24 @@ def kimchiauth(admin_methods=None):
     if not template.can_accept('application/json'):
         redirect_login()

+    # from browser, and it stays on one page.
+    if session_missing and cherrypy.request.cookie.get("lastPage") is not None:
+        raise cherrypy.HTTPError(401, "sessionTimeout")
+
     if not from_browser():
         cherrypy.response.headers['WWW-Authenticate'] = 'Basic realm=kimchi'

     e = InvalidOperation('KCHAUTH0002E')
     raise cherrypy.HTTPError(401, e.message.encode('utf-8'))
+
+
+def kimchisession(admin_methods=None):
+    session = cherrypy.request.cookie.get("kimchi")
+    last_page = cherrypy.request.cookie.get("lastPage")
+    # when client browser first login in, both the session and lastPage cookie
+    # are None.
+    # when session timeout, only session cookie is None.
+    if (session is None and last_page is None and
+       template.can_accept('text/html')):
+        if last_page is None:
+            redirect_login()
diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in
index d4cbda0..f557516 100644
--- a/src/kimchi/config.py.in
+++ b/src/kimchi/config.py.in
@@ -179,6 +179,7 @@ class KimchiConfig(dict):
             'tools.sessions.locking': 'explicit',
             'tools.sessions.storage_type': 'ram',
             'tools.sessions.timeout': SESSIONSTIMEOUT,
+            'tools.kimchisession.on': True,
             'tools.kimchiauth.on': False
         },
         '/vnc_auto.html': {
@@ -190,6 +191,9 @@ class KimchiConfig(dict):
        '/kimchi-ui.html': {
             'tools.kimchiauth.on': True
         },
+       '/login.html': {
+            'tools.kimchisession.on': False,
+        },
         '/data/screenshots': {
             'tools.staticdir.on': True,
             'tools.staticdir.dir': get_screenshot_path(),
diff --git a/src/kimchi/server.py b/src/kimchi/server.py
index 7344349..30140ce 100644
--- a/src/kimchi/server.py
+++ b/src/kimchi/server.py
@@ -77,6 +77,8 @@ def __init__(self, options):
         cherrypy.tools.nocache = cherrypy.Tool('on_end_resource', set_no_cache)
         cherrypy.tools.kimchiauth = cherrypy.Tool('before_handler',
                                                   auth.kimchiauth)
+        cherrypy.tools.kimchisession = cherrypy.Tool('before_request_body',
+                                                     auth.kimchisession)
         # Setting host to 127.0.0.1. This makes kimchi runs
         # as a localhost app, inaccessible to the outside
         # directly. You must go through the proxy.
diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js
index 2a8f461..78971f8 100644
--- a/ui/js/src/kimchi.main.js
+++ b/ui/js/src/kimchi.main.js
@@ -223,11 +223,12 @@ kimchi.main = function() {
             }

             if (jqXHR['status'] === 401) {
+                var isSessionTimeout = jqXHR['responseText'].indexOf("sessionTimeout")!=-1;
                 kimchi.user.showUser(false);
                 kimchi.previousAjax = ajaxSettings;
                 $(".empty-when-logged-off").empty();
                 $(".remove-when-logged-off").remove();
-                document.location.href='login.html';
+                document.location.href= isSessionTimeout ? 'login.html<font color="#ff0000"><u>/</u></font>?error=sessionTimeout' : 'login.html';</pre>
    </blockquote>
    remove the '/' before '?'<br>
    <pre wrap="">document.location.href= isSessionTimeout ? 'login.html?error=sessionTimeout' : 'login.html';</pre>
    <br>
    <blockquote
      cite="mid:1401984638-13103-6-git-send-email-shaohef@linux.vnet.ibm.com"
      type="cite">
      <pre wrap="">
                 return;
             }
             else if((jqXHR['status'] == 0) &amp;&amp; ("error"==jqXHR.statusText)) {
diff --git a/ui/pages/login.html.tmpl b/ui/pages/login.html.tmpl
index fc6cee6..4a7c87e 100644
--- a/ui/pages/login.html.tmpl
+++ b/ui/pages/login.html.tmpl
@@ -185,6 +185,8 @@ function setMessage() {
     var err = "$getVar('data.error', '')";
     if(err=="userPassWrong")
         document.getElementById("messUserPass").style.display = "";
+    if(err=="sessionTimeout")
+        document.getElementById("messSession").style.display = "";
 }
 function init() {
     setLang();
</pre>
    </blockquote>
    <br>
  </body>
</html>