* extra/modules/liberty.py:

- add timeout parameter to soap_call function, default = 240s
 - escape content of SoapFault/Detail relaying python exceptions
 - handle desynchronization of state of federation:
   - if asking for creation when on already exist, switch automatically to
     requesting,
   - if asking for an existing federation switch to creation.
 - rework user clicking 'Back' (or MSP refusing to authenticate us):
   - when user click 'Back' on msp page, return to /login if not logged locally
     else return to '/'.
 - replace authentic original soap_call function with the authentic-adeline
   version
 - add printing of reponse, destination url and timing of soap calls
This commit is contained in:
root 2008-10-23 11:37:53 +02:00
parent d0e4936cbc
commit aa2bdf2299
1 changed files with 74 additions and 31 deletions

View File

@ -6,6 +6,8 @@ import Cookie
import StringIO
import cgi
import traceback
import socket
import xml.sax.saxutils
import lasso
@ -116,38 +118,64 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
try:
login.processResponseMsg(soap_answer)
except lasso.Error, error:
# Traitement d'une demande de federation existante
# apres désynchro, on recree a la volee
if error[0] == lasso.LOGIN_ERROR_FEDERATION_NOT_FOUND:
t = self.proxy_auth_federation_not_found(login)
if t:
return t
if error[0] != lasso.LOGIN_ERROR_UNKNOWN_PRINCIPAL:
try:
msg = login.response.status.statusMessage
return template.error_page(_('Response is not Success (%s)') % msg)
except:
pass
if error[0] == lasso.PROFILE_ERROR_INVALID_MSG:
print 'Received invalid SOAP answer when resolving artifact: \'%s\'' % soap_answer
raise error
t = self.proxy_auth_peer_cancelled(login)
if t:
return t
session = get_session()
if not session.lasso_login_dump:
# probably user clicked on "back" on MSP (see bug 138)
get_response().expire_cookie('msp-user',
domain = get_publisher().config.session_cookie_domain,
path = '/')
return redirect('/login')
login = lasso.Login.newFromDump(authentic.misc.get_lasso_server(),
session.lasso_login_dump)
session.lasso_login_dump = None
return self.sso_after_authentication(login, False, proxied = True)
return redirect('/federate_msp')
# Traitement particulie pour le cas d'une demande de creation
# alors que la federation existe
if error[0] == lasso.LOGIN_ERROR_STATUS_NOT_SUCCESS and\
login.response.status and\
login.response.status.statusCode and\
login.response.status.statusCode.statusCode and\
login.response.status.statusCode.statusCode.statusCode and\
login.response.status.statusCode.statusCode.statusCode.value == 'msp:AlreadyFederated':
print 'Interception already federated'
return redirect('/login_msp')
if error[0] == lasso.LOGIN_ERROR_UNKNOWN_PRINCIPAL:
get_response().expire_cookie('msp-user',
domain = get_publisher().config.session_cookie_domain,
path = '/')
if not session.lasso_login_dump:
# probably user clicked on "back" on MSP (see bug 138)
if not session.user:
return redirect('/login')
else:
try:
msg = login.response.status.statusMessage
return template.error_page(_('Response is not Success (%s)') % msg, continue_to=('/', _('Home')))
except:
return redirect('/')
login = lasso.Login.newFromDump(authentic.misc.get_lasso_server(),
session.lasso_login_dump)
session.lasso_login_dump = None
return self.sso_after_authentication(login, False, proxied = True)
try:
msg = login.response.status.statusMessage
return template.error_page(_('Response is not Success (%s)') % msg, continue_to=('/', _('Home')))
except:
pass
if error[0] == lasso.PROFILE_ERROR_INVALID_MSG:
print 'Received invalid SOAP answer when resolving artifact: \'%s\'' % soap_answer
raise error
t = self.proxy_auth_peer_cancelled(login)
if t:
return t
else:
self.proxy_auth_ok(login)
else:
login.processAuthnResponseMsg(get_field('LARES'))
session = get_session()
if session.lasso_proxy_session_dump:
login.setSessionFromDump(session.lasso_proxy_session_dump)
ni = login.nameIdentifier.content
@ -531,7 +559,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
<Detail>%s</Detail>
</Fault>
</Body>
</Envelope>''' % msg
</Envelope>''' % xml.sax.saxutils.escape(msg)
return body
msp_oids = {
@ -822,7 +850,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
import urllib
import httplib
def soap_call(url, msg, client_cert = None, more_headers = None):
def soap_call(url, msg, client_cert = None, more_headers = None, timeout = 3600):
print 'Entering SOAP_CALL for %s' % url
if url.startswith('http://'):
host, query = urllib.splithost(url[5:])
conn = httplib.HTTPConnection(host)
@ -833,16 +862,30 @@ def soap_call(url, msg, client_cert = None, more_headers = None):
headers = {'Content-Type': 'text/xml'}
if more_headers:
headers.update(more_headers)
conn.set_debuglevel(1)
conn.request('POST', query, msg, headers)
response = conn.getresponse()
data = response.read()
conn.close()
if response.status not in (200, 204): # 204 ok for federation termination
get_logger().warn('SOAP error (%s) (on %s)' % (response.status, url))
raise SOAPError()
conn.set_debuglevel(3)
oldtimeout = socket.getdefaulttimeout()
start = time.time()
try:
try:
socket.setdefaulttimeout(timeout)
conn.request('POST', query, msg, headers)
response = conn.getresponse()
data = response.read()
print 'reponse: %s' % str(data)
if response.status not in (200, 204): # 204 ok for federation termination
get_logger().warn('SOAP error (%s) (on %s)' % (response.status, url))
raise SOAPError()
except Exception, exception:
get_logger().warn('SOAP error (%s) (on %s)' % (exception, url))
raise SOAPError(str(exception))
finally:
socket.setdefaulttimeout(oldtimeout)
conn.close()
print "Temps ecoule: %s" % str(time.time()-start)
return data
authentic.liberty.root.soap_call = soap_call
# import uuid # only in 2.5
import smtplib
try: