From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
add a next attribute in login html page.
if "next" is not None, it 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&tok...
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&tok...
Signed-off-by: ShaoHe Feng <shaohef(a)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