[Kimchi-devel] [PATCH V3 2/5] redirect the URL to login page when session timeout or first login

Sheldon shaohef at linux.vnet.ibm.com
Tue Jun 10 14:02:42 UTC 2014


On 06/10/2014 09:27 PM, Aline Manera wrote:
> On 06/10/2014 09:42 AM, Sheldon wrote:
>> On 06/10/2014 02:11 AM, Aline Manera wrote:
>>> On 06/05/2014 01:10 PM, shaohef at linux.vnet.ibm.com wrote:
>>>> From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
>>>>
>>>> If the content type is application/json still raise 401 status code.
>>>> And let UI redirect to login page.
>>>>
>>>> or the backe redirects to login page directly.
>>>>
>>>> Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
>>>> Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
>>>> ---
>>>> src/kimchi/auth.py | 11 +++++++++++
>>>> src/kimchi/config.py.in | 3 +++
>>>> src/kimchi/root.py | 28 +++++++++++++++++++---------
>>>> ui/js/src/kimchi.main.js | 5 +----
>>>> 4 files changed, 34 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
>>>> index dc78ded..a38dbd3 100644
>>>> --- a/src/kimchi/auth.py
>>>> +++ b/src/kimchi/auth.py
>>>> @@ -28,6 +28,7 @@
>>>> import re
>>>> import termios
>>>> import time
>>>> +import urllib2
>>>>
>>>>
>>>> from kimchi import template
>>>> @@ -41,6 +42,12 @@
>>>> REFRESH = 'robot-refresh'
>>>>
>>>>
>>>> +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)
>>>> +
>>>> +
>>>> def debug(msg):
>>>> pass
>>>> # cherrypy.log.error(msg)
>>>> @@ -234,6 +241,10 @@ def kimchiauth(admin_methods=None):
>>>> raise cherrypy.HTTPError(403)
>>>> return
>>>>
>>>> + # not a REST full request, redirect login page directly
>>>> + if not template.can_accept('application/json'):
>>>> + redirect_login()
>>>> +
>>>> if not from_browser():
>>>> cherrypy.response.headers['WWW-Authenticate'] = 'Basic realm=kimchi'
>>>>
>>>> diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in
>>>> index 0206570..d4cbda0 100644
>>>> --- a/src/kimchi/config.py.in
>>>> +++ b/src/kimchi/config.py.in
>>>> @@ -187,6 +187,9 @@ class KimchiConfig(dict):
>>>> '/spice.html': {
>>>> 'tools.kimchiauth.on': True
>>>> },
>>>> + '/kimchi-ui.html': {
>>>> + 'tools.kimchiauth.on': True
>>>> + },
>>>> '/data/screenshots': {
>>>> 'tools.staticdir.on': True,
>>>> 'tools.staticdir.dir': get_screenshot_path(),
>>>> diff --git a/src/kimchi/root.py b/src/kimchi/root.py
>>>> index 8b1d09b..181ab13 100644
>>>> --- a/src/kimchi/root.py
>>>> +++ b/src/kimchi/root.py
>>>> @@ -81,7 +81,7 @@ def get(self):
>>>> @cherrypy.expose
>>>> def default(self, page, **kwargs):
>>>> if page.endswith('.html'):
>>>> - return template.render(page, None)
>>>> + return template.render(page, kwargs)
>>>> raise cherrypy.HTTPError(404)
>>>>
>>>> @cherrypy.expose
>>>> @@ -110,14 +110,24 @@ def __init__(self, model, dev_env):
>>>> self.messages = messages
>>>>
>>>> @cherrypy.expose
>>>> - def login(self, *args):
>>>> - params = parse_request()
>>>> - try:
>>>> - username = params['username']
>>>> - password = params['password']
>>>> - except KeyError, item:
>>>> - e = MissingParameter('KCHAUTH0003E', {'item': str(item)})
>>>> - raise cherrypy.HTTPError(400, e.message)
>>>
>>>> + def login(self, *args, **kwargs):
>>>> + username = kwargs.get('username')
>>>> + password = kwargs.get('password')
>>>> + # forms base authentication
>>>> + if username is not None:
>>>> + # UI can pass the redirect url by "next" query parameter
>>>> + next_url = kwargs.get('next', "/")
>>>> + next_url = type(next_url) is list and next_url[0]
>>>> + auth.login(username, password)
>>>> + 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)
>>>
>>> I didn't understand this code.
>>> Why did you get username and password from kwargs and in "else" from 
>>> parse_request()?
>>> Should that info be in a single location?
>> parse_request() get the password and username from body for REST API 
>> request.
>> for form authentication. The cherrypy will do it by itself, and pass 
>> it to login
>
> And when in which situation we get the username and password from kwargs?
>
> PS. Sorry about too many questions but I am trying to understand the 
> code =)

Request Headersview source
Accept 	|text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8|
Accept-Encoding 	|gzip, deflate|
Accept-Language 	|zh-cn,en-us;q=0.7,en;q=0.3|
Connection 	|keep-alive|
Cookie 	|userid=root; kimchiLang=zh_CN; username=shhfeng; 
ticketVM=VqO6AWlH; lastPage="/#tabs/templates"; 
kimchi||=fc2fa059ee694c3d959fa1a1902557d21526e78e|
DNT 	|1|
Host 	|localhost:8001|
Referer 	|https://localhost:8001/login.html|
User-Agent 	|Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 
Firefox/29.0|

Request Headers From Upload Stream
Content-Length 	|41|
Content-Type 	|application/x-www-form-urlencoded|



post body.
I think the cherrypy know x-www-form-urlencoded, it can parser the body 
by itself.

Parametersapplication/x-www-form-urlencoded
next 	|/|
password 	|123456|
username 	|shhfeng|

Source
|next=%2F&username=shhfeng&password=123456|



By our rest quest,  the Content-Type is application/json we paser it by 
ourself.


I have check the cherrypy code:  some explanation for 
application/x-www-form-urlencoded

     def _get_body_params(self):
         warnings.warn(
                 "body_params is deprecated in CherryPy 3.2, will be 
removed in "
                 "CherryPy 3.3.",
                 DeprecationWarning
             )
         return self.body.params
     body_params = property(_get_body_params,
                       doc= """
     If the request Content-Type is 'application/x-www-form-urlencoded' or
     multipart, this will be a dict of the params pulled from the entity
     body; that is, it will be the portion of request.params that come
     from the message body (sometimes called "POST params", although they
     can be sent with various HTTP method verbs). This value is set between
     the 'before_request_body' and 'before_handler' hooks (assuming that
     process_request_body is True).

     Deprecated in 3.2, will be removed for 3.3 in favor of
:attr:`request.body.params<cherrypy._cprequest.RequestBody.params>`.""")


>>>
>>> And if you raise/return, you don't need a "else" it eliminates some 
>>> indentation levels.
>> I can remove the “else”
>>>
>>>> try:
>>>> user_info = auth.login(username, password)
>>>> diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js
>>>> index 184029d..2a8f461 100644
>>>> --- a/ui/js/src/kimchi.main.js
>>>> +++ b/ui/js/src/kimchi.main.js
>>>> @@ -227,10 +227,7 @@ kimchi.main = function() {
>>>> kimchi.previousAjax = ajaxSettings;
>>>> $(".empty-when-logged-off").empty();
>>>> $(".remove-when-logged-off").remove();
>>>> - kimchi.window.open({
>>>> - url: 'login-window.html',
>>>> - id: 'login-window-wrapper'
>>>> - });
>>>> + document.location.href='login.html';
>>>> return;
>>>> }
>>>> else if((jqXHR['status'] == 0) && ("error"==jqXHR.statusText)) {
>>>
>>>
>>>
>>
>>
>
>
>


-- 
Thanks and best regards!

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ovirt.org/pipermail/kimchi-devel/attachments/20140610/beec68fe/attachment.html>


More information about the Kimchi-devel mailing list