@@ -15,7 +15,7 @@
[if-any user]
[else]
-
CRÉER MON COMPTE
+
M'IDENTIFIER
[end]
diff --git a/debian/authentic-adeline.init b/debian/authentic-adeline.init
index db3b684..5667879 100755
--- a/debian/authentic-adeline.init
+++ b/debian/authentic-adeline.init
@@ -11,7 +11,7 @@
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Authentic (+Adeline)"
-NAME=authentic
+NAME=authentic-adeline
DAEMON=/usr/sbin/authenticctl
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
diff --git a/extra/modules/alternatespui.ptl b/extra/modules/alternatespui.ptl
new file mode 100644
index 0000000..d5d9ff1
--- /dev/null
+++ b/extra/modules/alternatespui.ptl
@@ -0,0 +1,45 @@
+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
+
+
+class AlternateSpUI(authentic.liberty.root.SpUI):
+ _q_exports = ['proxy_terminate_confirm','terminate','login','proxy_terminate']
+
+ def proxy_terminate_confirm [html] (self):
+ template.html_top()
+ u'
Souhaitez-vous vraiment supprimer la liaison avec Mon Service Public ?
'
+ u'
'
+
+class AlternateSpDir(authentic.liberty.root.SpDir):
+ def _q_lookup(self, component):
+ return AlternateSpUI(component)
diff --git a/extra/modules/liberty.py b/extra/modules/liberty.py
index 9e9425d..a6750dd 100644
--- a/extra/modules/liberty.py
+++ b/extra/modules/liberty.py
@@ -6,6 +6,10 @@ import Cookie
import StringIO
import cgi
import traceback
+import socket
+import xml.sax.saxutils
+import string
+import random
import lasso
@@ -25,6 +29,7 @@ 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
@@ -32,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'
@@ -47,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",
@@ -56,6 +67,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
"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)
@@ -93,6 +106,9 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
def proxyAssertionConsumer(self):
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)
@@ -112,42 +128,68 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
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'))
+ 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
- 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
@@ -201,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
@@ -233,7 +273,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
adeline_service.initQuery('/ad:PersonalDocumentList', 'doclist')
adeline_service.buildRequestMsg()
try:
- soap_anwser = soap_call(adeline_service.msgUrl, adeline_service.msgBody)
+ 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:
@@ -277,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()
@@ -340,7 +402,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
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 = '1260'
+ wsc_proxy_service.request.teleserviceId = '1001'
# Add interaction service header
headers = wsc_proxy_service.soapEnvelopeRequest.header.other
user_interaction = lasso.IsUserInteraction()
@@ -366,13 +428,12 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
'
@@ -531,8 +627,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
%s
- ''' % msg
- return body
+ ''' % xml.sax.saxutils.escape(msg)
+ return body
msp_oids = {
'OID.1.1.1' : { 'name': 'lbNomFamille'},
@@ -616,7 +712,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
'''
- def query_msp_for_pp(self, service_type, identity, query_items):
+ def query_msp_for_pp(self, service_type, identity, wsc_proxy_service = None):
# 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()))
@@ -627,10 +723,11 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
# 2nd, query MSP
# Init ReadOid request
- wsc_proxy_service = self.msp_disco_query(latest_session)
+ if not wsc_proxy_service:
+ 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 = '1260'
+ wsc_proxy_service.request.teleserviceId = '1001'
# Request complete description
for oid in self.msp_oids:
@@ -649,6 +746,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
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)
@@ -708,21 +806,40 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
# 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 = '1260'
- if service_type == adeline_urn:
- modify_oids = []
- pp = ET.XML(resource_data)
- for oid in self.msp_oids:
- name = self.msp_oids[oid]['name']
- item = pp.findall('{%s}%s' % (adeline_urn, name))
- if item:
- item = item[0]
- if item.text != dummy_value:
- text = item.text
- if text == None:
- text = ""
- wsc_proxy_service.addUpdateOidItem(oid, text.encode('utf-8'))
+ try:
+ # Get previous datas
+ old_datas = self.query_msp_for_pp(service_type, identity)
+ 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)
+ if old_datas:
+ oldpp = ET.XML(old_datas)
+ else:
+ oldpp = None
+ for oid in self.msp_oids:
+ name = self.msp_oids[oid]['name']
+ item = pp.findall('{%s}%s' % (adeline_urn, name))
+ olditem = oldpp.findall('{%s}%s' % (adeline_urn, name))
+ if item:
+ item = item[0]
+ if item.text != dummy_value:
+ text = item.text
+ if text == None:
+ text = ""
+ if olditem:
+ olditem = olditem[0]
+ if olditem is not None:
+ olditem = olditem.text
+ if olditem is None:
+ olditem = ""
+ if olditem is not None and text != olditem:
+ wsc_proxy_service.addUpdateOidItem(oid, text.encode('utf-8'))
+ except Exception, exception:
+ print 'Got an exception in new code'
+ print exception
+ raise exception
if service_type == lasso.PP_HREF:
pass # FIXME
# Add interaction service header
@@ -743,11 +860,12 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
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(
+ 'Message hors demarche avec PJ
admin@entrouvert.com
true
- 1260
+ 1001
abcd
true
true
@@ -937,8 +1072,8 @@ def envoie_fichier(adeline_service, filename, filecontent, identity):
%(filename)s
%(filename)s
1
- 1260
- 1260
+ 1001
+ 1001
%(filename)s
%(date)s
2100-12-17T09:30:47.0Z
diff --git a/extra/modules/root.ptl b/extra/modules/root.ptl
index 78956ca..b0cda73 100644
--- a/extra/modules/root.ptl
+++ b/extra/modules/root.ptl
@@ -53,12 +53,10 @@ class MspUserHash(StorableObject):
return cls.get(hash)
get_by_cookie = classmethod(get_by_cookie)
-
-
class AlternateRootDirectory(OldRootDirectory):
_q_exports = ['', 'admin', 'liberty', 'login', 'logout', 'change_password', 'register',
'forgot_password', 'update_info', 'saml', 'singleLogout',
- 'federations', 'login_local', 'login_msp', 'federate_msp',
+ 'federations', 'login_local', 'login_msp_for_proxy', 'login_msp', 'federate_msp',
'migration_done', 'reset', 'add_msp_cookie']
liberty = AlternateLibertyDirectory()
@@ -146,7 +144,7 @@ class AlternateRootDirectory(OldRootDirectory):
if identity.is_federated_with_msp():
msp_provider_id = get_cfg('adeline', {}).get('msp_idp')
klp = get_key_from_provider_id(msp_provider_id)
- terminate_url = '/liberty/sp/%s/proxy_terminate' % klp
+ terminate_url = '/liberty/sp/%s/proxy_terminate_confirm' % klp
msp_portal_url = get_cfg('adeline', {}).get('msp_portal_url')
'%s %s %s' % (
_('Access MSP'), msp_portal_url, _('Connect'), terminate_url, _('Remove Link'))
@@ -262,6 +260,12 @@ class AlternateRootDirectory(OldRootDirectory):
get_session().peer_cancelled = False
return self.sso_to_msp(nameIdPolicy = 'federated')
+ def login_msp_for_proxy(self):
+ session = get_session()
+ request = get_request()
+ session.after_url = get_field('ReturnToURL')
+ return redirect('login_msp')
+
def login_msp(self):
if get_field('idTs'):
for coll in collectivity.Collectivity.select():
@@ -440,10 +444,10 @@ class AlternateRootDirectory(OldRootDirectory):
session = get_session()
if session.msp_login_dump:
identity = identities.get_store().get_identity(get_session().user)
- if get_request().form.get('tfConfirmFederationFromMSP') == 'true' or \
+ if get_request().form.get('tfConfirmFederationFromMSP') or \
get_response().filter.get('federated_with_msp'):
return self.liberty.proxyAssertionConsumer()
- elif get_request().form.get('tfConfirmFederationFromMSP') == 'true':
+ elif get_request().form.get('tfConfirmFederationFromMSP'):
if session.msp_init_federate:
session.msp_init_federate = False
return self.federate_msp()
@@ -594,8 +598,8 @@ class MspLoginForm(Form):