Implement interaction redirect on ED service request when not connected to MSP

* add a method to generate proper built SOAP faults
 * add a method to generate unique ID
 * add a method to generate InteractionRedirect SOAP faults
 * overload get_identity_by_resource to always return a proxy DST service for MSP ED.
 * add a new exception class to handle case needing a redirect soap fault
 * remove all debugging code
This commit is contained in:
root 2008-11-25 19:48:54 +01:00
parent d9cef3decc
commit 4c105e414d
1 changed files with 69 additions and 13 deletions

View File

@ -8,6 +8,8 @@ import cgi
import traceback
import socket
import xml.sax.saxutils
import string
import random
import lasso
@ -35,6 +37,9 @@ ED_DOCUMENTS_MIGRATION_DISABLED = True
def isotime(offset = 0):
return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(time.time()+offset))
def get_unique_id():
return base64.encodestring("".join([random.choice("0123456789ABCDEF") for x in range(40)]).decode('hex'))
msp_urn = 'urn:dgme:msp:ed:2007-01'
adeline_urn = 'urn:fr.icdc.dei.adeline:ppAdeline:2008-01'
dummy_value = 'd41d8cd98f00b204e9800998ecf8427e'
@ -50,6 +55,9 @@ except ImportError:
except ImportError:
import xml.etree.ElementTree as ET
class RedirectException(Exception):
def __init__(self, redirect_url):
self.redirect_url = redirect_url
class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
_q_exports = ["", "sp", "singleSignOn", "soapEndpoint",
@ -99,6 +107,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
session = get_session()
request = get_request()
continue_home = ('/',_('Home'))
if session.after_url:
continue_home = (session.after_url, _('request origin'))
server = authentic.misc.get_lasso_server(lasso.PROVIDER_ROLE_SP)
@ -233,8 +243,6 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
return redirect(after_url)
return redirect(get_request().environ['SCRIPT_NAME'] + '/')
def migrationMsp(self, login, identity, session):
if not identity.lasso_dump:
# create empty identity
@ -309,6 +317,28 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
return None
def get_identity_by_resource_id(self, resource_id):
identity = authentic.liberty.root.RootDirectory.get_identity_by_resource_id(self, resource_id)
if not identity:
return None
if lasso.WSF_SUPPORT:
lasso_identity = lasso.Identity.newFromDump(identity.lasso_dump)
server = authentic.misc.get_lasso_server()
offerings = lasso_identity.getOfferings(adeline_urn)
if offerings:
lst = [x for x in lasso_identity.getOfferings(adeline_urn) if \
x.serviceInstance.providerId == server.providerId]
else:
lst = []
if len(lst) == 0:
# adds authentic id-sis ppa offering
resource_offering = lasso.DiscoResourceOffering(self.get_ppa_proxy_service())
resource_offering.resourceId = lasso.DiscoResourceID(identity.resource_id)
resource_offering.abstract = "Adeline Personal Profile with Authentic informations"
lasso_identity.addResourceOffering(resource_offering)
identity.lasso_dump = lasso_identity.dump()
authentic.identities.get_store().save(identity)
return identity
def get_pp_proxy_service(self):
server = authentic.misc.get_lasso_server()
@ -402,13 +432,10 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
try:
wsc_proxy_service.processResponseMsg(soap_answer)
except lasso.Error, error:
print 'erreur', error
print 'dump', wsc_proxy_service.response.dump()
if wsc_proxy_service.response and wsc_proxy_service.response.detail and wsc_proxy_service.response.detail.any[0]:
print wsc_proxy_service.response.detail.any[0].dump()
if error[0] != lasso.SOAP_FAULT_REDIRECT_REQUEST or not wsc_proxy_service.msgUrl:
raise
print 'redirect'
messageId = self.getMessageId(wsc_proxy_service.soapEnvelopeResponse)
return None, wsc_proxy_service.msgUrl, messageId
# Convert DownloadFileReponse to a document
@ -451,6 +478,36 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
else:
return None, None, None
def get_blank_soap_fault(self, message_id):
header = lasso.SoapHeader()
if (message_id):
correlation = lasso.SoapBindingCorrelation()
correlation.messageId = get_unique_id()
correlation.refToMessageId = message_id
correlation.mustUnderstand = 1
correlation.id = correlation.messageId
correlation.actor = "http://schemas.xmlsoap.org/soap/actor/next"
corrleation.timestamp = isotime()
header.other = (correlation,)
fault = lasso.SoapFault()
fault.faultcode = 'S:Server'
fault.faultstring = 'Server Error'
body = lasso.SoapBody()
body.any = (fault,)
envelope = lasso.SoapEnvelope(body)
envelope.header = header
return envelope
def get_redirect_soap_fault(self, redirect_url,message_id):
soap_fault = self.get_blank_soap_fault(message_id)
if lasso.WSF_SUPPORT:
redirectrequest = lasso.IsRedirectRequest(redirect_url)
detail = lasso.SoapDetail()
detail.any = (redirectrequest,)
soap_fault.body.any[0].detail = detail
else:
print 'Pas de support ID-WSF, redirect request impossible'
return soap_fault
def mspProxyEndpoint(self):
request = get_request()
@ -472,6 +529,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
service = lasso.DataService(authentic.misc.get_lasso_server())
messageId = None
try:
if request_type == lasso.REQUEST_TYPE_DST_QUERY:
try:
@ -554,6 +612,10 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
service.buildModifyResponseMsg()
return service.msgBody
except RedirectException, redirect_exception:
soap_fault = self.get_redirect_soap_fault(redirect_exception.redirect_url, messageId)
body = soap_fault.exportToXml()
return body
except:
fp = StringIO.StringIO()
traceback.print_exc(file=fp)
@ -750,15 +812,11 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
if service_type == adeline_urn:
modify_oids = []
pp = ET.XML(resource_data)
print 'resource: ', resource_data
for oid in self.msp_oids:
name = self.msp_oids[oid]['name']
print 'name: ', name
item = pp.findall('{%s}%s' % (adeline_urn, name))
print 'item: ', item
if item:
item = item[0]
print 'item[0]: ', item
if item.text != dummy_value:
text = item.text
if text == None:
@ -790,15 +848,11 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
more_headers = more_headers)
# FIXME: MSP for dummies !
soap_answer = soap_answer.replace('S:detail', 'S:Detail')
print 'after replace: ', soap_answer
try:
wsc_proxy_service.processResponseMsg(soap_answer)
except lasso.Error, error:
print 'erreur sur update', error
print 'dump', wsc_proxy_service.response.dump()
if error[0] != lasso.SOAP_FAULT_REDIRECT_REQUEST or not wsc_proxy_service.msgUrl:
raise
print 'redirect'
messageId = self.getMessageId(wsc_proxy_service.soapEnvelopeResponse)
return (wsc_proxy_service.msgUrl, messageId)
if wsc_proxy_service.response.status.code == 'Ok':
@ -810,6 +864,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
disco = lasso.Discovery(authentic.misc.get_lasso_server())
if session.lasso_proxy_session_dump:
disco.setSessionFromDump(session.lasso_proxy_session_dump)
else:
raise RedirectException('http://' + get_request().get_server().replace('-app','') + '/login_msp_for_proxy')
# XXX: else build an error response ?
# if CredentialRef is present can activate lasso.SECURITY11_MECH_TLS_SAML
try: