
From: ShaoHe Feng <shaohef@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@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