1056 lines
45 KiB
Python
1056 lines
45 KiB
Python
import time
|
|
import sys
|
|
import re
|
|
import base64
|
|
import Cookie
|
|
import StringIO
|
|
import cgi
|
|
import traceback
|
|
import socket
|
|
import xml.sax.saxutils
|
|
|
|
import lasso
|
|
|
|
try:
|
|
import lassodgme
|
|
except ImportError:
|
|
print >> sys.stderr, 'Missing lassodgme module; ID-WSF proxy has been disabled'
|
|
lassodgme = None
|
|
|
|
from quixote import get_session, get_session_manager, get_request, get_response, redirect, get_field, get_publisher
|
|
from quixote.http_request import parse_header
|
|
|
|
from qommon import get_cfg, get_logger
|
|
from qommon import errors, template
|
|
|
|
import misc
|
|
|
|
import authentic.liberty.root
|
|
from authentic.liberty.root import SOAPError
|
|
from alternatespui import AlternateSpDir
|
|
|
|
ED_MIGRATION_DISABLED = False
|
|
ED_DOCUMENTS_MIGRATION_DISABLED = True
|
|
|
|
def isotime(offset = 0):
|
|
return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(time.time()+offset))
|
|
|
|
msp_urn = 'urn:dgme:msp:ed:2007-01'
|
|
adeline_urn = 'urn:fr.icdc.dei.adeline:ppAdeline:2008-01'
|
|
dummy_value = 'd41d8cd98f00b204e9800998ecf8427e'
|
|
|
|
try:
|
|
from lxml import etree as ET
|
|
except ImportError:
|
|
try:
|
|
import cElementTree as ET
|
|
except ImportError:
|
|
try:
|
|
import elementtree.ElementTree as ET
|
|
except ImportError:
|
|
import xml.etree.ElementTree as ET
|
|
|
|
|
|
class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|
_q_exports = ["", "sp", "singleSignOn", "soapEndpoint",
|
|
'metadata', ('metadata.xml', 'metadata'), 'public_key',
|
|
"singleLogout", "singleLogoutReturn", "federationTermination",
|
|
"federationTerminationReturn", "registerNameIdentifier", "consent",
|
|
"proxySoapEndpoint", "proxyAssertionConsumer", "proxySingleLogout",
|
|
"proxySingleLogoutNext", 'mspProxyEndpoint', 'proxySingleLogoutReturn']
|
|
|
|
sp = AlternateSpDir()
|
|
|
|
def perform_proxy_login(self, idp = None, nameIdPolicy = None, extensions = None):
|
|
session = get_session()
|
|
server = authentic.misc.get_lasso_server(lasso.PROVIDER_ROLE_SP)
|
|
login = lasso.Login(server)
|
|
login.initAuthnRequest(idp, lasso.HTTP_METHOD_REDIRECT)
|
|
login.request.nameIdPolicy = 'federated'
|
|
login.request.forceAuthn = False
|
|
login.request.isPassive = False
|
|
login.request.consent = "urn:liberty:consent:obtained"
|
|
login.request.requestAuthnContext = lasso.LibRequestAuthnContext()
|
|
login.request.requestAuthnContext.authnContextClassRef = (
|
|
lasso.LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD_PROTECTED_TRANSPORT, )
|
|
|
|
if session.lasso_login_dump:
|
|
# replicates parameters from the request we proxy
|
|
orig_login = lasso.Login.newFromDump(authentic.misc.get_lasso_server(),
|
|
session.lasso_login_dump)
|
|
login.request.nameIdPolicy = orig_login.request.nameIdPolicy
|
|
login.request.forceAuthn = orig_login.request.forceAuthn
|
|
login.request.isPassive = orig_login.request.isPassive
|
|
login.request.consent = orig_login.request.consent
|
|
|
|
if nameIdPolicy: # forced value
|
|
login.request.nameIdPolicy = nameIdPolicy
|
|
if extensions:
|
|
ext_list = lasso.StringList()
|
|
for ext in extensions:
|
|
ext_list.append('<lib:Extension xmlns:lib="urn:liberty:iff:2003-08"><%s>%s</%s></lib:Extension>' % (ext[0], ext[1], ext[0]))
|
|
login.request.extension = tuple(ext_list)
|
|
|
|
login.buildAuthnRequestMsg()
|
|
return redirect(login.msgUrl)
|
|
|
|
|
|
def proxyAssertionConsumer(self):
|
|
session = get_session()
|
|
request = get_request()
|
|
continue_home = ('/',_('Home'))
|
|
|
|
server = authentic.misc.get_lasso_server(lasso.PROVIDER_ROLE_SP)
|
|
|
|
if session.msp_login_dump:
|
|
login = lasso.Login.newFromDump(server, session.msp_login_dump)
|
|
session.msp_login_dump = None
|
|
identity = None
|
|
else:
|
|
login = lasso.Login(server)
|
|
if request.get_method() == 'GET' or get_field('LAREQ'):
|
|
if request.get_method() == 'GET':
|
|
login.initRequest(request.get_query(), lasso.HTTP_METHOD_REDIRECT)
|
|
else:
|
|
login.initRequest(get_field('LAREQ'), lasso.HTTP_METHOD_POST)
|
|
|
|
login.buildRequestMsg()
|
|
try:
|
|
soap_answer = soap_call(login.msgUrl, login.msgBody)
|
|
except authentic.liberty.root.SOAPError:
|
|
return template.error_page(_('Failed to get Assertion from identity provider'),continue_to=continue_home)
|
|
try:
|
|
login.processResponseMsg(soap_answer)
|
|
except lasso.Error, error:
|
|
# Traitement d'une demande de federation existante
|
|
# apres desynchro, 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
|
|
get_response().expire_cookie('msp-user',
|
|
domain = get_publisher().config.session_cookie_domain,
|
|
path = '/')
|
|
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'))
|
|
|
|
if session.lasso_proxy_session_dump:
|
|
login.setSessionFromDump(session.lasso_proxy_session_dump)
|
|
ni = login.nameIdentifier.content
|
|
authentic.identities.get_store().load_identities()
|
|
identity = authentic.identities.get_store().get_identity_for_name_identifier(ni)
|
|
|
|
if identity is None and get_session().user:
|
|
identity = authentic.identities.get_store().get_identity(get_session().user)
|
|
|
|
if identity:
|
|
if identity.lasso_proxy_dump:
|
|
login.setIdentityFromDump(identity.lasso_proxy_dump)
|
|
session.set_user(identity.id)
|
|
else:
|
|
session.msp_login_dump = login.dump()
|
|
return redirect(request.environ['SCRIPT_NAME'] + '/login')
|
|
|
|
session.proxied_idp = login.remoteProviderId
|
|
if not session.name_identifiers:
|
|
session.name_identifiers = []
|
|
session.name_identifiers.append(login.nameIdentifier.content)
|
|
|
|
migration_url = None
|
|
login.acceptSso()
|
|
if login.isIdentityDirty:
|
|
if not identity.lasso_proxy_dump:
|
|
migration_url = self.migrationMsp(login, identity, session)
|
|
identity.lasso_proxy_dump = login.identity.dump()
|
|
if login.isSessionDirty:
|
|
session.lasso_proxy_session_dump = login.session.dump()
|
|
|
|
authentic.identities.get_store().save(identity)
|
|
|
|
response = get_response()
|
|
response.set_cookie('msp-user', 'true',
|
|
domain = get_publisher().config.session_cookie_domain,
|
|
expires = Cookie._getdate(3*365*86400),
|
|
path = '/')
|
|
|
|
if migration_url:
|
|
return redirect(migration_url)
|
|
|
|
if session.lasso_login_dump:
|
|
login = lasso.Login.newFromDump(authentic.misc.get_lasso_server(), session.lasso_login_dump)
|
|
session.lasso_login_dump = None
|
|
return self.sso_after_authentication(login, True, proxied = True)
|
|
|
|
if session.after_url:
|
|
after_url = session.after_url
|
|
session.after_url = None
|
|
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
|
|
identity.lasso_dump = '<Identity xmlns="http://www.entrouvert.org/namespaces/lasso/0.0" Version="2"></Identity>'
|
|
|
|
get_logger().info('ID-WSF migration to MSP')
|
|
|
|
server = authentic.misc.get_lasso_server()
|
|
lasso_identity = lasso.Identity.newFromDump(identity.lasso_dump)
|
|
|
|
lst = []
|
|
offerings = lasso_identity.getOfferings(lasso.PP_HREF)
|
|
if offerings:
|
|
lst.extend([x.entryId for x in offerings if \
|
|
x.serviceInstance.providerId == server.providerId])
|
|
offerings = lasso_identity.getOfferings(adeline_urn)
|
|
if offerings:
|
|
server = authentic.misc.get_lasso_server()
|
|
lst.extend([x.entryId for x in offerings if \
|
|
x.serviceInstance.providerId == server.providerId])
|
|
|
|
# Migrate documents from Adeline to MSP
|
|
|
|
# First get documents list
|
|
if not ED_MIGRATION_DISABLED and not ED_DOCUMENTS_MIGRATION_DISABLED:
|
|
adeline_service = lasso.DataService.newFull(server, offerings[0])
|
|
lasso.registerDstService('ad', adeline_urn)
|
|
adeline_service.initQuery('/ad:PersonalDocumentList', 'doclist')
|
|
adeline_service.buildRequestMsg()
|
|
try:
|
|
soap_anwser = soap_call(adeline_service.msgUrl, adeline_service.msgBody + ' ')
|
|
adeline_service.processQueryResponseMsg(soap_anwser)
|
|
doc_list = adeline_service.getAnswer('/ad:PersonalDocumentList')
|
|
if doc_list:
|
|
doc_keys = re.findall('documentKey="(.+)"', doc_list)
|
|
if doc_keys:
|
|
# then register after job to get and transfer all documents
|
|
adeline_service = lasso.DataService.newFull(server, offerings[0])
|
|
get_response().add_after_job('migrate data space',
|
|
MigrateDataSpace(identity, session, adeline_service, doc_keys),
|
|
fire_and_forget = True)
|
|
except (SOAPError, lasso.ProfileInvalidSoapMsgError), error:
|
|
pass
|
|
|
|
if lst:
|
|
# identity had data services, remove them
|
|
for x in lst:
|
|
lasso_identity.removeResourceOffering(x)
|
|
|
|
if not identity.resource_id:
|
|
identity.resource_id = '%s/resources/identity/%s' % (
|
|
get_cfg('idp')['base_url'], identity.id)
|
|
|
|
resource_offering = lasso.DiscoResourceOffering(self.get_pp_proxy_service())
|
|
resource_offering.resourceId = lasso.DiscoResourceID(identity.resource_id)
|
|
resource_offering.abstract = 'Fake Personal Profile Service, Proxying to MSP'
|
|
lasso_identity.addResourceOffering(resource_offering)
|
|
|
|
resource_offering = lasso.DiscoResourceOffering(self.get_ppa_proxy_service())
|
|
resource_offering.resourceId = lasso.DiscoResourceID(identity.resource_id)
|
|
resource_offering.abstract = 'Fake Adeline Personal Profile Service, Proxying to MSP'
|
|
lasso_identity.addResourceOffering(resource_offering)
|
|
|
|
# and save that
|
|
identity.lasso_dump = lasso_identity.dump()
|
|
authentic.identities.get_store().save(identity)
|
|
|
|
if lst and not ED_MIGRATION_DISABLED:
|
|
# identity had data services, notify them
|
|
data_migration_url = get_cfg('adeline', {}).get('data_migration_url')
|
|
return data_migration_url
|
|
|
|
return None
|
|
|
|
|
|
def get_pp_proxy_service(self):
|
|
server = authentic.misc.get_lasso_server()
|
|
return lasso.DiscoServiceInstance(
|
|
lasso.PP_HREF,
|
|
server.providerId,
|
|
lasso.DiscoDescription_newWithBriefSoapHttpDescription(
|
|
lasso.SECURITY_MECH_NULL,
|
|
'%s/mspProxyEndpoint' % get_cfg('idp', {}).get('base_url', None)))
|
|
|
|
def get_ppa_proxy_service(self):
|
|
server = authentic.misc.get_lasso_server()
|
|
return lasso.DiscoServiceInstance(
|
|
adeline_urn,
|
|
server.providerId,
|
|
lasso.DiscoDescription_newWithBriefSoapHttpDescription(
|
|
lasso.SECURITY_MECH_NULL,
|
|
'%s/mspProxyEndpoint' % get_cfg('idp', {}).get('base_url', None)))
|
|
|
|
def getMessageId(self, soap_envelope):
|
|
header = soap_envelope.header
|
|
if header:
|
|
headers = header.other
|
|
for x in headers:
|
|
if isinstance(x, lasso.SoapBindingCorrelation):
|
|
return x.messageId
|
|
|
|
def getRefToMessageId(self, soap_envelope):
|
|
header = soap_envelope.header
|
|
if header:
|
|
headers = header.other
|
|
for x in headers:
|
|
if isinstance(x, lasso.SoapBindingCorrelation):
|
|
return x.refToMessageId
|
|
|
|
|
|
def setMessageId(self, soap_envelope, messageId):
|
|
headers = soap_envelope.header.other
|
|
for x in headers:
|
|
if isinstance(x, lasso.SoapBindingCorrelation):
|
|
x.messageId = messageId
|
|
|
|
def setRefToMessageId(self, soap_envelope, messageId):
|
|
headers = soap_envelope.header.other
|
|
for x in headers:
|
|
if isinstance(x, lasso.SoapBindingCorrelation):
|
|
x.refToMessageId = messageId
|
|
|
|
|
|
def get_msp_document(self, identity, messageId):
|
|
# 1st, get current user session
|
|
sessions = [x for x in get_session_manager().values() if x.user == identity.id]
|
|
sessions.sort(lambda x,y: cmp(x.get_creation_time(), y.get_creation_time()))
|
|
if not sessions:
|
|
return None
|
|
latest_session = sessions[-1]
|
|
|
|
# 2nd, query MSP
|
|
|
|
# Init DownloadFile request
|
|
wsc_proxy_service = self.msp_disco_query(latest_session)
|
|
wsc_proxy_service.initDownloadFileRequest(lasso.SECURITY11_MECH_TLS_SAML)
|
|
# FIXME: set appropriate teleserviceId
|
|
wsc_proxy_service.request.teleserviceId = '1001'
|
|
# Add interaction service header
|
|
headers = wsc_proxy_service.soapEnvelopeRequest.header.other
|
|
user_interaction = lasso.IsUserInteraction()
|
|
user_interaction.id = 'userinteractid'
|
|
user_interaction.redirect = 1
|
|
user_interaction.maxInteractTime = 600
|
|
headers = headers + ( user_interaction, )
|
|
wsc_proxy_service.soapEnvelopeRequest.header.other = headers
|
|
|
|
if messageId:
|
|
self.setRefToMessageId(wsc_proxy_service.soapEnvelopeRequest, messageId)
|
|
wsc_proxy_service.buildRequestMsg()
|
|
|
|
more_headers = {}
|
|
if get_cfg('adeline', {}).get('http_auth_tuple'):
|
|
more_headers['Authorization'] = 'Basic ' + base64.encodestring(
|
|
get_cfg('adeline', {}).get('http_auth_tuple'))
|
|
|
|
# Send request to MSP
|
|
body = wsc_proxy_service.msgBody
|
|
# FIXME: MSP is void !
|
|
body = body.replace('xmlns:is="urn:liberty:is:2003-08"','').replace(
|
|
'<is:UserInteraction', '<is:UserInteraction xmlns:is="urn:liberty:is:2003-08"')
|
|
soap_answer = soap_call(wsc_proxy_service.msgUrl, body + ' ',
|
|
more_headers = more_headers)
|
|
soap_answer = soap_answer.replace('S:detail', 'S:Detail')
|
|
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
|
|
# Content of Response:
|
|
# response->file -> {
|
|
# int type
|
|
# string nom
|
|
# string binaryFile # base64 encoded content
|
|
# string xmlMetadata (xml fragment for the metatada)
|
|
# }
|
|
# to convert to
|
|
# ad:PersonalDocument
|
|
# ad:PersonalDocumentMetadata
|
|
# ad:Content
|
|
#
|
|
response = wsc_proxy_service.response
|
|
if response.status.code == 'Ok':
|
|
template = '''<PersonalDocument xmlns='%(urn)s'>
|
|
<PersonalDocumentMetadata fileName="%(nom)s" documentType="%(type_urn)s" mimeType="application/octet-stream" modifyTime="%(date)s" documentKey="%(nom)s">
|
|
<ExternMetadata>%(other_metadata)s</ExternMetadata>
|
|
<Title>%(nom)s</Title>
|
|
</PersonalDocumentMetadata>
|
|
<Content>%(content)s</Content>
|
|
</PersonalDocument>'''
|
|
context = {
|
|
'urn' : adeline_urn,
|
|
'nom' : response.file.nom,
|
|
'date' : '2008-07-01T14:12:00',
|
|
'type_urn' : 'urn:fr.icdc.dei.adeline:document-type:msp:%s' % response.file.type,
|
|
'other_metadata' : response.file.xmlMetadata,
|
|
'content' : response.file.binaryFile
|
|
}
|
|
metadata = ET.XML(response.file.xmlMetadata)
|
|
documentmsp = metadata.findall('documentMSPType')
|
|
if documentmsp:
|
|
modifytimes = documentmsp[0].findall('dateReference')
|
|
if modifytimes and modifytimes[0].text:
|
|
context['date'] = modifytimes[0].text
|
|
return (template % context), None, None
|
|
else:
|
|
return None, None, None
|
|
|
|
|
|
def mspProxyEndpoint(self):
|
|
request = get_request()
|
|
ctype = request.environ.get("CONTENT_TYPE")
|
|
if not ctype:
|
|
get_logger().warn('SOAP Endpoint got message without content-type')
|
|
return
|
|
|
|
ctype, ctype_params = parse_header(ctype)
|
|
if ctype != 'text/xml':
|
|
get_logger().warn('SOAP Endpoint got message with wrong content-type (%s)' % ctype)
|
|
return
|
|
|
|
get_response().set_content_type('text/xml')
|
|
|
|
length = int(request.environ.get('CONTENT_LENGTH'))
|
|
soap_message = request.stdin.read(length)
|
|
print 'Received on mspProxySoapEndpoint: %s' % soap_message
|
|
|
|
request_type = lasso.getRequestTypeFromSoapMsg(soap_message)
|
|
service = lasso.DataService(authentic.misc.get_lasso_server())
|
|
try:
|
|
if request_type == lasso.REQUEST_TYPE_DST_QUERY:
|
|
try:
|
|
service_prefix = re.findall('<([a-z]*?):Query>', soap_message)[0]
|
|
service_href = re.findall('xmlns:%s="(.*?)"' % service_prefix, soap_message)[0]
|
|
lasso.registerDstService(service_prefix, service_href)
|
|
except IndexError: # too bad, this hacky thing didn't work.
|
|
service_href = lasso.PP_HREF
|
|
|
|
service.processQueryMsg(soap_message)
|
|
messageId = self.getRefToMessageId(service.soapEnvelopeRequest)
|
|
query_items = []
|
|
for item in service.request.queryItem:
|
|
get_logger().info('Received DST_QUERY for %s' % item.select)
|
|
query_items.append(item.select)
|
|
|
|
try:
|
|
identity = self.get_identity_by_resource_id(service.resourceId)
|
|
except:
|
|
pass # XXX: build deny request ?
|
|
|
|
# fill resource data, query MSP for values
|
|
if '/ad:PersonalDocument' in query_items:
|
|
resource, redirect_url, messageId = self.get_msp_document(identity, messageId)
|
|
else:
|
|
resource = self.query_msp_for_pp(service_href, identity, query_items)
|
|
redirect_url = None
|
|
if resource:
|
|
service.resourceData = resource
|
|
elif redirect_url and messageId:
|
|
service.soapEnvelopeResponse.body.any = ()
|
|
# Keep messageId of SOAP Fault
|
|
# if the request is repeated we will use
|
|
# the refToMessageId on the proxyed request
|
|
# to set refToMessageId on the request to MSP
|
|
self.setMessageId(service.soapEnvelopeResponse, messageId)
|
|
service.needRedirectUser(redirect_url)
|
|
else:
|
|
raise Exception('No Resource!!!')
|
|
|
|
service.buildResponseMsg()
|
|
return service.msgBody
|
|
|
|
|
|
if request_type == lasso.REQUEST_TYPE_DST_MODIFY:
|
|
try:
|
|
service_prefix = re.findall('<([a-z]*?):Modify>', soap_message)[0]
|
|
service_href = re.findall('xmlns:%s="(.*?)"' % service_prefix, soap_message)[0]
|
|
lasso.registerDstService(service_prefix, service_href)
|
|
except IndexError: # too bad, this hacky thing didn't work.
|
|
service_href = lasso.PP_HREF
|
|
|
|
service.processModifyMsg(soap_message)
|
|
messageId = self.getRefToMessageId(service.soapEnvelopeRequest)
|
|
modify_items = {}
|
|
for item in service.request.modification:
|
|
get_logger().info('Received DST_MODIFY for %s' % item.select)
|
|
modify_items[item.select] = item.newData.any
|
|
|
|
try:
|
|
identity = self.get_identity_by_resource_id(service.resourceId)
|
|
except:
|
|
pass # XXX: build deny request
|
|
resource = self.init_modify_msp_for_pp(service_href, modify_items)
|
|
if resource:
|
|
service.resourceData = resource
|
|
else:
|
|
return 'ERROR'
|
|
service.buildModifyResponseMsg()
|
|
result, messageId = self.do_modify_msp_for_pp(service_href, identity, service.resourceData, messageId)
|
|
if result and result != 'Ok':
|
|
service.soapEnvelopeResponse.body.any = ()
|
|
# Keep messageId of SOAP Fault
|
|
# if the request is repeated we will use
|
|
# the refToMessageId on the proxyed request
|
|
# to set refToMessageId on the request to MSP
|
|
self.setMessageId(service.soapEnvelopeResponse, messageId)
|
|
print 'Redirection sur %s' % result
|
|
service.needRedirectUser(result)
|
|
|
|
service.buildModifyResponseMsg()
|
|
return service.msgBody
|
|
except:
|
|
fp = StringIO.StringIO()
|
|
traceback.print_exc(file=fp)
|
|
msg = fp.getvalue()
|
|
body = '''<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
|
|
<Header/>
|
|
<Body>
|
|
<Fault>
|
|
<faultcode>PythonException</faultcode>
|
|
<faultstring>Python Exception</faultstring>
|
|
<Detail>%s</Detail>
|
|
</Fault>
|
|
</Body>
|
|
</Envelope>''' % xml.sax.saxutils.escape(msg)
|
|
return body
|
|
|
|
msp_oids = {
|
|
'OID.1.1.1' : { 'name': 'lbNomFamille'},
|
|
'OID.1.1.2' : { 'name': 'lbNomUsage'},
|
|
'OID.1.1.3' : { 'name': 'lbSurnom'},
|
|
'OID.1.1.4.1' : { 'name': 'lbPrenoms0'},
|
|
'OID.1.1.4.2' : { 'name': 'lbPrenoms1'},
|
|
'OID.1.1.4.3' : { 'name': 'lbPrenoms2'},
|
|
'OID.1.1.4.4' : { 'name': 'lbPrenoms3'},
|
|
'OID.1.1.5' : { 'name': 'cdSexe' },
|
|
'OID.1.1.6' : { 'name': 'cdCivilite'},
|
|
'OID.1.1.7' : { 'name': 'lbTitre'},
|
|
'OID.1.1.8' : { 'name': 'cdSituationFamiliale'},
|
|
'OID.1.1.9' : { 'name': 'dtNaissance'},
|
|
'OID.1.1.10' : { 'name': 'lbLocaliteNaissance'},
|
|
'OID.1.1.11' : { 'name': 'cdPostalNaissance'},
|
|
'OID.1.1.12' : { 'name': 'lbPaysNaissance'},
|
|
'OID.1.1.13' : { 'name': 'lbDivisionTerritorialeNaissance',},
|
|
'OID.1.2.1.1.1' : { 'name': 'lbPointRemise'},
|
|
'OID.1.2.1.1.2' : { 'name': 'lbComplement'},
|
|
'OID.1.2.1.1.3' : { 'name': 'noVoirie'},
|
|
'OID.1.2.1.1.4' : { 'name': 'lbExtension'},
|
|
'OID.1.2.1.1.5' : { 'name': 'lbTypeVoie'},
|
|
'OID.1.2.1.1.6' : { 'name': 'lbNomVoie'},
|
|
'OID.1.2.1.1.7' : { 'name': 'lbLieuDit'},
|
|
'OID.1.2.1.1.8' : { 'name': 'lbMentionPartDistrib'},
|
|
'OID.1.2.1.1.9' : { 'name': 'cdCedex'},
|
|
'OID.1.2.1.1.10' : { 'name': 'lbBureauCedex'},
|
|
'OID.1.2.1.1.11' : { 'name': 'cdPostal'},
|
|
'OID.1.2.1.1.12' : { 'name': 'lbLocaliteResidence'},
|
|
'OID.1.2.1.1.13' : { 'name': 'lbPays'},
|
|
'OID.1.2.1.1.14' : { 'name': 'lbDivisionTerritoriale'},
|
|
'OID.1.3.1.1.1' : { 'name': 'lbEmail'},
|
|
'OID.1.3.2.1.1' : { 'name': 'noTelFixe'},
|
|
'OID.1.3.2.1.2' : { 'name': 'lbIndPaysTelFixe'},
|
|
'OID.1.3.3.1.1' : { 'name': 'noTelPortable'},
|
|
'OID.1.3.3.1.2' : { 'name': 'lbIndPaysTelPortable'},
|
|
'OID.1.3.4.1.1' : { 'name': 'noFax'},
|
|
'OID.1.3.4.1.2' : { 'name': 'lbIndPaysFax'}
|
|
}
|
|
# SIS-PP content
|
|
# <InformalName>%(lbInformalName)s</InformalName>
|
|
# <CommonName>
|
|
# <AnalyzedName>
|
|
# <PersonalTitle>%(cdCivilite)s</PersonalTitle>
|
|
# <FN>%(lbPrenoms)s</FN>
|
|
# <SN>%(lbNomFamille)s</SN>
|
|
# </AnalyzedName>
|
|
# </CommonName>
|
|
# <LegalIdentity>
|
|
# <DOB>%(dtNaissance)s</DOB>
|
|
# </LegalIdentity>
|
|
# <AddressCard>
|
|
# <AddrType>urn:liberty:id-sis-pp:addrType:home</AddrType>
|
|
# <Address>
|
|
# <PostalAddress></PostalAddress>
|
|
# <PostalCode>%(cdPostal)s</PostalCode>
|
|
# <L>%(lbLocaliteResidence)s</L>
|
|
# <C>%(lbPays)s</C>
|
|
# </Address>
|
|
# </AddressCard>
|
|
# <MsgContact>
|
|
# <MsgType>urn:liberty:id-sis-pp:msgType:personal</MsgType>
|
|
# <MsgMethod>urn:liberty:id-sis-pp:msgMethod:voice</MsgMethod>
|
|
# <MsgAccount>%(noTelFixe)s</MsgAccount>
|
|
# </MsgContact>
|
|
# <MsgContact>
|
|
# <MsgType>urn:liberty:id-sis-pp:msgType:personal</MsgType>
|
|
# <MsgMethod>urn:liberty:id-sis-pp:msgMethod:email</MsgMethod>
|
|
# <MsgProvider>%(emailAccount)s</MsgProvider>
|
|
# <MsgAccount>%(emailProvider)s</MsgAccount>
|
|
# </MsgContact>
|
|
# <MsgContact>
|
|
# <MsgType>urn:liberty:id-sis-pp:msgType:mobile</MsgType>
|
|
# <MsgMethod>urn:liberty:id-sis-pp:msgMethod:voice</MsgMethod>
|
|
# <MsgAccount>%(noTelPortable)s</MsgAccount>
|
|
# </MsgContact>
|
|
pp_format = '''
|
|
<PP xmlns="%(urn)s">
|
|
%(extension)s
|
|
</PP>
|
|
'''
|
|
|
|
def query_msp_for_pp(self, service_type, identity, query_items):
|
|
# 1st, get current user session
|
|
sessions = [x for x in get_session_manager().values() if x.user == identity.id]
|
|
sessions.sort(lambda x,y: cmp(x.get_creation_time(), y.get_creation_time()))
|
|
if not sessions:
|
|
return None
|
|
latest_session = sessions[-1]
|
|
|
|
# 2nd, query MSP
|
|
|
|
# Init ReadOid request
|
|
wsc_proxy_service = self.msp_disco_query(latest_session)
|
|
wsc_proxy_service.initReadOidRequest(lasso.SECURITY11_MECH_TLS_SAML)
|
|
# FIXME: set appropriate teleserviceId
|
|
wsc_proxy_service.request.teleserviceId = '1001'
|
|
|
|
# Request complete description
|
|
for oid in self.msp_oids:
|
|
wsc_proxy_service.addReadOidItem(oid)
|
|
wsc_proxy_service.buildRequestMsg()
|
|
|
|
more_headers = {}
|
|
if get_cfg('adeline', {}).get('http_auth_tuple'):
|
|
more_headers['Authorization'] = 'Basic ' + base64.encodestring(
|
|
get_cfg('adeline', {}).get('http_auth_tuple'))
|
|
|
|
# Send request to MSP
|
|
if identity.id == 11:
|
|
soap_answer = soap_call(wsc_proxy_service.msgUrl, wsc_proxy_service.msgBody,
|
|
more_headers = more_headers)
|
|
else:
|
|
soap_answer = soap_call(wsc_proxy_service.msgUrl, wsc_proxy_service.msgBody + ' ',
|
|
more_headers = more_headers)
|
|
soap_answer = soap_answer.replace('S:detail', 'S:Detail')
|
|
|
|
# Process ReadOid response from MSP
|
|
wsc_proxy_service.processResponseMsg(soap_answer)
|
|
|
|
if wsc_proxy_service.response.status.code == 'Ok':
|
|
# Build a profile
|
|
profile = {}
|
|
extension = []
|
|
for oid in wsc_proxy_service.response.oId:
|
|
try:
|
|
desc = self.msp_oids[oid.oid]
|
|
except Exception:
|
|
continue
|
|
profile[desc['name']] = oid.content
|
|
extension.append('<%s>%s</%s>' % (desc['name'], cgi.escape(oid.content), desc['name']))
|
|
for oid in self.msp_oids:
|
|
if not self.msp_oids[oid]['name'] in profile:
|
|
name = self.msp_oids[oid]['name']
|
|
profile[name] = ''
|
|
extension.append('<%s></%s>' % (name, name))
|
|
|
|
extension = '\n'.join(extension)
|
|
profile['extension'] = extension
|
|
|
|
if service_type == lasso.PP_HREF:
|
|
profile['urn'] = lasso.PP_HREF
|
|
user_data = self.pp_format % profile
|
|
elif service_type == adeline_urn:
|
|
profile['urn'] = adeline_urn
|
|
user_data = self.pp_format % profile
|
|
else:
|
|
user_data = '<PP xmlns="urn:liberty:id-sis-pp:2003-08">Erreur ID-WSF</PP>'
|
|
|
|
|
|
return user_data
|
|
|
|
def init_modify_msp_for_pp(self, service_type, modify_items):
|
|
if service_type == adeline_urn:
|
|
content = []
|
|
for oid in self.msp_oids:
|
|
name = self.msp_oids[oid]['name']
|
|
content.append('<%s>%s</%s>' % (name, dummy_value, name))
|
|
content = '\n'.join(content)
|
|
return '<PP xmlns="%s">\n%s\n</PP>' % (adeline_urn, content)
|
|
else:
|
|
return ''
|
|
|
|
def do_modify_msp_for_pp(self, service_type, identity, resource_data, messageId):
|
|
# 1st, get current user session
|
|
sessions = [x for x in get_session_manager().values() if x.user == identity.id]
|
|
sessions.sort(lambda x,y: cmp(x.get_creation_time(), y.get_creation_time()))
|
|
if not sessions:
|
|
return (None, None)
|
|
latest_session = sessions[-1]
|
|
|
|
# 2nd, query MSP
|
|
|
|
# Init UpdateOid request
|
|
wsc_proxy_service = self.msp_disco_query(latest_session)
|
|
wsc_proxy_service.initUpdateOidRequest(lasso.SECURITY11_MECH_TLS_SAML)
|
|
wsc_proxy_service.request.teleserviceId = '1001'
|
|
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:
|
|
text = ""
|
|
wsc_proxy_service.addUpdateOidItem(oid, text.encode('utf-8'))
|
|
if service_type == lasso.PP_HREF:
|
|
pass # FIXME
|
|
# Add interaction service header
|
|
headers = wsc_proxy_service.soapEnvelopeRequest.header.other
|
|
user_interaction = lasso.IsUserInteraction()
|
|
user_interaction.id = 'userinteractid'
|
|
user_interaction.redirect = 1
|
|
user_interaction.maxInteractTime = 600
|
|
headers = headers + ( user_interaction, )
|
|
wsc_proxy_service.soapEnvelopeRequest.header.other = headers
|
|
|
|
if messageId:
|
|
self.setRefToMessageId(wsc_proxy_service.soapEnvelopeRequest, messageId)
|
|
wsc_proxy_service.buildRequestMsg()
|
|
more_headers = {}
|
|
if get_cfg('adeline', {}).get('http_auth_tuple'):
|
|
more_headers['Authorization'] = 'Basic ' + base64.encodestring(
|
|
get_cfg('adeline', {}).get('http_auth_tuple'))
|
|
body = wsc_proxy_service.msgBody
|
|
# FIXME: MSP is void !
|
|
body = body.replace('xmlns:is="urn:liberty:is:2003-08"','').replace(
|
|
'<is:UserInteraction', '<is:UserInteraction xmlns:is="urn:liberty:is:2003-08"')
|
|
soap_answer = soap_call(wsc_proxy_service.msgUrl, body + ' ',
|
|
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':
|
|
return ('Ok',None)
|
|
return (None,None)
|
|
|
|
def msp_disco_query(self, session):
|
|
'''Standard discovery query with MSP service type'''
|
|
disco = lasso.Discovery(authentic.misc.get_lasso_server())
|
|
if session.lasso_proxy_session_dump:
|
|
disco.setSessionFromDump(session.lasso_proxy_session_dump)
|
|
# XXX: else build an error response ?
|
|
# if CredentialRef is present can activate lasso.SECURITY11_MECH_TLS_SAML
|
|
try:
|
|
disco.initQuery(lasso.SECURITY11_MECH_TLS_SAML)
|
|
except lasso.ProfileMissingResourceOfferingError:
|
|
return None
|
|
disco.addRequestedServiceType(lassodgme.MSPED_HREF)
|
|
disco.buildRequestMsg()
|
|
soap_answer = soap_call(disco.msgUrl, disco.msgBody)
|
|
disco.processQueryResponseMsg(soap_answer)
|
|
return disco.getService()
|
|
|
|
# Query for an UploadFileToken, approximate date of depot is set to
|
|
# now + 10 minutes
|
|
def getUploadToken(self, identity, filename):
|
|
datedepot = isotime(600)
|
|
# 1st, get current user session
|
|
sessions = [x for x in get_session_manager().values() if x.user == identity.id]
|
|
sessions.sort(lambda x,y: cmp(x.get_creation_time(), y.get_creation_time()))
|
|
if not sessions:
|
|
return None
|
|
latest_session = sessions[-1]
|
|
|
|
# 2nd, query MSP
|
|
|
|
# Init UpdateOid request
|
|
wsc_proxy_service = self.msp_disco_query(latest_session)
|
|
wsc_proxy_service.initUploadToken(lasso.SECURITY11_MECH_TLS_SAML, 1, filename, datedepot)
|
|
wsc_proxy_service.request.teleserviceId = '1001'
|
|
wsc_proxy_service.buildRequestMsg()
|
|
more_headers = {}
|
|
if get_cfg('adeline', {}).get('http_auth_tuple'):
|
|
more_headers['Authorization'] = 'Basic ' + base64.encodestring(
|
|
get_cfg('adeline', {}).get('http_auth_tuple'))
|
|
body = wsc_proxy_service.msgBody
|
|
# FIXME: MSP is void !
|
|
soap_answer = soap_call(wsc_proxy_service.msgUrl, body + ' ',
|
|
more_headers = more_headers)
|
|
# FIXME: MSP for dummies !
|
|
soap_answer = soap_answer.replace('faultcode','S:faultcode').replace('faultstring', 'S:faultstring').replace(
|
|
'faultactor', 'S:faultactor').replace('detail', 'S:Detail')
|
|
try:
|
|
wsc_proxy_service.processResponseMsg(soap_answer)
|
|
except lasso.Error, error:
|
|
if error[0] != lasso.SOAP_FAULT_REDIRECT_REQUEST or not wsc_proxy_service.msgUrl:
|
|
raise
|
|
messageId = self.getMessageId(wsc_proxy_service.soapEnvelopeResponse)
|
|
return None
|
|
if wsc_proxy_service.response.status.code == 'Ok':
|
|
base64encoded_assertion = wsc_proxy_service.response.token
|
|
if base64encoded_assertion:
|
|
assertion = base64.b64decode(base64encoded_assertion)
|
|
return assertion
|
|
return None
|
|
|
|
import urllib
|
|
import httplib
|
|
|
|
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)
|
|
else:
|
|
host, query = urllib.splithost(url[6:])
|
|
conn = httplib.HTTPSConnection(host,
|
|
key_file = client_cert, cert_file = client_cert)
|
|
headers = {'Content-Type': 'text/xml'}
|
|
if more_headers:
|
|
headers.update(more_headers)
|
|
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:
|
|
from M2Crypto import BIO, SMIME, X509
|
|
except ImportError:
|
|
m2crypto = False
|
|
else:
|
|
m2crypto = True
|
|
|
|
def send_smime(from_addr, to_addrs, subject, msg, from_key=None, from_cert=None, to_certs=None, smtpd='localhost'):
|
|
if not m2crypto:
|
|
return
|
|
msg_bio = BIO.MemoryBuffer(msg)
|
|
sign = from_key and from_cert
|
|
encrypt = to_certs
|
|
|
|
s = SMIME.SMIME()
|
|
if sign:
|
|
s.load_key(from_key, from_cert)
|
|
p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
|
|
msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
|
|
|
|
if encrypt:
|
|
sk = X509.X509_Stack()
|
|
for x in to_certs:
|
|
sk.push(X509.load_cert(x))
|
|
s.set_x509_stack(sk)
|
|
s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
|
|
tmp_bio = BIO.MemoryBuffer()
|
|
if sign:
|
|
s.write(tmp_bio, p7)
|
|
else:
|
|
tmp_bio.write(msg)
|
|
p7 = s.encrypt(tmp_bio)
|
|
|
|
out = BIO.MemoryBuffer()
|
|
out.write('From: %s\r\n' % from_addr)
|
|
out.write('To: %s\r\n' % ", ".join(to_addrs))
|
|
out.write('Subject: %s\r\n' % subject)
|
|
if encrypt:
|
|
s.write(out, p7)
|
|
else:
|
|
if sign:
|
|
s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
|
|
else:
|
|
out.write('\r\n')
|
|
out.write(msg)
|
|
out.close()
|
|
|
|
smtp = smtplib.SMTP()
|
|
smtp.connect(smtpd)
|
|
smtp.sendmail(from_addr, to_addrs, out.read())
|
|
smtp.quit()
|
|
|
|
import random
|
|
import email.Encoders
|
|
from email.MIMEText import MIMEText
|
|
from email.MIMEBase import MIMEBase
|
|
from email.MIMEMultipart import MIMEMultipart
|
|
|
|
def envoie_fichier(adeline_service, filename, filecontent, identity):
|
|
assertion = adeline_service.getUploadToken(identity, filename)
|
|
context = dict()
|
|
context['assertion'] = assertion
|
|
context['filename'] = filename
|
|
context['date'] = isotime()
|
|
context['dateperemption'] = isotime(1200)
|
|
# context['uuid'] = uuid.uuid4().hex # only in 2.5
|
|
context['uuid'] = '%x' % random.randint(0,1000000000000000000000)
|
|
template = '''<enveloppeMSP xmlns="urn://application.mon.service-public.fr/xmlns/routeur/2007/05/01">
|
|
<infoRoutageMSP>
|
|
%(assertion)s
|
|
</infoRoutageMSP>
|
|
<messageMSP>
|
|
<infoMSP>
|
|
<version>1.1</version>
|
|
<typeMessage>03</typeMessage>
|
|
<contenuMsg>Message hors demarche Cdc Num</contenuMsg>
|
|
<dtEnvoi>%(date)s</dtEnvoi>
|
|
<titreMessage>Message hors demarche avec PJ</titreMessage>
|
|
<emailTransportResponse>admin@entrouvert.com</emailTransportResponse>
|
|
<arDemande>true</arDemande>
|
|
<idTSEmetteur>1001</idTSEmetteur>
|
|
<refMessage>abcd</refMessage>
|
|
<reponseAutorisee>true</reponseAutorisee>
|
|
<isurgent>true</isurgent>
|
|
<datePeremption>%(dateperemption)s</datePeremption>
|
|
<idTSCible>0</idTSCible>
|
|
<refMessageOrigine>refmesOrigine</refMessageOrigine>
|
|
</infoMSP>
|
|
<documentMSP>
|
|
<intitule>%(filename)s</intitule>
|
|
<lbNom>%(filename)s</lbNom>
|
|
<typeDocument>1</typeDocument>
|
|
<infoEmeteur>1001</infoEmeteur>
|
|
<infoAuteur>1001</infoAuteur>
|
|
<description>%(filename)s</description>
|
|
<dateReference>%(date)s</dateReference>
|
|
<dateFinValidite>2100-12-17T09:30:47.0Z</dateFinValidite>
|
|
<lbDoc>%(uuid)s<lbDoc>
|
|
</documentMSP>
|
|
</messageMSP>
|
|
</enveloppeMSP>'''
|
|
description = MIMEText(template % context)
|
|
description.set_param('name', 'informationMSP.txt')
|
|
fichier = MIMEBase('application','octet-stream')
|
|
fichier.set_payload(filecontent)
|
|
fichier.set_param('name', filename)
|
|
email.Encoders.encode_base64(fichier)
|
|
fichier['Content-ID'] = context['uuid']
|
|
msg = MIMEMultipart()
|
|
msg.attach(description)
|
|
msg.attach(fichier)
|
|
send_smime('admin@entrouvert.com',
|
|
('tm.routeurmsp.fr@capgemini.com',),
|
|
'Uploading document from Adeline to MSP',
|
|
msg.as_string(),
|
|
'/var/lib/authentic/adelauth.servicepubliclocal.net/private-key.pem',
|
|
'/var/lib/authentic/adelauth.servicepubliclocal.net/certificate.pem',
|
|
('/var/lib/authentic/adelauth.servicepubliclocal.net/AC2_routeur_SMIME.pem',))
|
|
|
|
class MigrateDataSpace:
|
|
def __init__(self, identity, session, adeline_service, doc_keys):
|
|
self.identity = identity
|
|
self.session = session
|
|
self.adeline_service = adeline_service
|
|
self.doc_keys = doc_keys
|
|
|
|
|
|
def __call__(self):
|
|
if ED_MIGRATION_DISABLED or ED_DOCUMENTS_MIGRATION_DISABLED:
|
|
return
|
|
# 1st, ask local data space for documents
|
|
docs = []
|
|
adeline_service = self.adeline_service
|
|
for key in self.doc_keys:
|
|
doc_xpath = "/ad:PersonalDocument[ad:PersonalDocumentMetadata/@documentKey='%s']" % key
|
|
adeline_service.initQuery(doc_xpath, key)
|
|
adeline_service.buildRequestMsg()
|
|
soap_anwser = soap_call(adeline_service.msgUrl, adeline_service.msgBody)
|
|
adeline_service.processQueryResponseMsg(soap_anwser)
|
|
docs.append(adeline_service.getAnswer(doc_xpath))
|
|
|
|
# TODO: get files and metadata out of "docs"
|
|
files = []
|
|
|
|
#for file in files:
|
|
#envoie_fichier(self.adeline_service, '', '', self.identity)
|
|
|