Improve authform and begin duonet support
* mandaye/auth/authform.py: add action auto detection * mandaye/configs/duonet_vincennes.py: begin duonet mapping * mandaye/server.py: improve cookiejar support in get_response * mandaye/templates/duonet_associate.html: the associate template * mandaye/filters/vincennes.py: begin duonet support
This commit is contained in:
parent
133a9a931f
commit
b316506ed2
|
@ -18,31 +18,55 @@ from mandaye.server import get_response
|
|||
|
||||
class AuthForm(object):
|
||||
|
||||
def __init__(self, local_auth, form_action, form_url, form_headers,
|
||||
form_values, username_field, password_field):
|
||||
def __init__(self, local_auth, form_values):
|
||||
""" local_auth: instance of your local authentification system
|
||||
form_values: dict example :
|
||||
{
|
||||
'form_action': '/myform',
|
||||
'form_url': '/myform',
|
||||
'form_attrs': { 'name': 'form40', },
|
||||
'username_field': 'user',
|
||||
'password_field': 'pwd'
|
||||
}
|
||||
"""
|
||||
self.local_auth = local_auth
|
||||
|
||||
self.form_action = form_action
|
||||
self.form_url = form_url
|
||||
self.form_headers = form_headers
|
||||
if not form_values.has_key('form_headers'):
|
||||
form_values['form_headers'] = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'User-Agent': 'Mozilla/5.0 Mandaye/0.0'
|
||||
}
|
||||
|
||||
if not form_values.has_key('form_url') or \
|
||||
not form_values.has_key('form_attrs') or \
|
||||
not form_values.has_key('username_field') or \
|
||||
not form_values.has_key('password_field'):
|
||||
logging.critical("Bad configuration: AuthForm form_values dict must have \
|
||||
this keys: form_url, form_attrs, username_field and password_field")
|
||||
# TODO: manage Mandaye exceptions
|
||||
raise BaseException, 'AuthForm bad configuration'
|
||||
|
||||
self.form_url = form_values['form_url']
|
||||
self.form_values = form_values
|
||||
self.username_field = username_field
|
||||
self.password_field = password_field
|
||||
|
||||
def replay(self, env, username, password, **kwargs):
|
||||
""" replay the login / password
|
||||
"""
|
||||
cj = CookieJar()
|
||||
request = HTTPRequest()
|
||||
if not "://" in self.form_url:
|
||||
self.form_url = env['target'].geturl() + self.form_url
|
||||
cj = CookieJar()
|
||||
request = HTTPRequest()
|
||||
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 = soup.find('form', **self.form_values['form_attrs'])
|
||||
if not self.form_values.has_key('from_action'):
|
||||
action = 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" %
|
||||
(self.env['HTTP_HOST'], self.env['PATH_INFO'], self.form_url))
|
||||
|
@ -50,7 +74,7 @@ class AuthForm(object):
|
|||
|
||||
cookies = login.cookies
|
||||
headers = HTTPHeader()
|
||||
headers.load_from_dict(self.form_headers)
|
||||
headers.load_from_dict(self.form_values['form_headers'])
|
||||
params = {}
|
||||
for input in form.findAll('input'):
|
||||
if input['type'] != "submit" and input['type'] != 'button' \
|
||||
|
@ -59,15 +83,13 @@ class AuthForm(object):
|
|||
params[input['name']] = input['value']
|
||||
else:
|
||||
params[input['name']] = ''
|
||||
params[self.username_field] = username
|
||||
params[self.password_field] = password
|
||||
params[self.form_values['username_field']] = username
|
||||
params[self.form_values['password_field']] = password
|
||||
for key, value in kwargs:
|
||||
params[key] = value
|
||||
params = urllib.urlencode(params)
|
||||
request = HTTPRequest(cookies, headers, "POST", params)
|
||||
if not "://" in self.form_action:
|
||||
self.form_action = env['target'].geturl() + self.form_action
|
||||
return get_response(env, request, self.form_action, cj)
|
||||
return get_response(env, request, action, cj)
|
||||
|
||||
def associate(self, env, values, request):
|
||||
""" Render the associate page
|
||||
|
|
|
@ -9,14 +9,12 @@ from mandaye.configs.vincennes import auth_vincennes
|
|||
|
||||
form_values = {
|
||||
'form_url': '/sezhame/page/connexion-abonne',
|
||||
'form_action': '/sezhame/page/connexion-abonne?destination=user',
|
||||
'form_headers': { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
'form_values': { 'id': 'dk-opac15-login-form', },
|
||||
'form_attrs': { 'id': 'dk-opac15-login-form', },
|
||||
'username_field': 'user',
|
||||
'password_field': 'password'
|
||||
}
|
||||
|
||||
authform = AuthForm(auth_vincennes, **form_values)
|
||||
authform = AuthForm(auth_vincennes, form_values)
|
||||
|
||||
|
||||
biblio_mapping = [
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
from mandaye.auth.authform import AuthForm
|
||||
from mandaye.auth.vincennes import VincennesAuth
|
||||
|
||||
from mandaye.filters.vincennes import Duonet
|
||||
from mandaye.filters.default import MandayeFilter
|
||||
|
||||
from mandaye.configs.vincennes import auth_vincennes
|
||||
|
||||
filters = Duonet()
|
||||
|
||||
form_values = {
|
||||
'form_url': 'Connect.aspx?key=CV4j27Em0dM%3d',
|
||||
'form_attrs': { 'name': 'form1', },
|
||||
'username_field': 'txtNomFoyer',
|
||||
'birthdate_field': 'txtDateNaissance',
|
||||
'password_field': 'txtCode',
|
||||
}
|
||||
|
||||
authform = AuthForm(auth_vincennes, form_values)
|
||||
|
||||
|
||||
duonet_mapping = [
|
||||
{
|
||||
'path': r'/vincennes/login$',
|
||||
'method': 'GET',
|
||||
'response': [{
|
||||
'filter': authform.login,
|
||||
'values': { 'associate_url': '/vincennes/associate' },
|
||||
'condition': 'response.code==302',
|
||||
},]
|
||||
},
|
||||
{
|
||||
'path': r'/associate$',
|
||||
'method': 'GET',
|
||||
'target': 'https://extranet.duonet.fr/Connect.aspx?key=CV4j27Em0dM%3d',
|
||||
'on_response': [{
|
||||
'filter': filters.resp_associate,
|
||||
'values': {
|
||||
'action': '/associate',
|
||||
'template': 'duonet_associate.html',
|
||||
},
|
||||
}]
|
||||
},
|
||||
# {
|
||||
# 'path': r'/vincennes/associate$',
|
||||
# 'method': 'POST',
|
||||
# 'response': [
|
||||
# {
|
||||
# 'filter': authform.associate_submit,
|
||||
# 'values': {
|
||||
# 'site_name': 'espace_famille',
|
||||
# 'connection_url': '/vincennes/connection',
|
||||
# 'failed_url': 'https://vincennes.espace-famille.net/vincennes/index.do'
|
||||
# },
|
||||
# 'condition': "response.code==302"
|
||||
# },
|
||||
# {
|
||||
# 'filter': filters.resp_associate,
|
||||
# 'values': {
|
||||
# 'action': '/vincennes/associate',
|
||||
# 'template': 'famille_associate.html',
|
||||
# 'error_msg': "Code famille et/ou mot de passe incorrects",
|
||||
# },
|
||||
# },
|
||||
# ]
|
||||
# },
|
||||
{
|
||||
'path': r'/vincennes/connection$',
|
||||
'method': 'GET',
|
||||
'response': [{
|
||||
'filter': auth_vincennes.connection,
|
||||
'values': {
|
||||
'destination': 'https://test.vincennes.fr/comptecitoyen/auth',
|
||||
'next_url': '/vincennes/login',
|
||||
'service_name': 'biblio'
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
'path': r'/Connect.aspx$',
|
||||
'method': 'GET',
|
||||
'on_response': [{
|
||||
'filter': filters.resp_login_page,
|
||||
'values': {'connection_url': '/vincennes/connection'}}]
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -10,25 +10,13 @@ from mandaye.configs.vincennes import auth_vincennes
|
|||
filters = EspaceFamille()
|
||||
|
||||
form_values = {
|
||||
'form_action': '/vincennes/index.do',
|
||||
'form_url': '/vincennes/index.do',
|
||||
'form_headers': { 'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
|
||||
'Accept-language': 'fr-FR,en-US;q=0.8,en;q=0.6',
|
||||
'Accept-encoding': 'gzip,deflate,sdch',
|
||||
'Accept': 'text/css,*/*;q=0.1',
|
||||
'Accept-charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
|
||||
'Connection': 'keep-alive',
|
||||
'Pragma': 'no-cache',
|
||||
'Origin': 'https://vincennes.espace-famille.net',
|
||||
'Referer': 'https://vincennes.espace-famille.net/vincennes/login.do',
|
||||
'Cache-control': 'no-cache',},
|
||||
'form_values': { 'action': 'login.do', },
|
||||
'form_attrs': { 'action': 'login.do', },
|
||||
'username_field': 'codeFamille',
|
||||
'password_field': 'motDePasse'
|
||||
}
|
||||
|
||||
authform = AuthForm(auth_vincennes, **form_values)
|
||||
authform = AuthForm(auth_vincennes, form_values)
|
||||
|
||||
|
||||
famille_mapping = [
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import ipdb
|
||||
|
||||
import re
|
||||
|
||||
|
@ -47,7 +48,6 @@ class EspaceFamille:
|
|||
def resp_associate(self, env, values, request, response):
|
||||
"""docstring for resp_associate_login"""
|
||||
if response.msg:
|
||||
#response.msg = response.msg.replace('./config/', '/vincennes/config/')
|
||||
soup = BeautifulSoup(response.msg)
|
||||
div = soup.find('div', {'class': 'bloc-model-1'})
|
||||
if div:
|
||||
|
@ -58,3 +58,30 @@ class EspaceFamille:
|
|||
return response
|
||||
|
||||
|
||||
class Duonet:
|
||||
|
||||
def resp_login_page(self, env, values, request, response):
|
||||
"""docstring for resp_login_page"""
|
||||
if response.msg:
|
||||
soup = BeautifulSoup(response.msg)
|
||||
table = soup.find('table', {'id': 'tbConnect'})
|
||||
input = table.find('input', type='submit')
|
||||
input.append('<a href=\"%s\">Connection via mon compte citoyen</a>' % \
|
||||
values['connection_url'])
|
||||
response.msg = str(soup)
|
||||
return response
|
||||
|
||||
def resp_associate(self, env, values, request, response):
|
||||
"""docstring for resp_associate_login"""
|
||||
if response.msg:
|
||||
soup = BeautifulSoup(response.msg)
|
||||
form = soup.find('form', {'name': 'form1'})
|
||||
if form:
|
||||
new_form = serve_template(values.get('template'), **values)
|
||||
new_form.encode('utf-8')
|
||||
form.replaceWith(new_form)
|
||||
response.msg = str(soup)
|
||||
return response
|
||||
|
||||
def associate_submit(self, env, values, request, response):
|
||||
pass
|
||||
|
|
|
@ -54,15 +54,16 @@ def get_response(env, request, url, cookiejar=None):
|
|||
if cookiejar:
|
||||
response.cookies = Cookie.SimpleCookie()
|
||||
for cookie in cookiejar:
|
||||
if response.cookies.has_key(cookie.name):
|
||||
del response.cookies[cookie.name]
|
||||
response.cookies[cookie.name] = cookie.value
|
||||
if cookie.expires:
|
||||
response.cookies[cookie.name]['expires'] = cookie.expires
|
||||
else:
|
||||
del response.cookies[cookie.name]['expires']
|
||||
if cookie.domain:
|
||||
response.cookies[cookie.name]['domain'] = cookie.domain
|
||||
if cookie.path:
|
||||
response.cookies[cookie.name]['path'] = cookie.path
|
||||
# TODO: add the other RFC 2109 cookie values
|
||||
resp.close()
|
||||
return response
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
<form name="form1" method="post" action="${action}" id="form1">
|
||||
|
||||
<center>
|
||||
|
||||
<div id="divMargin" style="height:100px"></div>
|
||||
<div id="pnlLogin" style="text-align:center;">
|
||||
|
||||
|
||||
<input type="hidden" name="hd" id="hd" value="800;1000" />
|
||||
<table width="100%" align="center">
|
||||
<tr >
|
||||
<td colspan="2" align="center">
|
||||
<img id="imgMain" src="http://www.parapharmacie-defrance.fr/lien/logo_mairie_vincennes.gif" style="height:120px;border-width:0px;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td colspan="2" style="padding-top:10px;padding-bottom:15px">
|
||||
<div style="border:solid 1px black" >
|
||||
<span id="lblSchoolName" style="font-size:XX-Large;">Associer votre compte</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td colspan="2" align="center" lang="fr">
|
||||
<table>
|
||||
<tr valign="top">
|
||||
<td style="display:none">
|
||||
<a id="hlkExt" title="Nouveaux élève(s)/Consultation/Espace publique de l'établissement" href="External/Default.aspx" style="font-weight:bold;">Pas encore inscrit(e)?</a>
|
||||
</td>
|
||||
<td>
|
||||
<div id="pnlLog" style="background-color:LightGrey;">
|
||||
<table align="center" id="tbConnect" style="padding:10px 10px 10px 10px">
|
||||
|
||||
<tr>
|
||||
<td align="right">
|
||||
<span id="lblPassword">Nom de famille</span>
|
||||
</td>
|
||||
<td align="left">
|
||||
<input name="username" type="text" id="txtNomFoyer" autocomplete="off" style="font-weight:bold;" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="right">
|
||||
<span id="lblDateDeNaissance">Date de Naissance</span>
|
||||
</td>
|
||||
|
||||
<td align="left">
|
||||
<input name="birthdate" type="text" id="txtDateNaissance" autocomplete="off" style="font-weight:bold;" />
|
||||
<span id="lblPassword1" style="font-size:XX-Small;font-style:italic;">(Ex: 16/06/2008)</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td align="right">
|
||||
<span id="lblLogin">Code DuoNET</span>
|
||||
</td>
|
||||
<td align="left" style="padding-left:3px">
|
||||
<input name="password" type="password" maxlength="13" id="txtCode" autocomplete="off" style="font-weight:bold;width:121px;" />
|
||||
<span id="lblPassword2" style="font-size:XX-Small;font-style:italic;">(Ex: 1994000001001)</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td align="center" colspan="2">
|
||||
<input type="submit" name="btnConnect" value="Associer" id="btnConnect" style="font-weight:bold;" />
|
||||
<div id="upChooseRole">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<center>
|
||||
|
||||
% if error_msg:
|
||||
<span id="lblError" style="color:Red;font-weight:bold;">${error_msg}</span>
|
||||
% endif
|
||||
</center>
|
||||
</div>
|
||||
</center>
|
||||
|
||||
<div id="pnlLoadModal" style="background-color:White;border:solid 1px black;padding:3px 3px 3px 3px;display:none">
|
||||
<img id="imgLoadModal" src="Images/loading1.gif" style="border-width:0px;" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<div class="bloc-model-1">
|
||||
<h2>Associer votre compte au compte citoyen</h2>
|
||||
<div class="bloc-gris">
|
||||
<form action="${action}" method="post">
|
||||
<div class="form">
|
||||
% if error_msg:
|
||||
<div id="list-errors">
|
||||
<p class="errors"><b>${error_msg}</b><br></p>
|
||||
</div>
|
||||
% endif
|
||||
<div class="firstline">
|
||||
<label for="cdfmll" class="first"><b>⇒</b> Code famille</label> :
|
||||
<input type="text" id="cdfmll" class="txt" name="username" title="Indiquez votre code famille"><br>
|
||||
<label for="mtdpss"><b>⇒</b> Mot de passe</label> :
|
||||
<input type="password" id="mtdpss" class="txt" name="password" title="Indiquez votre mot de passe"></div>
|
||||
<input type="submit" class="submit" value="Associer"><br>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
Reference in New Issue