Finish mono account management for biblio, improve mapping management

and fix model

 * mandaye/__init__.py: load sqlachemy session
 * mandaye/auth/authform.py: add account management
 * mandaye/auth/vincennes.py: add account management
 * mandaye/configs/biblio_vincennes.py: add vincennes conf
 * mandaye/dispatcher.py; improve mapping management
This commit is contained in:
Jérôme Schneider 2011-09-16 19:13:17 +02:00
parent 7285c43a26
commit e6fc815ff5
14 changed files with 327 additions and 147 deletions

View File

@ -1 +1,15 @@
VERSION=0.1 VERSION=0.1
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from mandaye.config import db_url
# an Engine, which the Session will use for connection
# resources
sql_engine = create_engine(db_url)
# create a configured "Session" class
Session = sessionmaker(bind=sql_engine)
# create a Session
sql_session = Session()

View File

@ -1,4 +1,3 @@
import ipdb
""" """
Dispatcher for basic auth form authentifications Dispatcher for basic auth form authentifications
""" """
@ -9,7 +8,10 @@ import urllib
from urlparse import parse_qs from urlparse import parse_qs
from mandaye.http import HTTPResponse import mandaye
from mandaye.models import Site, ExtUser, LocalUser
from mandaye.http import HTTPResponse, HTTPHeader
from mandaye.response import _500, _302, _401 from mandaye.response import _500, _302, _401
from mandaye.response import template_response from mandaye.response import template_response
@ -47,42 +49,71 @@ class AuthForm(object):
""" """
return template_response(values['template'], values) return template_response(values['template'], values)
def associate_submit(self, env, values, request, condition=None): def associate_submit(self, env, values, condition, request, response):
""" Associate your login / password with Mandaye
""" """
""" pseudo = env['beaker.session'].get('pseudo')
session = env['beaker.session']
if request.msg: if request.msg:
post = parse_qs(request.msg.read()) post = parse_qs(request.msg.read())
response = self._replay(env, post['username'][0], post['password'][0]) replay_response = self._replay(env, post['username'][0], post['password'][0])
if eval(condition): if eval(condition):
if not session.has_key('pseudo'): if not pseudo:
# Find a way to put this in the configuration return _302(values.get('connection_url'))
return _302("/mandaye/connection")
else: else:
# TODO associate this login / password in the db site = mandaye.sql_session.query(Site).\
pass filter_by(name=values.get('site_name')).first()
return template_response(values['template'], values) if not site:
site = Site(values.get('site_name'))
mandaye.sql_session.add(site)
local_user = mandaye.sql_session.query(LocalUser).\
filter_by(token=pseudo).first()
if not local_user:
local_user = LocalUser(token=pseudo)
mandaye.sql_session.add(local_user)
ext_user = mandaye.sql_session.query(ExtUser).join(LocalUser).\
filter(LocalUser.token==pseudo).first()
if not ext_user:
ext_user = ExtUser()
mandaye.sql_session.add(ext_user)
ext_user.login = post['username'][0]
ext_user.password = post['password'][0]
ext_user.local_user = local_user
mandaye.sql_session.commit()
return _302(values.get('connection_url'))
return response
def check_auth(self, env, values, request=None): def check_auth(self, env, values, request=None):
""" values: dict witth username, login """ values: dict witth username, login
""" """
pass pass
def login(self, env, values, request): def login(self, env, values, condition, request):
""" Automatic login on a site with a form """ Automatic login on a site with a form
""" """
login = self.local_auth.get_current_login(env) login = self.local_auth.get_current_login(env)
if not login: if not login:
return _401('Access denied: invalid token') return _401('Access denied: invalid token')
#if not values.has_key('form_action') \ ext_user = mandaye.sql_session.query(ExtUser).\
# or not values.has_key('form_values') \ join(LocalUser).\
# or not values.has_key('username_field') \ filter(LocalUser.token==login).\
# or not values.has_key('password_field'): first()
# return _500(env['PATH_INFO'], if not ext_user:
# 'Invalid values for AuthFormDispatcher.login') return _302(values.get('associate_url'))
# TODO: Test get the username / password here if not ext_user.login or not ext_user.password:
#response = self._replay(env, return _500(env['PATH_INFO'],
#return _302(location, cookies) 'Invalid values for AuthFormDispatcher.login')
response = self._replay(env, ext_user.login, ext_user.password)
headers = HTTPHeader()
headers.load_from_list(response.getheaders())
cookies = Cookie.BaseCookie(response.msg.getheader('set-cookie'))
response = HTTPResponse(response.status, response.reason, headers,
response.read(), cookies)
if condition and eval(condition):
return response
else:
# TODO; find a better solution
return _302(values.get('associate_url'))
def connection(self, values, response): def connection(self, values, response):
pass pass

View File

@ -6,7 +6,7 @@ import traceback
from Crypto.Cipher import AES from Crypto.Cipher import AES
from mandaye.dispatchers.auth import AuthFormDispatcher #from mandaye.dispatchers.auth import AuthFormDispatcher
from mandaye.response import _502, _302 from mandaye.response import _502, _302
class VincennesAuth(object): class VincennesAuth(object):
@ -44,7 +44,6 @@ class VincennesAuth(object):
session = env['beaker.session'] session = env['beaker.session']
session['pseudo'] = info['pseudo'] session['pseudo'] = info['pseudo']
session.save() session.save()
print info['pseudo']
return info['pseudo'] return info['pseudo']
except Exception, e: except Exception, e:
if config.debug: if config.debug:
@ -55,8 +54,10 @@ class VincennesAuth(object):
def connection(self, env, values, request): def connection(self, env, values, request):
""" Connection to the compte citoyen """ Connection to the compte citoyen
""" """
dest_url = "%s://%s%s" % (env['wsgi.url_scheme'], env['HTTP_HOST'],
values.get('next_url'))
location = "%s?next_url=%s&service=%s" % \ location = "%s?next_url=%s&service=%s" % \
(self.url, values.get('next_url'), values.get('service_name')) (self.url, dest_url, values.get('service_name'))
return _302(location) return _302(location)

View File

View File

@ -0,0 +1,78 @@
from mandaye.filters.vincennes import biblio_html, biblio_html_login_page
from mandaye.filters.vincennes import biblio_associate_login, biblio_associate_req
from mandaye.filters.default import MandayeFilter
from mandaye.configs.vincennes import auth_vincennes, authform
biblio_mapping = [
{
'path': r'/',
'on_response': [{'filter': biblio_html}]
},
{
'path': r'/mandaye/login$',
'method': 'GET',
'response': {
'filter': authform.login,
'values': { 'associate_url': '/mandaye/associate' },
'condition': 'response.code==302',
},
},
{
'path': r'/mandaye/associate$',
'method': 'GET',
'target': 'http://biblio.vincennes.fr/sezhame/page/connexion-abonne',
'on_response': [{
'filter': biblio_associate_login,
'values': {
'action': '/mandaye/associate',
'template': 'biblio_associate.html',
},
}]
},
{
'path': r'/mandaye/associate$',
'method': 'POST',
'target': 'http://biblio.vincennes.fr/sezhame/page/connexion-abonne',
'on_request': [{'filter': biblio_associate_req}],
'on_response': [
{
'filter': authform.associate_submit,
'values': {
'site_name': 'biblio',
'connection_url': '/mandaye/connection'
},
'condition': "replay_response.status==302"
},
{
'filter': biblio_associate_login,
'values': {
'action': '/mandaye/associate',
'template': 'biblio_associate.html',
'error_msg': "Mauvais numéro ou mot de passe",
},
},
]
},
{
'path': r'/mandaye/connection$',
'method': 'GET',
'response': {
'filter': auth_vincennes.connection,
'values': {
'destination': 'https://test.vincennes.fr/comptecitoyen/auth',
'next_url': '/mandaye/login',
'service_name': 'biblio'
}
}
},
{
'path': r'/sezhame/page/connexion-abonne$',
'method': 'GET',
'on_response': [{'filter': biblio_html_login_page}]
},
]

View File

@ -0,0 +1,16 @@
from mandaye.auth.authform import AuthForm
from mandaye.auth.vincennes import VincennesAuth
form_values = {
'form_action': '/sezhame/page/connexion-abonne',
'from_headers': { 'Content-Type': 'application/x-www-form-urlencoded' },
'form_values': { 'user': '',
'password': '',
'op': 'Se connecter',
'form_id': 'dk_opac15_login_form' },
'username_field': 'user',
'password_field': 'password'
}
auth_vincennes = VincennesAuth('https://test.vincennes.fr/comptecitoyen/auth')
authform = AuthForm(auth_vincennes, **form_values)

View File

@ -27,11 +27,10 @@ class Dispatcher(object):
""" parse the mapping on every request """ parse the mapping on every request
""" """
req_mapping = { req_mapping = {
'on_request_hook': None, 'on_request': [],
'on_request_filters': [], 'on_response': [],
'on_response_hook': None,
'on_response_filters': [],
'response': None, 'response': None,
'target': None
} }
for conf in mapping: for conf in mapping:
@ -47,12 +46,17 @@ class Dispatcher(object):
req_mapping[hookname] = conf[hookname] req_mapping[hookname] = conf[hookname]
return req_mapping return req_mapping
def _call_dispatcher_hook(self, hook, *args): def _call_hook(self, hook, *args):
if hook and hook.has_key('method'): if hook and hook.has_key('filter'):
values = hook.get('values') values = hook.get('values')
if not values: if not values:
values = dict() values = dict()
return hook['method'](self.env, values, *args) if hook.has_key('condition'):
return hook['filter'](self.env, values, hook['condition'], *args)
else:
return hook['filter'](self.env, values, *args)
else:
logging.warning("%s hook failed (no filter option)" % self.env['PATH_INFO'])
return None return None
def get_target_url(self): def get_target_url(self):
@ -61,8 +65,10 @@ class Dispatcher(object):
# Disable reverse proxy if we have a static response # Disable reverse proxy if we have a static response
if self.req_mapping['response']: if self.req_mapping['response']:
return None return None
# TODO: manage redirect here if self.req_mapping['target']:
url = self.target.geturl() + self.env['PATH_INFO'] url = self.req_mapping['target']
else:
url = self.target.geturl() + self.env['PATH_INFO']
if self.env['QUERY_STRING']: if self.env['QUERY_STRING']:
return url + "?" + self.env['QUERY_STRING'] return url + "?" + self.env['QUERY_STRING']
else: else:
@ -71,18 +77,12 @@ class Dispatcher(object):
def get_response(self, request): def get_response(self, request):
""" Called if you have a response hook for this request """ Called if you have a response hook for this request
""" """
if self.req_mapping['response'].has_key('condition'): response = self._call_hook(self.req_mapping['response'],
response = self._call_dispatcher_hook(self.req_mapping['response'],
request, self.req_mapping['response']['condition'])
else:
response = self._call_dispatcher_hook(self.req_mapping['response'],
request) request)
if not response: if not response:
return _500(self.env["PATH_INFO"], "The response hook failed") return _500(self.env["PATH_INFO"], "The response hook failed")
# loading defaults filters # loading defaults filters
response.headers = self.filter.response_headers(response.headers) response = self.filter.on_response(response)
response.cookies = self.filter.response_cookies(response.cookies)
response.msg = self.filter.response_msg(response.msg)
return response return response
def mod_request(self, request): def mod_request(self, request):
@ -90,23 +90,16 @@ class Dispatcher(object):
request: MandayeRequest object with cookies and headers request: MandayeRequest object with cookies and headers
Return the request object """ Return the request object """
# Loading defaults filters # Loading defaults filters
request.headers = self.filter.request_headers(request.headers) request = self.filter.on_request(request)
request.cookies = self.filter.request_cookies(request.cookies)
request.msg = self.filter.request_msg(request.msg)
# Loading specific filters
for filter in self.req_mapping['on_request_filters']:
if filter['type'] == "data":
request.msg = filter['filter'](request.msg, self.env)
elif filter['type'] == "cookies":
request.cookies = filter['filter'](request.cookies, self.env)
elif filter['type'] == "headers":
request.headers = filter['filter'](request.headers, self.env)
# Calling hook function # Calling hook function
if self.req_mapping['on_request_hook']: for hook in self.req_mapping['on_request']:
return self._call_dispatcher_hook( new_request = self._call_hook(hook, request)
self.req_mapping['on_request_hook'], request) if new_request:
request = new_request
else:
logging.warning("%s On_request hook %s failed" % (self.env['PATH_INFO'],
self.req_mapping['on_request']['filter']))
return request return request
def mod_response(self, request, response): def mod_response(self, request, response):
@ -116,23 +109,16 @@ class Dispatcher(object):
you can modify the cookies and the HTTP headers """ you can modify the cookies and the HTTP headers """
# loading defaults filters # loading defaults filters
response.headers = self.filter.response_headers(response.headers) response = self.filter.on_response(response)
response.cookies = self.filter.response_cookies(response.cookies)
response.msg = self.filter.response_msg(response.msg)
# Loading specific filters
for filter in self.req_mapping['on_response_filters']:
if filter['type'] == "data":
response.msg = filter['filter'](response.msg, self.env)
elif filter['type'] == "cookies":
response.cookies = filter['filter'](response.cookies, self.env)
elif filter['type'] == "headers":
response.headers = filter['filter'](response.headers, self.env)
# Calling hook function # Calling hook function
if self.req_mapping['on_response_hook']: for hook in self.req_mapping['on_response']:
return self._call_dispatcher_hook( new_response = self._call_hook(hook, request, response)
self.req_mapping['on_response_hook'], request, response) if new_response:
response = new_response
else:
logging.warning("%s On_response hook %s failed" % (self.env['PATH_INFO'],
self.req_mapping['on_response']['filter']))
return response return response

View File

@ -14,57 +14,28 @@ class MandayeFilter(object):
self.env = env self.env = env
self.target = target self.target = target
def request_cookies(self, cookies): def on_request(self, request):
""" cookies: a Cookie.BaseCookie referer = request.headers.getheader('referer')
http://docs.python.org/library/cookie.html
return a Cookie.BaseCookie
"""
return cookies
def request_headers(self, headers):
""" headers: HTTPHeader instance
return HTTPHeader object
"""
referer = headers.getheader('referer')
if referer: if referer:
referer = referer.replace(self.self.env["HTTP_HOST"], self.target.hostname) referer = referer.replace(self.env["HTTP_HOST"], self.target.hostname)
headers.addheader("Referer", referer) request.headers.addheader("Referer", referer)
return headers return request
def request_msg(self, msg): def on_response(self, response):
""" msg: request message body # Modify cookies
return the modify message
"""
return msg
def response_cookies(self, cookies):
""" cookies: a Cookie.BaseCookie object
return a Cookie.BaseCookie
"""
src_hostname = re.sub(":\d*$", "", self.env["HTTP_HOST"]) src_hostname = re.sub(":\d*$", "", self.env["HTTP_HOST"])
for cookie in cookies.values(): for cookie in response.cookies.values():
if cookie.has_key('domain'): if cookie.has_key('domain'):
cookie['domain'] = cookie['domain'].replace(self.target.hostname, src_hostname) cookie['domain'] = cookie['domain'].replace(self.target.hostname, src_hostname)
return cookies # Modify headers
def response_headers(self, headers):
""" headers: HTTPHeader instance
return a HTTPHeader object
"""
blacklist = ['transfer-encoding', 'content-length'] blacklist = ['transfer-encoding', 'content-length']
for key, value in headers.iteritems(): for key, value in response.headers.iteritems():
if key == 'location': if key == 'location':
location = value[0].replace(self.target.hostname, location = value[0].replace(self.target.hostname,
self.env["HTTP_HOST"]) self.env["HTTP_HOST"])
headers.addheader(key, location) response.headers.addheader(key, location)
for name in blacklist: for name in blacklist:
if headers.has_key(name): if response.headers.has_key(name):
del headers[name] del response.headers[name]
return headers return response
def response_msg(self, msg):
""" msg: response message body
return the modify message """
return msg

View File

@ -1,18 +1,39 @@
import re import re
def biblio_html_login_page(data, env): from mandaye.response import serve_template
""" data: response message body
def biblio_html_login_page(env, values, request, response):
""" msg: response message body
env: Mandaye environment env: Mandaye environment
""" """
data = re.sub("</center></div>", response.msg = re.sub("</center></div>",
"<a href=\"/mandaye/connection\">Connection via mon compte citoyen</center></div>", "<a href=\"/mandaye/connection\">Connection via mon compte citoyen</center></div>",
data) response.msg)
return data return response
def biblio_html(data, env): def biblio_html(env, values, request, response):
""" Global html filter the Vincenne library """ Global html filter the Vincenne library
This fix the fucking absolute url of the biblio site This fix the fucking absolute url of the biblio site
""" """
data = data.replace(env["target"].hostname, env["HTTP_HOST"]) response.msg = response.msg.replace(env["target"].hostname, env["HTTP_HOST"])
return data return response
def biblio_associate_req(env, values, request):
""" Modify the association request
"""
request.req_method = 'GET'
if request.headers.has_key('Content-Type'):
del request.headers['Content-Type']
return request
def biblio_associate_login(env, values, request, response):
""" Use default login page to associate an account on the SSO
"""
pattern = re.compile('<div class="inner">.*</center></div>\s+</div></div>',
re.MULTILINE | re.DOTALL)
form = serve_template(values.get('template'), **values)
form = form.encode('utf-8')
response.msg = re.sub(pattern, form, response.msg)
return response

View File

@ -14,6 +14,12 @@ class HTTPHeader(dict):
for key in headers.keys(): for key in headers.keys():
self[key] = headers.getheaders(key) self[key] = headers.getheaders(key)
def load_from_list(self, headers):
""" headers: list with the headers
"""
for header in headers:
self[header[0]] = [header[1]]
def addheader(self, name, value): def addheader(self, name, value):
""" name: field name """ name: field name
value: string with the field value """ value: string with the field value """
@ -55,27 +61,28 @@ class HTTPHeader(dict):
class HTTPRequest(object): class HTTPRequest(object):
def __init__(self, cookies, headers, msg=None): def __init__(self, cookies, headers, req_method, msg=None):
""" cookies: """
""" """
self.cookies = cookies self.cookies = cookies
self.headers = headers self.headers = headers
self.msg = msg self.msg = msg
self.req_method = req_method
class HTTPResponse(object): class HTTPResponse(object):
""" Mandaye HTTP Response """ Mandaye HTTP Response
""" """
def __init__(self, code=None, status=None, headers=None, msg=None, cookies=None): def __init__(self, code=None, reason=None, headers=None, msg=None, cookies=None):
""" """
code: integer return code (200, 302, 404, ..) code: integer return code (200, 302, 404, ..)
status: string with http status (ex: OK, Not Found, ...) reason: string with http status (ex: OK, Not Found, ...)
headers: dictionary with the headers headers: dictionary with the headers
msg: message body str msg: message body str
""" """
self.code = code self.code = code
self.status = status self.reason = reason
self.headers = headers self.headers = headers
self.msg = msg self.msg = msg
self.cookies = cookies self.cookies = cookies
@ -88,11 +95,9 @@ class HTTPResponse(object):
""" response: urrlib.addinfourl """ response: urrlib.addinfourl
""" """
self.headers.load_httpmessage(response.headers) self.headers.load_httpmessage(response.headers)
if self.headers.has_key('set-cookie'):
del self.headers['set-cookie']
for setcookie in response.headers.getheaders('set-cookie'): for setcookie in response.headers.getheaders('set-cookie'):
self.cookies.load("Set-Cookie: %s" % setcookie) self.cookies.load("Set-Cookie: %s" % setcookie)
self.code = response.code self.code = response.code
self.status = response.msg self.reason = response.msg
self.msg = response.read() self.msg = response.read()

View File

@ -13,22 +13,36 @@ class Site(Base):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
name = Column(String, unique=True, nullable=False) name = Column(String, unique=True, nullable=False)
def __init__(self, name):
self.name = name
def __repr__(self):
return "<Site('%s')>" % (self.name)
class LocalUser(Base): class LocalUser(Base):
""" Mandaye local user """ Mandaye local user
""" """
__tablename__ = 'local_users' __tablename__ = 'local_users'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
login = Column(String, nullable=True) login = Column(String(80), nullable=True)
fullname = Column(String, nullable=True) fullname = Column(String(150), nullable=True)
password = Column(String, nullable=True) password = Column(String, nullable=True)
token = Column(String, nullable=True) token = Column(String(150), nullable=True)
def __init__(self, login, password): def __init__(self, login=None, password=None,
fullname=None, token=None):
self.login = login
self.password = password self.password = password
self.fullname = fullname
self.token = token
def __repr__(self): def __repr__(self):
return "<User('%s)>" % (self.login) if self.login:
return "<LocalUser('%s')>" % (self.login)
elif self.token:
return "<LocalUser('%s')>" % (self.token)
return "<LocalUser>"
class ExtUser(Base): class ExtUser(Base):
""" User of externals applications """ User of externals applications
@ -36,22 +50,26 @@ class ExtUser(Base):
__tablename__ = 'ext_users' __tablename__ = 'ext_users'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
login = Column(String, nullable=True) login = Column(String(80), nullable=True)
password = Column(String, nullable=True) password = Column(String, nullable=True)
token = Column(String, nullable=True) token = Column(String(200), nullable=True)
local_user_id = Column(Integer, ForeignKey('local_users.id')) local_user_id = Column(Integer, ForeignKey('local_users.id'))
site_id = Column(Integer, ForeignKey('sites.id')) site_id = Column(Integer, ForeignKey('sites.id'))
local_user = relationship("LocalUser", backref=backref('ext_users', order_by=id)) local_user = relationship("LocalUser", backref=backref('ext_users', order_by=id))
site = relationship("LocalUser", backref=backref('users')) site = relationship("LocalUser", backref=backref('users'))
def __init__(self, login, password, token): def __init__(self, login=None, password=None, token=None):
self.login = login self.login = login
self.password = password self.password = password
self.token = token self.token = token
def __repr__(self): def __repr__(self):
return "<User('%s')>" % (self.login) if self.login:
return "<ExtUser('%s')>" % (self.login)
elif self.token:
return "<ExtUser('%s')>" % (self.token)
return "<ExtUser>"

View File

@ -9,7 +9,8 @@ from mako.template import Template
from mandaye.http import HTTPResponse, HTTPHeader from mandaye.http import HTTPResponse, HTTPHeader
from mandaye.config import template_directory, debug from mandaye.config import template_directory, debug
mylookup = TemplateLookup(directories=[template_directory]) mylookup = TemplateLookup(directories=[template_directory],
input_encoding='utf-8')
def serve_template(templatename, **kwargs): def serve_template(templatename, **kwargs):
mytemplate = mylookup.get_template(templatename) mytemplate = mylookup.get_template(templatename)

View File

@ -20,7 +20,7 @@ from gevent.pywsgi import WSGIServer
from mandaye.dispatcher import Dispatcher from mandaye.dispatcher import Dispatcher
from mandaye.handlers.default import MandayeRedirectHandler, MandayeErrorHandler from mandaye.handlers.default import MandayeRedirectHandler, MandayeErrorHandler
from mandaye.http import HTTPHeader, HTTPRequest, HTTPResponse from mandaye.http import HTTPHeader, HTTPRequest, HTTPResponse
from mandaye.response import _404, _502 from mandaye.response import _404, _502, _500
# Init poster # Init poster
opener = poster.streaminghttp.register_openers() opener = poster.streaminghttp.register_openers()
@ -77,7 +77,7 @@ class MandayeApp(object):
else: else:
msg = None msg = None
return HTTPRequest(cookies, headers, msg) return HTTPRequest(cookies, headers, self.env['REQUEST_METHOD'], msg)
def on_request(self, start_response): def on_request(self, start_response):
mrequest = self._get_request() mrequest = self._get_request()
@ -90,17 +90,18 @@ class MandayeApp(object):
if not url: if not url:
return self.on_response(start_response, return self.on_response(start_response,
self.dispatcher.get_response(mrequest)) self.dispatcher.get_response(mrequest))
if self.env['REQUEST_METHOD'] == 'POST': if mrequest.req_method == 'POST':
data = self.env['wsgi.input'].read() req = urllib2.Request(url, mrequest.msg, mrequest.headers.getheaders())
req = urllib2.Request(url, data, mrequest.headers.getheaders())
else: else:
req = urllib2.Request(url, headers=mrequest.headers.getheaders()) req = urllib2.Request(url, headers=mrequest.headers.getheaders())
# Load the cookies # Load the cookies
req.add_header('cookie', mrequest.cookies.output(sep=',', header='')) req.add_header('cookie', mrequest.cookies.output(sep=',', header=''))
print req.headers
try: try:
opener = urllib2.build_opener(MandayeErrorHandler, MandayeRedirectHandler) opener = urllib2.build_opener(MandayeErrorHandler, MandayeRedirectHandler)
response = opener.open(req) response = opener.open(req)
except Exception, e: except Exception, e:
response.close()
response = _502(self.env['PATH_INFO'], req.get_host(), e) response = _502(self.env['PATH_INFO'], req.get_host(), e)
return self.on_response(start_response, response) return self.on_response(start_response, response)
else: else:
@ -113,7 +114,7 @@ class MandayeApp(object):
""" start_response: wsgi start_response """ start_response: wsgi start_response
response: an instance of HTTPResponse """ response: an instance of HTTPResponse """
response.headers.addsetcookies(response.cookies) response.headers.addsetcookies(response.cookies)
start_response('%d %s' % (response.code, response.status), start_response('%d %s' % (response.code, response.reason),
response.headers.items()) response.headers.items())
return [response.msg] return [response.msg]

View File

@ -0,0 +1,37 @@
<div class="inner">
<h1 class="title">Associer votre compte</h1>
% if error_msg:
<div class="messages error">
${error_msg}
</div>
% endif
<div class="node" id="node-470">
<div class="content">
<strong><u>N° de carte</u></strong> = les <u>6 derniers numéros </u>de&nbsp; la carte <br>
<strong><u>Mot de passe</u></strong> = lors de la <u>première connexion votre nom de famille</u>
</div>
</div>
<div class="block-connexion-utilisateur clear-block block block-dk_opac15" id="block-dk_opac15-login"><div id="blockContent">
<h2><div>Associer votre compte au compte citoyen</div></h2>
<div class="content"><center>
<form id="dk-opac15-login-form" method="post" accept-charset="UTF-8" action="${action}">
<div><div class="form-item">
<label for="edit-user">Numéro de carte&nbsp;: <span title="Ce champ est obligatoire." class="form-required">*</span></label>
<input type="text" class="form-text required error" value="fdssdf" size="19" id="edit-user" name="username" maxlength="128">
</div>
<div class="form-item">
<label for="edit-password">Mot de passe&nbsp;: <span title="Ce champ est obligatoire." class="form-required">*</span></label>
<input type="password" class="form-text required" size="19" id="edit-password" name="password">
</div>
<input type="submit" class="form-submit" value="Associer" id="edit-submit" name="op">
<input type="hidden" value="dk_opac15_login_form" id="edit-dk-opac15-login-form" name="form_id">
</div></form>
</center></div>
</div></div>