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:
parent
d9cef3decc
commit
4c105e414d
|
@ -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:
|
||||
|
|
Reference in New Issue