From 4c105e414dd7b2fb35cbd78618c8fa5bf5797452 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Nov 2008 19:48:54 +0100 Subject: [PATCH] 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 --- extra/modules/liberty.py | 82 +++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/extra/modules/liberty.py b/extra/modules/liberty.py index 0f935df..de7fb61 100644 --- a/extra/modules/liberty.py +++ b/extra/modules/liberty.py @@ -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: