diff --git a/mandaye/auth/authform.py b/mandaye/auth/authform.py index 9af88df..4fe9435 100644 --- a/mandaye/auth/authform.py +++ b/mandaye/auth/authform.py @@ -1,3 +1,4 @@ +import ipdb """ Dispatcher for basic auth form authentifications """ @@ -10,8 +11,9 @@ import mandaye from cookielib import CookieJar from datetime import datetime +from lxml.html import fromstring from urlparse import parse_qs -from BeautifulSoup import BeautifulSoup +#from BeautifulSoup import BeautifulSoup from mandaye.models import Site, ExtUser, LocalUser from mandaye.http import HTTPResponse, HTTPHeader, HTTPRequest @@ -55,14 +57,6 @@ this keys: form_url, form_attrs, username_field and password_field") self.form_values = form_values self.site_name = site_name - def __get_full_url(self, url, env): - """ url: full or relative url - """ - if re.match("http://|https://", url): - return url - else: - return env['target'].geturl() + url - def replay(self, env, username, password, extra_values={}): """ replay the login / password env: WSGI env with beaker session and the target @@ -75,29 +69,43 @@ this keys: form_url, form_attrs, username_field and password_field") login = get_response(env, request, self.form_url, cj) if login.code == 502: return login - soup = BeautifulSoup(login.msg) - form = soup.find('form', self.form_values['form_attrs']) + html = fromstring(login.msg) + auth_form = None + for form in html.forms: + is_good = True + for key, value in self.form_values['form_attrs'].iteritems(): + if form.get(key) != value: + is_good = False + if is_good: + auth_form = form + break + + if auth_form == None: + logging.critical("%s %s: can't find login form on %s" % + (env['HTTP_HOST'], env['PATH_INFO'], self.form_url)) + return _500(env['PATH_INFO'], "Replay: Can't find login form") + if not self.form_values.has_key('from_action'): - action = form['action'] + if not auth_form.action: + logging.critical("%s %s: don't find form action on %s" % + (env['HTTP_HOST'], env['PATH_INFO'], self.form_url)) + return _500(env['PATH_INFO'], 'Replay: form action not found') + action = auth_form.action else: action = self.form_values['form_action'] if not "://" in action: action = env['target'].geturl() + '/' + action - if not form: - logging.warning("%s %s: can't find login form on %s" % - (env['HTTP_HOST'], env['PATH_INFO'], self.form_url)) - return _500("Can't find login form") cookies = login.cookies headers = HTTPHeader() headers.load_from_dict(self.form_values['form_headers']) params = {} - for input in form.findAll('input'): - if input.has_key('name'): - if input.has_key('value'): - params[input['name']] = input['value'] + for input in auth_form.inputs: + if input.name and input.type != 'button': + if input.value: + params[input.name] = input.value else: - params[input['name']] = '' + params[input.name] = '' params[self.form_values['username_field']] = username params[self.form_values['password_field']] = password for key, value in extra_values.iteritems(): @@ -114,8 +122,7 @@ this keys: form_url, form_attrs, username_field and password_field") post = parse_qs(request.msg.read(), request) if not post.has_key('username') or not post.has_key('password'): logging.info('Auth failed: form not correctly filled') - failed_url = self.__get_full_url(values.get('failed_url'), env) - return get_response(env, HTTPRequest(), failed_url) + return _302(values.get('associate_url') + "?type=badlogin") username = post['username'][0] # TODO: generized this part (use a generic key / value table) extra_values = {}