On 06/10/2014 02:22 AM, Aline Manera wrote:
On 06/05/2014 01:10 PM, shaohef@linux.vnet.ibm.com wrote:
From: ShaoHe Feng <shaohef@linux.vnet.ibm.com>

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

When session logout, close session directly.

Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com>
---
  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")
+

Why is it needed?
The session timeout is handled in check_auth_session() which already return cherrypy.HTTPError(401, "sessionTimeout")

here is the difference between kimchi and lastPage cookie.
kimchi cookie set expires. but lastPage does set it.
also we set lastPage only for browser.  not for REST Full request.

when session timeout, cherrypy will clean session data.
check_auth_session will check session data. no session date may means session timeout or http base authentication.
 


Here is the session cookie ID and lastPage cookie.
nginx/1.4.7
kimchi=02fff0323dbe0bfbffb6f377e48ac5d9802de890; expires=Wed, 11 Jun 2014 03:33:34 GMT; httponly; Path=/; secure lastPage="/#tabs/templates"; Path=/
max-age=31536000; includeSubdomains;



      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/?error=sessionTimeout' : 'login.html';
                  return;
              }
              else if((jqXHR['status'] == 0) && ("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();





-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com>
IBM Linux Technology Center