merging stuff done on adelauth.4et5.net
This commit is contained in:
commit
bfb565777d
|
@ -341,7 +341,7 @@ body {
|
|||
float:left;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification form fieldset.cdc_valider input{
|
||||
width:80px;
|
||||
width:70px;
|
||||
float:right;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification form fieldset.cdc_coche{
|
||||
|
@ -354,7 +354,7 @@ body {
|
|||
width:auto;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification form fieldset.cdc_coche label{
|
||||
width:210px;
|
||||
width:180px;
|
||||
padding-top:0;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification form fieldset.cdc_coche label img{
|
||||
|
@ -364,14 +364,14 @@ body {
|
|||
}
|
||||
#cdc_page #cdc_bloc_identification form fieldset label{
|
||||
font-size:0.75em;
|
||||
width:85px;
|
||||
width:75px;
|
||||
float:left;
|
||||
display:block;
|
||||
padding-top:4px;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification form fieldset input{
|
||||
font-size:0.75em;
|
||||
width:150px;
|
||||
width:140px;
|
||||
float:left;
|
||||
display:block;
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ body {
|
|||
padding:15px 10px;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification .cdc_boite_connexion .cdc_bouton a{
|
||||
padding:2px 25px;
|
||||
padding:2px 15px;
|
||||
}
|
||||
#cdc_page #cdc_bloc_identification .cdc_boite_connexion .cdc_logo{
|
||||
padding:10px;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
|
||||
<link rel="stylesheet" href="/themes/adeline/styles/cdc_structure.css" media="all" />
|
||||
</head>
|
||||
<body>
|
||||
<body[if-any onload] onload="[onload]"[end]>
|
||||
<div id="cdc_page" style="width:550px">
|
||||
|
||||
<div class="cdc_bloc" id="cdc_bloc_demarches">
|
||||
|
@ -15,7 +15,7 @@
|
|||
[if-any user]
|
||||
[else]
|
||||
<div class="cdc_connexion">
|
||||
<div class="cdc_creer"><span>CRÉER MON COMPTE</span></div>
|
||||
<div class="cdc_creer"><a href="/register"><span>CRÉER MON COMPTE</span></a></div>
|
||||
<div class="cdc_identifier"><span>M'IDENTIFIER</span></div>
|
||||
</div>
|
||||
[end]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'<p>Souhaitez-vous vraiment supprimer la liaison avec Mon Service Public ?</p>'
|
||||
u'<p><ul>'
|
||||
u'<li><a href="proxy_terminate">Valider<a/></li>'
|
||||
u'<li><a href="../../..">Annuler</a></li>'
|
||||
u'</ul></p>'
|
||||
|
||||
class AlternateSpDir(authentic.liberty.root.SpDir):
|
||||
def _q_lookup(self, component):
|
||||
return AlternateSpUI(component)
|
|
@ -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):
|
|||
'<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('faultcode','S:faultcode').replace('faultstring', 'S:faultstring').replace(
|
||||
'faultactor', 'S:faultactor').replace('detail', 'S:Detail')
|
||||
|
||||
soap_answer = soap_answer.replace('S:detail', 'S:Detail')
|
||||
try:
|
||||
wsc_proxy_service.processResponseMsg(soap_answer)
|
||||
except lasso.Error, error:
|
||||
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
|
||||
messageId = self.getMessageId(wsc_proxy_service.soapEnvelopeResponse)
|
||||
|
@ -417,10 +478,41 @@ 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()
|
||||
ctype = request.environ.get("CONTENT_TYPE")
|
||||
body = None
|
||||
if not ctype:
|
||||
get_logger().warn('SOAP Endpoint got message without content-type')
|
||||
return
|
||||
|
@ -434,9 +526,11 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
|
||||
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())
|
||||
messageId = None
|
||||
try:
|
||||
if request_type == lasso.REQUEST_TYPE_DST_QUERY:
|
||||
try:
|
||||
|
@ -462,7 +556,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
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)
|
||||
resource = self.query_msp_for_pp(service_href, identity)
|
||||
redirect_url = None
|
||||
if resource:
|
||||
service.resourceData = resource
|
||||
|
@ -478,7 +572,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
raise Exception('No Resource!!!')
|
||||
|
||||
service.buildResponseMsg()
|
||||
return service.msgBody
|
||||
body = service.msgBody
|
||||
|
||||
|
||||
if request_type == lasso.REQUEST_TYPE_DST_MODIFY:
|
||||
|
@ -501,10 +595,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
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.resourceData = resource
|
||||
service.buildModifyResponseMsg()
|
||||
result, messageId = self.do_modify_msp_for_pp(service_href, identity, service.resourceData, messageId)
|
||||
if result and result != 'Ok':
|
||||
|
@ -514,14 +605,19 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
# 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:
|
||||
body = service.msgBody
|
||||
except RedirectException, redirect_exception:
|
||||
soap_fault = self.get_redirect_soap_fault(redirect_exception.redirect_url, messageId)
|
||||
body = soap_fault.exportToXml()
|
||||
except Exception, exception:
|
||||
fp = StringIO.StringIO()
|
||||
traceback.print_exc(file=fp)
|
||||
msg = fp.getvalue()
|
||||
print msg
|
||||
body = '''<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<Header/>
|
||||
<Body>
|
||||
|
@ -531,8 +627,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
<Detail>%s</Detail>
|
||||
</Fault>
|
||||
</Body>
|
||||
</Envelope>''' % msg
|
||||
return body
|
||||
</Envelope>''' % 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):
|
|||
</PP>
|
||||
'''
|
||||
|
||||
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(
|
||||
'<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('faultcode','S:faultcode').replace(
|
||||
'faultstring', 'S:faultstring').replace('faultactor', 'S:faultactor').replace('detail', 'S:Detail')
|
||||
soap_answer = soap_answer.replace('S:detail', 'S:Detail')
|
||||
try:
|
||||
wsc_proxy_service.processResponseMsg(soap_answer)
|
||||
except lasso.Error, error:
|
||||
|
@ -764,6 +882,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:
|
||||
|
@ -792,7 +912,7 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
# 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 = '1260'
|
||||
wsc_proxy_service.request.teleserviceId = '1001'
|
||||
wsc_proxy_service.buildRequestMsg()
|
||||
more_headers = {}
|
||||
if get_cfg('adeline', {}).get('http_auth_tuple'):
|
||||
|
@ -822,7 +942,8 @@ class AlternateLibertyDirectory(authentic.liberty.root.RootDirectory):
|
|||
import urllib
|
||||
import httplib
|
||||
|
||||
def soap_call(url, msg, client_cert = None, more_headers = None):
|
||||
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)
|
||||
|
@ -833,16 +954,30 @@ def soap_call(url, msg, client_cert = None, more_headers = None):
|
|||
headers = {'Content-Type': 'text/xml'}
|
||||
if more_headers:
|
||||
headers.update(more_headers)
|
||||
conn.set_debuglevel(1)
|
||||
conn.request('POST', query, msg, headers)
|
||||
response = conn.getresponse()
|
||||
data = response.read()
|
||||
conn.close()
|
||||
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()
|
||||
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:
|
||||
|
@ -925,7 +1060,7 @@ def envoie_fichier(adeline_service, filename, filecontent, identity):
|
|||
<titreMessage>Message hors demarche avec PJ</titreMessage>
|
||||
<emailTransportResponse>admin@entrouvert.com</emailTransportResponse>
|
||||
<arDemande>true</arDemande>
|
||||
<idTSEmetteur>1260</idTSEmetteur>
|
||||
<idTSEmetteur>1001</idTSEmetteur>
|
||||
<refMessage>abcd</refMessage>
|
||||
<reponseAutorisee>true</reponseAutorisee>
|
||||
<isurgent>true</isurgent>
|
||||
|
@ -937,8 +1072,8 @@ def envoie_fichier(adeline_service, filename, filecontent, identity):
|
|||
<intitule>%(filename)s</intitule>
|
||||
<lbNom>%(filename)s</lbNom>
|
||||
<typeDocument>1</typeDocument>
|
||||
<infoEmeteur>1260</infoEmeteur>
|
||||
<infoAuteur>1260</infoAuteur>
|
||||
<infoEmeteur>1001</infoEmeteur>
|
||||
<infoAuteur>1001</infoAuteur>
|
||||
<description>%(filename)s</description>
|
||||
<dateReference>%(date)s</dateReference>
|
||||
<dateFinValidite>2100-12-17T09:30:47.0Z</dateFinValidite>
|
||||
|
|
|
@ -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')
|
||||
'<li>%s <span class="but-right"><a href="%s">%s</a> <a href="%s">%s</a></span></li>' % (
|
||||
_('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):
|
|||
<div class="cdc_plus"><a href="forgot_password">Mot de passe perdu ?</a></div>
|
||||
</fieldset>
|
||||
<fieldset class="cdc_coche">
|
||||
<input type="checkbox" id="cdc_champ_liaison" name="cdc_champ_liaison" checked="checked"/>
|
||||
<label for="cdc_champ_liaison">Créer une liaison avec <img src="/themes/adeline/images/logo_servicepublic_mini.gif" alt="mon servicepublic.fr" /></label>
|
||||
<input type="checkbox" id="tfConfirmFederationFromMSP" name="tfConfirmFederationFromMSP" checked="checked"/>
|
||||
<label for="tfConfirmFederationFromMSP">Créer une liaison avec <img src="/themes/adeline/images/logo_servicepublic_mini.gif" alt="mon servicepublic.fr" /></label>
|
||||
</fieldset>
|
||||
<fieldset class="cdc_valider">
|
||||
<input type="submit" value="Valider" />
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2008-10-15 13:32+0200\n"
|
||||
"POT-Creation-Date: 2008-11-25 19:53+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -16,149 +16,140 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../extra/modules/root.ptl:99 ../extra/modules/root.ptl:142
|
||||
#: ../extra/modules/root.ptl:145
|
||||
#: ../extra/modules/root.ptl:101 ../extra/modules/root.ptl:144
|
||||
#: ../extra/modules/root.ptl:147
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:118
|
||||
#: ../extra/modules/root.ptl:120
|
||||
msgid "Your keyring allows you to access..."
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:122
|
||||
#: ../extra/modules/root.ptl:124
|
||||
msgid "To access to the service of your choice..."
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:128
|
||||
#: ../extra/modules/root.ptl:130
|
||||
msgid "Your local services"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:133
|
||||
#: ../extra/modules/root.ptl:135
|
||||
msgid "Our partners services"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:142
|
||||
#: ../extra/modules/root.ptl:144
|
||||
msgid "Access MSP"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:142
|
||||
#: ../extra/modules/root.ptl:144
|
||||
msgid "Remove Link"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:145
|
||||
#: ../extra/modules/root.ptl:147
|
||||
msgid "Create a Link with MSP"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:149
|
||||
#: ../extra/modules/root.ptl:151
|
||||
#, python-format
|
||||
msgid "Log on %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:154
|
||||
#: ../extra/modules/root.ptl:156
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:156
|
||||
#: ../extra/modules/root.ptl:158
|
||||
msgid "Reset account federations and offerings"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:174
|
||||
#: ../extra/modules/root.ptl:176
|
||||
msgid "Username (your email address)"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:176 ../extra/modules/root.ptl:507
|
||||
#: ../extra/modules/root.ptl:178 ../extra/modules/root.ptl:538
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:177 ../extra/modules/root.ptl:511
|
||||
#: ../extra/modules/root.ptl:179 ../extra/modules/root.ptl:542
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:179
|
||||
#: ../extra/modules/root.ptl:181
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:182
|
||||
#: ../extra/modules/root.ptl:184
|
||||
#, python-format
|
||||
msgid "Move to %s Identity Provider"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:187 ../extra/modules/root.ptl:525
|
||||
#: ../extra/modules/root.ptl:189 ../extra/modules/root.ptl:556
|
||||
#: ../extra/modules/admin.ptl:36 ../extra/modules/admin.ptl:77
|
||||
#: ../extra/modules/admin.ptl:122 ../extra/modules/admin.ptl:163
|
||||
#: ../extra/modules/admin.ptl:286 ../extra/modules/admin.ptl:318
|
||||
#: ../extra/modules/admin.ptl:109 ../extra/modules/admin.ptl:150
|
||||
#: ../extra/modules/admin.ptl:273 ../extra/modules/admin.ptl:305
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:195
|
||||
#: ../extra/modules/root.ptl:197
|
||||
msgid "MSP Identity Provider Id is not known."
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:335
|
||||
#: ../extra/modules/root.ptl:358
|
||||
msgid "Authentication Failure"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:340 ../extra/modules/root.ptl:343
|
||||
#: ../extra/modules/root.ptl:363 ../extra/modules/root.ptl:366
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:473
|
||||
#: ../extra/modules/root.ptl:496
|
||||
msgid "Debug page"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:476
|
||||
#: ../extra/modules/root.ptl:499
|
||||
msgid "Out-of-flow MSP cookie set"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:499
|
||||
#: ../extra/modules/root.ptl:530
|
||||
msgid "First Name / Last Name"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:500
|
||||
#: ../extra/modules/root.ptl:531
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:513
|
||||
#: ../extra/modules/root.ptl:544
|
||||
msgid "A password will be mailed to you."
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:518
|
||||
#: ../extra/modules/root.ptl:549
|
||||
msgid "If you forget your password..."
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:520
|
||||
#: ../extra/modules/root.ptl:551
|
||||
msgid "Security question"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:521
|
||||
#: ../extra/modules/root.ptl:552
|
||||
msgid "[Select a question]"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:522
|
||||
#: ../extra/modules/root.ptl:553
|
||||
msgid "Your answer"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:524 ../extra/modules/admin.ptl:35
|
||||
#: ../extra/modules/admin.ptl:76 ../extra/modules/admin.ptl:121
|
||||
#: ../extra/modules/admin.ptl:162 ../extra/modules/admin.ptl:285
|
||||
#: ../extra/modules/admin.ptl:317
|
||||
#: ../extra/modules/root.ptl:555 ../extra/modules/admin.ptl:35
|
||||
#: ../extra/modules/admin.ptl:76 ../extra/modules/admin.ptl:108
|
||||
#: ../extra/modules/admin.ptl:149 ../extra/modules/admin.ptl:272
|
||||
#: ../extra/modules/admin.ptl:304
|
||||
msgid "Submit"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/root.ptl:536 ../extra/modules/root.ptl:537
|
||||
#: ../extra/modules/root.ptl:567 ../extra/modules/root.ptl:568
|
||||
msgid "Registration"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:88
|
||||
msgid "Failed to get Assertion from identity provider"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:99
|
||||
#, python-format
|
||||
msgid "Response is not Success (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:29 ../extra/modules/admin.ptl:101
|
||||
#: ../extra/modules/admin.ptl:29 ../extra/modules/admin.ptl:102
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
|
@ -187,109 +178,123 @@ msgid "Deleting National Service:"
|
|||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:99
|
||||
msgid "Collectivity Id"
|
||||
msgid "Collectivity SPL Id"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:103
|
||||
msgid "None"
|
||||
#: ../extra/modules/admin.ptl:104
|
||||
msgid "MSP tsId"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:117
|
||||
msgid "Collectivity Own Identity Provider"
|
||||
#: ../extra/modules/admin.ptl:106
|
||||
msgid "URL on Logout"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:119
|
||||
msgid "Propose MSP as Identity Provider"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:150 ../extra/modules/admin.ptl:151
|
||||
#: ../extra/modules/admin.ptl:137 ../extra/modules/admin.ptl:138
|
||||
msgid "Edit Collectivity"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:161
|
||||
#: ../extra/modules/admin.ptl:148
|
||||
msgid "You are about to irrevocably delete this collectivity."
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:167
|
||||
#: ../extra/modules/admin.ptl:154
|
||||
msgid "Delete Collectivity"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:168
|
||||
#: ../extra/modules/admin.ptl:155
|
||||
msgid "Deleting Collectivity:"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:189
|
||||
#: ../extra/modules/admin.ptl:176
|
||||
msgid "New Collectivity"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:190
|
||||
#: ../extra/modules/admin.ptl:177
|
||||
msgid "New National Service"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:191
|
||||
msgid "SP Mapping for MSP"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:192
|
||||
#: ../extra/modules/admin.ptl:178
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:194
|
||||
#: ../extra/modules/admin.ptl:180
|
||||
msgid "Collectivities"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:208
|
||||
#: ../extra/modules/admin.ptl:186
|
||||
msgid "SPL Code: "
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:195
|
||||
msgid "National Services (for MSP)"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:229 ../extra/modules/admin.ptl:230
|
||||
#: ../extra/modules/admin.ptl:216 ../extra/modules/admin.ptl:217
|
||||
msgid "New Adeline Collectivity"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:245 ../extra/modules/admin.ptl:246
|
||||
#: ../extra/modules/admin.ptl:232 ../extra/modules/admin.ptl:233
|
||||
msgid "New MSP National Service"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:258
|
||||
#: ../extra/modules/admin.ptl:245
|
||||
msgid "Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:272
|
||||
#: ../extra/modules/admin.ptl:259
|
||||
msgid "MSP IdP"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:274
|
||||
#: ../extra/modules/admin.ptl:261
|
||||
msgid "MSP Portal URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:276
|
||||
#: ../extra/modules/admin.ptl:263
|
||||
msgid "Data Migration URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:278
|
||||
#: ../extra/modules/admin.ptl:265
|
||||
msgid "MSP Session Image URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:280
|
||||
#: ../extra/modules/admin.ptl:267
|
||||
msgid "MSP New Account URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:282
|
||||
#: ../extra/modules/admin.ptl:269
|
||||
msgid "HTTP Authentication Tuple"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:284
|
||||
#: ../extra/modules/admin.ptl:271
|
||||
msgid "Format: username:password"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:291 ../extra/modules/admin.ptl:292
|
||||
#: ../extra/modules/admin.ptl:278 ../extra/modules/admin.ptl:279
|
||||
msgid "Adeline Options"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:321 ../extra/modules/admin.ptl:322
|
||||
#: ../extra/modules/admin.ptl:308 ../extra/modules/admin.ptl:309
|
||||
msgid "MSP SP Mapping"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:344
|
||||
#: ../extra/modules/admin.ptl:331
|
||||
msgid "Adeline"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:109 ../extra/modules/liberty.py:167
|
||||
#: ../extra/modules/liberty.py:177
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:111
|
||||
msgid "request origin"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:131
|
||||
msgid "Failed to get Assertion from identity provider"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:167 ../extra/modules/liberty.py:177
|
||||
#, python-format
|
||||
msgid "Response is not Success (%s)"
|
||||
msgstr ""
|
||||
|
|
204
po/fr.po
204
po/fr.po
|
@ -5,7 +5,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Authentic 0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2008-10-15 13:32+0200\n"
|
||||
"POT-Creation-Date: 2008-11-25 19:53+0100\n"
|
||||
"PO-Revision-Date: 2007-03-13 13:15+0100\n"
|
||||
"Last-Translator: Pierre Cros <pcros@entrouvert.com>\n"
|
||||
"Language-Team: French\n"
|
||||
|
@ -14,155 +14,144 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
||||
|
||||
#: ../extra/modules/root.ptl:99 ../extra/modules/root.ptl:142
|
||||
#: ../extra/modules/root.ptl:145
|
||||
#: ../extra/modules/root.ptl:101 ../extra/modules/root.ptl:144
|
||||
#: ../extra/modules/root.ptl:147
|
||||
msgid "Connect"
|
||||
msgstr "Se connecter"
|
||||
|
||||
#: ../extra/modules/root.ptl:118
|
||||
#: ../extra/modules/root.ptl:120
|
||||
msgid "Your keyring allows you to access..."
|
||||
msgstr ""
|
||||
"Votre porte-clé vous permet d'accéder de manière unique à nos services "
|
||||
"ainsi qu'à ceux proposés par nos partenaires."
|
||||
"Votre porte-clé vous permet d'accéder de manière unique à nos services ainsi "
|
||||
"qu'à ceux proposés par nos partenaires."
|
||||
|
||||
#: ../extra/modules/root.ptl:122
|
||||
#: ../extra/modules/root.ptl:124
|
||||
msgid "To access to the service of your choice..."
|
||||
msgstr ""
|
||||
"Pour accéder au service de votre choix, cliquez sur le bouton « Se "
|
||||
"connecter »."
|
||||
"Pour accéder au service de votre choix, cliquez sur le bouton « Se connecter "
|
||||
"»."
|
||||
|
||||
#: ../extra/modules/root.ptl:128
|
||||
#: ../extra/modules/root.ptl:130
|
||||
msgid "Your local services"
|
||||
msgstr "Vos services communaux"
|
||||
|
||||
#: ../extra/modules/root.ptl:133
|
||||
#: ../extra/modules/root.ptl:135
|
||||
msgid "Our partners services"
|
||||
msgstr "Les services de nos partenaires"
|
||||
|
||||
#: ../extra/modules/root.ptl:142
|
||||
#: ../extra/modules/root.ptl:144
|
||||
msgid "Access MSP"
|
||||
msgstr "Accéder à mon.Service-Public.fr"
|
||||
|
||||
#: ../extra/modules/root.ptl:142
|
||||
#: ../extra/modules/root.ptl:144
|
||||
msgid "Remove Link"
|
||||
msgstr "Supprimer la liaison"
|
||||
|
||||
#: ../extra/modules/root.ptl:145
|
||||
#: ../extra/modules/root.ptl:147
|
||||
msgid "Create a Link with MSP"
|
||||
msgstr "Créer une liaison avec mon.Service-Public.fr"
|
||||
|
||||
#: ../extra/modules/root.ptl:149
|
||||
#: ../extra/modules/root.ptl:151
|
||||
#, python-format
|
||||
msgid "Log on %s"
|
||||
msgstr "Se connecter à %s"
|
||||
|
||||
#: ../extra/modules/root.ptl:154
|
||||
#: ../extra/modules/root.ptl:156
|
||||
msgid "Debug"
|
||||
msgstr "Débuguage"
|
||||
|
||||
#: ../extra/modules/root.ptl:156
|
||||
#: ../extra/modules/root.ptl:158
|
||||
msgid "Reset account federations and offerings"
|
||||
msgstr "Réinitialiser le compte (fédérations et offres de ressources)"
|
||||
|
||||
#: ../extra/modules/root.ptl:174
|
||||
#: ../extra/modules/root.ptl:176
|
||||
msgid "Username (your email address)"
|
||||
msgstr "Identifiant (votre adresse électronique)"
|
||||
|
||||
#: ../extra/modules/root.ptl:176 ../extra/modules/root.ptl:507
|
||||
#: ../extra/modules/root.ptl:178 ../extra/modules/root.ptl:538
|
||||
msgid "Username"
|
||||
msgstr "Identifiant"
|
||||
|
||||
#: ../extra/modules/root.ptl:177 ../extra/modules/root.ptl:511
|
||||
#: ../extra/modules/root.ptl:179 ../extra/modules/root.ptl:542
|
||||
msgid "Password"
|
||||
msgstr "Mot de passe"
|
||||
|
||||
#: ../extra/modules/root.ptl:179
|
||||
#: ../extra/modules/root.ptl:181
|
||||
msgid "Log in"
|
||||
msgstr "S'identifier"
|
||||
|
||||
#: ../extra/modules/root.ptl:182
|
||||
#: ../extra/modules/root.ptl:184
|
||||
#, python-format
|
||||
msgid "Move to %s Identity Provider"
|
||||
msgstr "Aller sur le fournisseur d'identités de %s"
|
||||
|
||||
#: ../extra/modules/root.ptl:187 ../extra/modules/root.ptl:525
|
||||
#: ../extra/modules/root.ptl:189 ../extra/modules/root.ptl:556
|
||||
#: ../extra/modules/admin.ptl:36 ../extra/modules/admin.ptl:77
|
||||
#: ../extra/modules/admin.ptl:122 ../extra/modules/admin.ptl:163
|
||||
#: ../extra/modules/admin.ptl:286 ../extra/modules/admin.ptl:318
|
||||
#: ../extra/modules/admin.ptl:109 ../extra/modules/admin.ptl:150
|
||||
#: ../extra/modules/admin.ptl:273 ../extra/modules/admin.ptl:305
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: ../extra/modules/root.ptl:195
|
||||
#: ../extra/modules/root.ptl:197
|
||||
msgid "MSP Identity Provider Id is not known."
|
||||
msgstr "L'identifiant du fournisseur d'identités MSP n'est pas connu."
|
||||
|
||||
#: ../extra/modules/root.ptl:335
|
||||
#: ../extra/modules/root.ptl:358
|
||||
msgid "Authentication Failure"
|
||||
msgstr "Erreur d'authentification"
|
||||
|
||||
#: ../extra/modules/root.ptl:340 ../extra/modules/root.ptl:343
|
||||
#: ../extra/modules/root.ptl:363 ../extra/modules/root.ptl:366
|
||||
msgid "Login"
|
||||
msgstr "Connexion"
|
||||
|
||||
#: ../extra/modules/root.ptl:473
|
||||
#: ../extra/modules/root.ptl:496
|
||||
msgid "Debug page"
|
||||
msgstr "Page de débuguage"
|
||||
|
||||
#: ../extra/modules/root.ptl:476
|
||||
#: ../extra/modules/root.ptl:499
|
||||
msgid "Out-of-flow MSP cookie set"
|
||||
msgstr "Cookie MSP positionné hors du déroulé"
|
||||
|
||||
#: ../extra/modules/root.ptl:499
|
||||
#: ../extra/modules/root.ptl:530
|
||||
msgid "First Name / Last Name"
|
||||
msgstr "Prénom / Nom"
|
||||
|
||||
#: ../extra/modules/root.ptl:500
|
||||
#: ../extra/modules/root.ptl:531
|
||||
msgid "Email"
|
||||
msgstr "Courriel"
|
||||
|
||||
#: ../extra/modules/root.ptl:513
|
||||
#: ../extra/modules/root.ptl:544
|
||||
msgid "A password will be mailed to you."
|
||||
msgstr "Un mot de passe vous sera envoyé par courriel."
|
||||
|
||||
#: ../extra/modules/root.ptl:518
|
||||
#: ../extra/modules/root.ptl:549
|
||||
msgid "If you forget your password..."
|
||||
msgstr "Si vous oubliez votre mot de passe..."
|
||||
|
||||
#: ../extra/modules/root.ptl:520
|
||||
#: ../extra/modules/root.ptl:551
|
||||
msgid "Security question"
|
||||
msgstr "Question de sécurité"
|
||||
|
||||
#: ../extra/modules/root.ptl:521
|
||||
#: ../extra/modules/root.ptl:552
|
||||
msgid "[Select a question]"
|
||||
msgstr "[Choisissez une question]"
|
||||
|
||||
#: ../extra/modules/root.ptl:522
|
||||
#: ../extra/modules/root.ptl:553
|
||||
msgid "Your answer"
|
||||
msgstr "Votre réponse"
|
||||
|
||||
#: ../extra/modules/root.ptl:524 ../extra/modules/admin.ptl:35
|
||||
#: ../extra/modules/admin.ptl:76 ../extra/modules/admin.ptl:121
|
||||
#: ../extra/modules/admin.ptl:162 ../extra/modules/admin.ptl:285
|
||||
#: ../extra/modules/admin.ptl:317
|
||||
#: ../extra/modules/root.ptl:555 ../extra/modules/admin.ptl:35
|
||||
#: ../extra/modules/admin.ptl:76 ../extra/modules/admin.ptl:108
|
||||
#: ../extra/modules/admin.ptl:149 ../extra/modules/admin.ptl:272
|
||||
#: ../extra/modules/admin.ptl:304
|
||||
msgid "Submit"
|
||||
msgstr "Valider"
|
||||
|
||||
#: ../extra/modules/root.ptl:536 ../extra/modules/root.ptl:537
|
||||
#: ../extra/modules/root.ptl:567 ../extra/modules/root.ptl:568
|
||||
msgid "Registration"
|
||||
msgstr "Inscription"
|
||||
|
||||
#: ../extra/modules/liberty.py:88
|
||||
msgid "Failed to get Assertion from identity provider"
|
||||
msgstr ""
|
||||
"Tentative ratée de récupérer une assertion depuis le fournisseur "
|
||||
"d'identité"
|
||||
|
||||
#: ../extra/modules/liberty.py:99
|
||||
#, python-format
|
||||
msgid "Response is not Success (%s)"
|
||||
msgstr "La réponse n'est pas \"Success\" (%s)"
|
||||
|
||||
#: ../extra/modules/admin.ptl:29 ../extra/modules/admin.ptl:101
|
||||
#: ../extra/modules/admin.ptl:29 ../extra/modules/admin.ptl:102
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
|
@ -191,119 +180,146 @@ msgid "Deleting National Service:"
|
|||
msgstr "Suppression du service national :"
|
||||
|
||||
#: ../extra/modules/admin.ptl:99
|
||||
msgid "Collectivity Id"
|
||||
#, fuzzy
|
||||
msgid "Collectivity SPL Id"
|
||||
msgstr "Id de collectivité"
|
||||
|
||||
#: ../extra/modules/admin.ptl:103
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
#: ../extra/modules/admin.ptl:104
|
||||
#, fuzzy
|
||||
msgid "MSP tsId"
|
||||
msgstr "IdP MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:117
|
||||
msgid "Collectivity Own Identity Provider"
|
||||
msgstr "Fournisseur d'identités de la collectivité"
|
||||
#: ../extra/modules/admin.ptl:106
|
||||
#, fuzzy
|
||||
msgid "URL on Logout"
|
||||
msgstr "Déconnexion globale"
|
||||
|
||||
#: ../extra/modules/admin.ptl:119
|
||||
msgid "Propose MSP as Identity Provider"
|
||||
msgstr "Proposer MSP comme fournisseur d'identités"
|
||||
|
||||
#: ../extra/modules/admin.ptl:150 ../extra/modules/admin.ptl:151
|
||||
#: ../extra/modules/admin.ptl:137 ../extra/modules/admin.ptl:138
|
||||
msgid "Edit Collectivity"
|
||||
msgstr "Modifier la collectivité"
|
||||
|
||||
#: ../extra/modules/admin.ptl:161
|
||||
#: ../extra/modules/admin.ptl:148
|
||||
msgid "You are about to irrevocably delete this collectivity."
|
||||
msgstr "Vous allez définitivement supprimer cette collectivité."
|
||||
|
||||
#: ../extra/modules/admin.ptl:167
|
||||
#: ../extra/modules/admin.ptl:154
|
||||
msgid "Delete Collectivity"
|
||||
msgstr "Supprimer la collectivité"
|
||||
|
||||
#: ../extra/modules/admin.ptl:168
|
||||
#: ../extra/modules/admin.ptl:155
|
||||
msgid "Deleting Collectivity:"
|
||||
msgstr "Suppression de la collectivité :"
|
||||
|
||||
#: ../extra/modules/admin.ptl:189
|
||||
#: ../extra/modules/admin.ptl:176
|
||||
msgid "New Collectivity"
|
||||
msgstr "Nouvelle collectivité"
|
||||
|
||||
#: ../extra/modules/admin.ptl:190
|
||||
#: ../extra/modules/admin.ptl:177
|
||||
msgid "New National Service"
|
||||
msgstr "Nouveau service national"
|
||||
|
||||
#: ../extra/modules/admin.ptl:191
|
||||
msgid "SP Mapping for MSP"
|
||||
msgstr "Mapping des SP pour MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:192
|
||||
#: ../extra/modules/admin.ptl:178
|
||||
msgid "Options"
|
||||
msgstr "Options"
|
||||
|
||||
#: ../extra/modules/admin.ptl:194
|
||||
#: ../extra/modules/admin.ptl:180
|
||||
msgid "Collectivities"
|
||||
msgstr "Collectivités"
|
||||
|
||||
#: ../extra/modules/admin.ptl:208
|
||||
#: ../extra/modules/admin.ptl:186
|
||||
msgid "SPL Code: "
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/admin.ptl:195
|
||||
msgid "National Services (for MSP)"
|
||||
msgstr "Services nationaux (pour MSP)"
|
||||
|
||||
#: ../extra/modules/admin.ptl:229 ../extra/modules/admin.ptl:230
|
||||
#: ../extra/modules/admin.ptl:216 ../extra/modules/admin.ptl:217
|
||||
msgid "New Adeline Collectivity"
|
||||
msgstr "Nouvelle collectivité Adeline"
|
||||
|
||||
#: ../extra/modules/admin.ptl:245 ../extra/modules/admin.ptl:246
|
||||
#: ../extra/modules/admin.ptl:232 ../extra/modules/admin.ptl:233
|
||||
msgid "New MSP National Service"
|
||||
msgstr "Nouveau service national MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:258
|
||||
#: ../extra/modules/admin.ptl:245
|
||||
msgid "Unknown"
|
||||
msgstr "Inconnu"
|
||||
|
||||
#: ../extra/modules/admin.ptl:272
|
||||
#: ../extra/modules/admin.ptl:259
|
||||
msgid "MSP IdP"
|
||||
msgstr "IdP MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:274
|
||||
#: ../extra/modules/admin.ptl:261
|
||||
msgid "MSP Portal URL"
|
||||
msgstr "Adresse du portail MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:276
|
||||
#: ../extra/modules/admin.ptl:263
|
||||
msgid "Data Migration URL"
|
||||
msgstr "Adresse pour la migration des données"
|
||||
|
||||
#: ../extra/modules/admin.ptl:278
|
||||
#: ../extra/modules/admin.ptl:265
|
||||
msgid "MSP Session Image URL"
|
||||
msgstr "Adresse de l'image de maintien de session MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:280
|
||||
#: ../extra/modules/admin.ptl:267
|
||||
msgid "MSP New Account URL"
|
||||
msgstr "Adresse de la création de compte MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:282
|
||||
#: ../extra/modules/admin.ptl:269
|
||||
msgid "HTTP Authentication Tuple"
|
||||
msgstr "Paire pour l'authentification HTTP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:284
|
||||
#: ../extra/modules/admin.ptl:271
|
||||
msgid "Format: username:password"
|
||||
msgstr "Format: identifiant:mot-de-passe"
|
||||
|
||||
#: ../extra/modules/admin.ptl:291 ../extra/modules/admin.ptl:292
|
||||
#: ../extra/modules/admin.ptl:278 ../extra/modules/admin.ptl:279
|
||||
msgid "Adeline Options"
|
||||
msgstr "Options Adeline"
|
||||
|
||||
#: ../extra/modules/admin.ptl:321 ../extra/modules/admin.ptl:322
|
||||
#: ../extra/modules/admin.ptl:308 ../extra/modules/admin.ptl:309
|
||||
msgid "MSP SP Mapping"
|
||||
msgstr "Mapping SP MSP"
|
||||
|
||||
#: ../extra/modules/admin.ptl:344
|
||||
#: ../extra/modules/admin.ptl:331
|
||||
msgid "Adeline"
|
||||
msgstr "Adeline"
|
||||
|
||||
#: ../extra/modules/liberty.py:109 ../extra/modules/liberty.py:167
|
||||
#: ../extra/modules/liberty.py:177
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:111
|
||||
msgid "request origin"
|
||||
msgstr ""
|
||||
|
||||
#: ../extra/modules/liberty.py:131
|
||||
msgid "Failed to get Assertion from identity provider"
|
||||
msgstr ""
|
||||
"Tentative ratée de récupérer une assertion depuis le fournisseur d'identité"
|
||||
|
||||
#: ../extra/modules/liberty.py:167 ../extra/modules/liberty.py:177
|
||||
#, python-format
|
||||
msgid "Response is not Success (%s)"
|
||||
msgstr "La réponse n'est pas \"Success\" (%s)"
|
||||
|
||||
#~ msgid "None"
|
||||
#~ msgstr "Aucun"
|
||||
|
||||
#~ msgid "Collectivity Own Identity Provider"
|
||||
#~ msgstr "Fournisseur d'identités de la collectivité"
|
||||
|
||||
#~ msgid "Propose MSP as Identity Provider"
|
||||
#~ msgstr "Proposer MSP comme fournisseur d'identités"
|
||||
|
||||
#~ msgid "SP Mapping for MSP"
|
||||
#~ msgstr "Mapping des SP pour MSP"
|
||||
|
||||
#~ msgid "Welcome to your keyring"
|
||||
#~ msgstr "Bienvenue dans votre porte-clés"
|
||||
|
||||
#~ msgid "Global Logout"
|
||||
#~ msgstr "Déconnexion globale"
|
||||
|
||||
#~ msgid "To access to this service you must identify first"
|
||||
#~ msgstr ""
|
||||
#~ "Pour accéder à ce service, vous devez au préalable vous identifier en "
|
||||
|
|
5
setup.py
5
setup.py
|
@ -5,7 +5,7 @@ import distutils.core
|
|||
from quixote.ptl.qx_distutils import qx_build_py
|
||||
|
||||
def data_tree(destdir, sourcedir):
|
||||
extensions = ['.css', '.png', '.jpeg', '.jpg', '.xml', '.html', '.js', '.ezt']
|
||||
extensions = ['.css', '.png', '.jpeg', '.jpg', '.xml', '.html', '.js', '.ezt', '.gif']
|
||||
r = []
|
||||
for root, dirs, files in os.walk(sourcedir):
|
||||
l = [os.path.join(root, x) for x in files if os.path.splitext(x)[1] in extensions]
|
||||
|
@ -20,5 +20,6 @@ distutils.core.setup(
|
|||
package_dir = { 'extra': 'extra' },
|
||||
packages = ['extra', 'extra.modules'],
|
||||
cmdclass = {'build_py': qx_build_py},
|
||||
data_files = data_tree('share/authentic/texts', 'data/texts')
|
||||
data_files = data_tree('share/authentic/texts', 'data/texts') +\
|
||||
data_tree('share/authentic/themes/', 'data/themes/'),
|
||||
)
|
||||
|
|
Reference in New Issue