[Kimchi-devel] [PATCH V2 1/2] bug fix: redirect to the protected page after login

shaohef at linux.vnet.ibm.com shaohef at linux.vnet.ibm.com
Thu Jun 19 11:00:11 UTC 2014


From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>

add a 'next' attribute in login html page.

if "next" is not None, means there is a html protected page user
want to access. after authentication success, redirect to it.

if "next" is None, then redirect to the last page recorde in th the
cookie.

Test this case:
1. input a protected page URL in the browser.
such as:
https://localhost:8001/spice.html?port=64667&listen=localhost&token=vmname&encrypt=1

2. input a wrong password or username:
it should report:
"The username or password you entered is incorrect. Please try again."

3. input the right password and username:
It should redirect to the former page.
https://localhost:8001/spice.html?port=64667&listen=localhost&token=vmname&encrypt=1

Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
---
 src/kimchi/auth.py       | 18 ++++++++++++------
 src/kimchi/root.py       | 34 +++++++++++++++++++---------------
 ui/pages/login.html.tmpl |  3 ++-
 3 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 59889ed..c7f94a7 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -28,7 +28,6 @@
 import re
 import termios
 import time
-import urllib2
 
 
 from kimchi import template
@@ -43,9 +42,13 @@
 
 
 def redirect_login():
-    next_url = urllib2.quote(
-        cherrypy.request.path_info.encode('utf-8'), safe="")
-    raise cherrypy.HTTPRedirect("/login.html?next=%s" % next_url, 303)
+    url = "/login.html"
+    if cherrypy.request.path_info.endswith(".html"):
+        next_url = cherrypy.serving.request.request_line.split()[1]
+        next_url = base64.urlsafe_b64encode(next_url)
+        url = "/login.html?next=%s" % next_url
+
+    raise cherrypy.HTTPRedirect(url, 303)
 
 
 def debug(msg):
@@ -194,7 +197,7 @@ def check_auth_httpba():
     return login(username, password)
 
 
-def login(username, password):
+def login(username, password, **kwargs):
     try:
         if not authenticate(username, password):
             debug("User cannot be verified with the supplied password")
@@ -202,7 +205,10 @@ def login(username, password):
     except PAM.error, (resp, code):
         if (cherrypy.request.path_info == "/login" and
            not template.can_accept('application/json')):
-            raise cherrypy.HTTPRedirect("/login.html?error=userPassWrong", 303)
+            next_url = kwargs.get("next")
+            url = "/login.html?error=userPassWrong"
+            url = url if next_url is None else url + "&next=%s" % next_url
+            raise cherrypy.HTTPRedirect(url, 303)
         msg_args = {'username': username, 'code': code}
         raise OperationFailed("KCHAUTH0001E", msg_args)
 
diff --git a/src/kimchi/root.py b/src/kimchi/root.py
index f2b6a53..82bd97b 100644
--- a/src/kimchi/root.py
+++ b/src/kimchi/root.py
@@ -17,6 +17,7 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 
+import base64
 import cherrypy
 import json
 import os
@@ -122,25 +123,28 @@ def __init__(self, model, dev_env):
     def login(self, *args, **kwargs):
         username = kwargs.get('username')
         password = kwargs.get('password')
-        # forms base authentication
+        # traditional form base authentication
+        kwa = {}
         if username is not None:
-            next_url = cherrypy.request.cookie.get("lastPage")
+            # UI can parser the redirect url by "next" query parameter
+            next_url = kwargs.get('next')
+            next_url = next_url[0] if(type(next_url) is list) else next_url
             if next_url is None:
-                # UI can parser the redirect url by "next" query parameter
-                next_url = kwargs.get('next', "/")
-                next_url = next_url[0] if(type(next_url) is list) else next_url
+                lastPage = cherrypy.request.cookie.get("lastPage")
+                next_url = lastPage.value if lastPage is not None else "/"
             else:
-                next_url = next_url.value
-            auth.login(username, password)
+                kwa = {"next": next_url.encode("utf-8")}
+                next_url = base64.urlsafe_b64decode(next_url.encode("utf-8"))
+            auth.login(username, password, **kwa)
             raise cherrypy.HTTPRedirect(next_url, 303)
-        else:
-            try:
-                params = parse_request()
-                username = params['username']
-                password = params['password']
-            except KeyError, item:
-                e = MissingParameter('KCHAUTH0003E', {'item': str(item)})
-                raise cherrypy.HTTPError(400, e.message)
+
+        try:
+            params = parse_request()
+            username = params['username']
+            password = params['password']
+        except KeyError, item:
+            e = MissingParameter('KCHAUTH0003E', {'item': str(item)})
+            raise cherrypy.HTTPError(400, e.message)
 
         try:
             user_info = auth.login(username, password)
diff --git a/ui/pages/login.html.tmpl b/ui/pages/login.html.tmpl
index 0fa7122..f8f683d 100644
--- a/ui/pages/login.html.tmpl
+++ b/ui/pages/login.html.tmpl
@@ -21,6 +21,7 @@
 #silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang)
 #silent _ = t.gettext
 #silent _t = t.gettext
+#silent next = "?next=%s" % $getVar('data.next', '') if $getVar('data.next', '') else ""
 #from kimchi.config import get_version
 <!DOCTYPE html>
 <html lang="$lang.lang[0]">
@@ -99,7 +100,7 @@ function init() {
         <div id="messUserPass" class="err-mess" style="display: none;">$_("The username or password you entered is incorrect. Please try again.")</div>
         <div id="messSession" class="err-mess" style="display: none;">$_("Session timeout, please re-login.")</div>
     </div>
-    <form id="form-login" action="/login" method="POST" class="login-panel" onsubmit="updateBtnLabel();">
+    <form id="form-login" action="/login$next" method="POST" class="login-panel" onsubmit="updateBtnLabel();">
         <div class="row">
             <input type="text" id="username" name="username" required="required" placeholder="$_("User Name")" autofocus/>
             <div id="username-msg" class="msg-required"></div>
-- 
1.9.3




More information about the Kimchi-devel mailing list